T
TOMO
Developer Docs
BETA These docs are under partner review. Some features described are roadmap items, not yet shipped. Verify against your sandbox before relying on any contract.
● LIVEv1.0.0travel.book_forex

travel.book_forex — Full Intent Specification

INTENT NAMESPACE: travel
INTENT NAME:      book_forex
FULL ID:          travel.book_forex
VERSION:          v1.0.0
STATUS:           live
TTBS WEIGHTS:     time 0.25 · taste 0.10 · budget 0.40 · safety 0.25
LAST UPDATED:     2026-05-14

Foreign currency purchase/sale by Indian residents for outbound travel, study, business, medical, or gifts. Distinct from other travel intents because: (a) RBI's Liberalised Remittance Scheme (LRS) annual cap (USD 250,000 per resident per financial year) is regulator-enforced and TOMO must surface remaining headroom; (b) the actual seller must be an RBI-authorized dealer (AD-I bank or AD-II FFMC) — TOMO is a routing surface, never a forex holder; (c) TCS under Income Tax Act §206C(1G) applies above ₹7,00,000 per FY (5% non-tour / 20% tour-overseas); (d) the live exchange rate moves second-by-second — TOMO must lock or quote with a published TTL (time-to-live) and must NEVER show a stale rate as "current"; (e) margin (spread over RBI reference rate) is the partner's commission base, and TOMO must disclose it in plain numbers.


1. NATURAL LANGUAGE COVERAGE

Classifies IN

  • "buy 2000 USD for US trip"
  • "forex card for Europe vacation, EUR 1500"
  • "currency exchange Hyderabad airport pickup"
  • "order GBP cash, doorstep delivery tomorrow"
  • "best USD rate today, 5000 dollars"
  • "load forex card with AED for Dubai"
  • "sell back leftover EUR after Italy trip"
  • "wire transfer USD 10000 to my son in Toronto"
  • "student forex card with insurance, Canada"
  • "multi-currency card USD EUR GBP"

Classifies OUT — borderline NO

  • "international flight to London" → travel.book_flight
  • "send money to friend in UK via UPI" → not LRS — UPI international is partner-specific; intent v1 = forex purchase only
  • "crypto to USDT" → out of scope (RBI not approving)
  • "Western Union remittance receive in INR" → inbound, not this intent
  • "credit card forex markup" → information only, not a forex purchase
  • "open NRE account" → banking, not this intent

MULTI-INTENT TRIGGERS

  • "Europe trip — flight + hotel + forex" → travel.book_flight + travel.book_hotel + travel.book_forex
  • "study abroad — visa + flight + forex card + travel insurance" → travel.book_visa_assistance + travel.book_flight + travel.book_forex + finance.buy_travel_insurance
  • "Dubai work trip — package + forex + sim" → travel.book_package + travel.book_forex

2. INPUT — TOMO → PROVIDER

{
  "intent":          "travel.book_forex",
  "intent_version":  "v1.0.0",
  "request_id":      "req_fx_2k4p_2026-05-14T09:32:00Z",
  "user_session_id": "anon_user_token_or_uid",

  "purpose": {
    "lrs_code":   "S0306",
    "label":      "private_visit",
    "trip_country_iso2": "US"
  },

  "instrument": {
    "type":      "forex_card",
    "variants_allowed": ["forex_card", "currency_notes", "wire_transfer", "demand_draft"]
  },

  "currency": {
    "iso_4217":   "USD",
    "amount":     2000,
    "amount_basis": "foreign"
  },

  "user_state_inr_budget_ceiling": 175000,

  "delivery": {
    "mode":       "doorstep",
    "address_id": "addr_home_v1",
    "by_iso_datetime": "2026-05-16T12:00:00+05:30",
    "modes_allowed": ["doorstep", "branch_pickup", "airport_pickup"]
  },

  "compliance": {
    "pan_on_file": true,
    "passport_on_file": true,
    "visa_on_file": true,
    "lrs_fy_used_inr_equivalent": 412000,
    "tcs_consent_given": true
  },

  "user_constants": {
    "home_pin":     "500032",
    "preferred_ad": ["HDFC", "ICICI", "Thomas Cook", "BookMyForex"]
  }
}

Field rules

  • lrs_code MUST be one of the RBI A2-form purpose codes (S0301 business travel, S0303 medical, S0305 study, S0306 private visit, S0307 gift, S0308 emigration). Any other value rejected at provider.
  • amount_basis ∈ {foreign, inr}. If foreign, partner converts at quote time. If inr, foreign amount derived.
  • lrs_fy_used_inr_equivalent enforced HARD against ₹2.07 Cr (USD 250k × ~83) FY ceiling. If current + new > ceiling, reject.
  • tcs_consent_given mandatory if (cumulative FY remittance + current order INR equivalent) > ₹7,00,000. Provider rejects with ERR_TCS_CONSENT_MISSING otherwise.

3. PROVIDER TOOLS

The forex MCP server (travel-forex-mcp) exposes exactly these tools. No others.

forex.quote

Returns live mid-market rate + partner-published sell rate + margin + TTL.

{
  "tool": "forex.quote",
  "input": {
    "iso_4217": "USD",
    "instrument": "forex_card",
    "amount_foreign": 2000,
    "deliver_to_pin": "500032"
  },
  "output": {
    "rbi_reference_rate_inr_per_unit": 83.41,
    "partner_sell_rate_inr_per_unit":  84.72,
    "margin_inr_per_unit":             1.31,
    "margin_pct":                      1.57,
    "amount_foreign":                  2000,
    "amount_inr_excl_taxes":           169440,
    "delivery_fee_inr":                250,
    "gst_inr":                         203,
    "tcs_inr":                         0,
    "amount_inr_total":                169893,
    "quote_id":                        "q_fx_8d72k",
    "quote_ttl_seconds":               45
  }
}

forex.create_order

Commits the quote. Must be called within quote_ttl_seconds of forex.quote.

forex.kyc_submit

Uploads PAN + passport + visa + A2 form e-sign. Stored encrypted; auto-delete after RBI-mandated retention (8 years) at partner. TOMO retains pointer only.

forex.track_delivery

For doorstep mode — courier pin, ETA, OTP-on-delivery.

forex.cancel

Pre-dispatch cancel for cash/card. Post-dispatch cancel disallowed (regulatory — currency is bearer).

forex.sell_back

For unused notes after a trip. Partner buys back at published rate; only for currency_notes, not card residuals.


4. RESPONSE SHAPE — PROVIDER → TOMO

{
  "intent": "travel.book_forex",
  "request_id": "req_fx_2k4p_2026-05-14T09:32:00Z",
  "options": [
    {
      "tier": "OK",
      "provider": "Thomas Cook",
      "ad_category": "AD-II FFMC",
      "instrument": "forex_card",
      "card_brand": "Borderless Prepaid",
      "iso_4217": "USD",
      "amount_foreign": 2000,
      "rbi_reference_rate_inr_per_unit": 83.41,
      "partner_sell_rate_inr_per_unit":  84.92,
      "margin_pct":                      1.81,
      "amount_inr_total":                170150,
      "delivery_fee_inr":                 0,
      "earliest_delivery_iso":            "2026-05-16T16:00:00+05:30",
      "card_load_count_included":         4,
      "atm_withdrawal_fee_per_txn_usd":   2.5,
      "insurance_included":               false,
      "ad_license_no":                    "FE.MUM.FFMC.0123/2018",
      "ad_license_verified_at":           "2026-05-12T06:00:00Z",
      "ttbs_score":                       0.71,
      "tier_reason": "lowest INR total but card-only, branch pickup limits"
    },
    {
      "tier": "GOOD",
      "provider": "BookMyForex",
      "ad_category": "RBI-authorized aggregator (AD-I partner: YES Bank)",
      "instrument": "forex_card",
      "card_brand": "Multi-Currency",
      "iso_4217": "USD",
      "amount_foreign": 2000,
      "rbi_reference_rate_inr_per_unit": 83.41,
      "partner_sell_rate_inr_per_unit":  84.72,
      "margin_pct":                      1.57,
      "amount_inr_total":                169893,
      "delivery_fee_inr":                 250,
      "earliest_delivery_iso":            "2026-05-15T18:00:00+05:30",
      "card_load_count_included":         "unlimited",
      "atm_withdrawal_fee_per_txn_usd":   2.0,
      "insurance_included":               true,
      "insurance_cover_inr":              200000,
      "ad_license_no":                    "FE.DEL.AD.0007/2014",
      "ad_license_verified_at":           "2026-05-13T06:00:00Z",
      "ttbs_score":                       0.84,
      "tier_reason": "balanced — best margin, doorstep, insurance, next-day"
    },
    {
      "tier": "GREAT",
      "provider": "HDFC Bank ForexPlus",
      "ad_category": "AD-I Bank",
      "instrument": "forex_card",
      "card_brand": "Multi-Currency Platinum",
      "iso_4217": "USD",
      "amount_foreign": 2000,
      "rbi_reference_rate_inr_per_unit": 83.41,
      "partner_sell_rate_inr_per_unit":  84.55,
      "margin_pct":                      1.37,
      "amount_inr_total":                169603,
      "delivery_fee_inr":                 0,
      "earliest_delivery_iso":            "2026-05-15T11:00:00+05:30",
      "card_load_count_included":         "unlimited",
      "atm_withdrawal_fee_per_txn_usd":   1.75,
      "insurance_included":               true,
      "insurance_cover_inr":              300000,
      "concierge_24x7":                   true,
      "emergency_cash_replacement":       true,
      "ad_license_no":                    "AD-I bank license (RBI no. 1234)",
      "ad_license_verified_at":           "2026-05-13T06:00:00Z",
      "ttbs_score":                       0.91,
      "tier_reason": "lowest spread + bank-grade safety + concierge"
    }
  ],
  "tcs_disclosure": {
    "tcs_applicable_above_inr": 700000,
    "fy_used_inr": 412000,
    "headroom_inr": 288000,
    "current_order_inr": 170150,
    "tcs_will_trigger": false
  },
  "lrs_disclosure": {
    "fy_ceiling_usd": 250000,
    "fy_used_usd_equivalent": 4940,
    "current_order_usd_equivalent": 2000,
    "headroom_usd": 243060
  }
}

Field rules

  • partner_sell_rate_inr_per_unit MUST be backed by quote_id with TTL — UI shows countdown.
  • margin_pct MUST be displayed in plain English ("partner adds 1.57% over RBI rate").
  • ad_license_no + ad_license_verified_at enforced HARD — any option missing this is dropped before ranking.
  • tier_reason is mandatory (one human sentence) — UI surfaces it under the tier title.

5. CONTROLLED VOCABULARIES

lrs_code (RBI A2 form)

S0301 business · S0303 medical · S0304 close-relative-maintenance · S0305 studies · S0306 private_visit · S0307 gift · S0308 emigration · S0309 employment · S0311 overseas-property

instrument

forex_card · currency_notes · wire_transfer · demand_draft

ad_category

AD-I Bank · AD-II FFMC · AD-II non-FFMC · RBI-authorized aggregator

delivery.mode

doorstep · branch_pickup · airport_pickup

All values STRICT ENUM. Anything else → ERR_VOCAB.


6. TTBS DIMENSIONS

TIME (weight 0.25)

  • Hours to earliest delivery (smaller = better)
  • Cut-off compliance: order placed today by 14:00 = same-day pickup at branch
  • Doorstep slot density in user's PIN
  • TIME score = 1 − min(1, hours_to_delivery / 48)

TASTE (weight 0.10)

  • Card brand recall (Visa/Mastercard/RuPay)
  • App quality for reload while abroad
  • Multi-currency vs single-currency
  • TASTE score = brand_familiarity × app_recharge_smoothness

BUDGET (weight 0.40 — dominant)

  • amount_inr_total ratio against best-in-set
  • Margin_pct disclosure honesty
  • Delivery fee, GST, hidden cross-currency markup
  • ATM withdrawal fee per transaction abroad
  • Card issuance fee
  • BUDGET score = 1 − (this_total − best_total) / best_total

SAFETY (weight 0.25)

  • AD-I Bank > AD-II FFMC > aggregator partner status
  • Card insurance cover (loss/theft)
  • Emergency cash replacement abroad
  • 24×7 concierge / chargeback support
  • Verified AD license cache age ≤ 14 days
  • SAFETY score = bank_grade × insurance_cover_band × concierge_flag × license_freshness

HARD FILTERS (apply before scoring)

  1. ad_license_verified_at within 14 days — else drop.
  2. LRS headroom sufficient — else reject before quoting.
  3. Currency present in partner's authorized list — else drop.
  4. Delivery PIN serviceable — else drop or remap to branch pickup.
  5. Cumulative TCS calculation correct — else reject.

7. COMPLETION CONTRACT

Success criteria

  1. RBI A2 form e-signed.
  2. PAN + passport + visa (where applicable) submitted and encrypted at partner.
  3. Quote confirmed within TTL.
  4. Payment captured (NEFT/RTGS/UPI/Net banking — never credit card, per RBI cross-currency-on-credit rules being murky; partner may explicitly disallow).
  5. Order ID + tracking pin + ETA returned to TOMO.
  6. CPC webhook fired on delivery_confirmed_or_pickup_complete.

CPC webhook (HMAC-SHA256, 5-min replay window)

{
  "event": "travel.forex.completed",
  "intent_id": "travel.book_forex",
  "request_id": "req_fx_2k4p_2026-05-14T09:32:00Z",
  "order_id": "FX9KP72",
  "provider": "BookMyForex",
  "iso_4217": "USD",
  "amount_foreign": 2000,
  "rbi_reference_rate_inr_per_unit": 83.41,
  "partner_sell_rate_inr_per_unit":  84.72,
  "amount_inr_excl_pass_through":     2620,
  "pass_through_inr":                 167523,
  "tcs_inr":                          0,
  "tomo_commission_base_inr":         2620,
  "tomo_commission_inr":              262,
  "completed_at": "2026-05-15T18:14:00+05:30",
  "ad_license_no": "FE.DEL.AD.0007/2014",
  "signature_hmac_sha256": "…"
}

Note: pass_through_inr is the actual remittance value to the foreign currency liability + the AD's revenue. amount_inr_excl_pass_through is the partner-kept service margin/spread piece on which TOMO's 10% applies. TOMO never touches the currency or the remittance — only the service-margin slice. Aligns with COMMISSION BASE = NET rule.

Failure cases

  • delivery_failed_undeliverable_pin → full refund auto-issued within T+3 working days.
  • kyc_rejected → user notified, order voided pre-charge.
  • quote_expired_before_confirm → user re-quoted; no charge.
  • lrs_breached → order rejected before any provider call.

8. WIDGET — UOE → UI

{
  "widget": "ForexBundleWidget",
  "header": {
    "currency_iso_4217": "USD",
    "amount_foreign":    2000,
    "rbi_ref_strip":     "RBI ref ₹83.41/USD · live",
    "lrs_strip":         "LRS used $4,940 of $250,000 this FY",
    "tcs_strip":         "TCS does not trigger — ₹2.88L headroom"
  },
  "regions": {
    "region_1_intelligence": ["RBI A2 ready", "passport on file", "visa US B1/B2 verified", "delivery to home PIN serviceable"],
    "region_2_summary":      "2000 USD, forex card, doorstep tomorrow morning",
    "region_3_visual":       "card_artwork_url (real partner-supplied PNG, signed)",
    "region_4_now_pin":      "Quote locked for 00:00:42 — confirm now",
    "region_5_tomo_choices": [
      {"tier": "OK", "label": "Thomas Cook · ₹1,70,150 · branch pickup", "reason": "lowest INR total but pickup only"},
      {"tier": "GOOD", "label": "BookMyForex · ₹1,69,893 · doorstep tomorrow + insurance", "reason": "balanced"},
      {"tier": "GREAT", "label": "HDFC ForexPlus · ₹1,69,603 · same-day + concierge", "reason": "lowest spread + bank-grade"}
    ]
  },
  "footer_disclosures": [
    "Rate moves every few seconds. The number you see is locked only after you tap CONFIRM.",
    "All sellers above are RBI-authorized. TOMO never holds your currency.",
    "TCS at 5% applies if your FY remittance exceeds ₹7,00,000 — we'll warn you before that line."
  ]
}

UI invariants:

  • Quote-TTL countdown is mandatory and visible.
  • Margin_pct shown in plain English ("partner adds X% over RBI rate") — never hidden.
  • LRS used / available is always shown — privacy: derived from on-device cache + last partner pull.
  • All three tier rows render; no "see more".

9. CACHING POLICY

  • forex.quote output: TTL = quote_ttl_seconds returned by partner (typically 30–90s). Never cache beyond that.
  • RBI reference rate: cached 60s on-device; refresh on any quote re-render.
  • AD license verifications: cached 14 days at provider-registry layer.
  • LRS used per FY: cached on-device, last 24h; refreshed before any new quote.
  • Card artwork images: cached 30 days, content-hashed; replaced if hash changes.
  • KYC documents: NEVER cached at TOMO — pointer only, partner holds.

10. ERROR CODES

Code Meaning UI surface
ERR_LRS_BREACH FY ceiling reached or new order would breach Plain-language: "You have ₹X left in your $250k FY limit. This order needs ₹Y."
ERR_TCS_CONSENT_MISSING Order > ₹7L cumulative and consent not given Modal asking for TCS consent before retry
ERR_QUOTE_EXPIRED TTL elapsed before confirm Auto re-quote with updated rate
ERR_KYC_INCOMPLETE PAN/passport/visa missing Inline KYC capture
ERR_AD_LICENSE_STALE AD license cache > 14 days Drop option before showing user
ERR_PIN_UNSERVICEABLE Doorstep delivery not available Re-prompt with branch pickup option
ERR_CURRENCY_UNSUPPORTED Partner doesn't carry this ISO 4217 Drop option
ERR_AMOUNT_OUTSIDE_LIMITS Below partner min or above per-order max Plain-language with corrected bounds
ERR_INSTRUMENT_DECLINED_CARD RBI restrictions — payment by credit card not allowed Re-prompt with NEFT/UPI
ERR_RATE_DROP_INTEGRITY Partner-published rate diverges from RBI ref by > 5% Drop option + alert ops

11. SANDBOX → PRODUCTION CHECKLIST

  • Sandbox quote returns RBI ref ± realistic margin (test: 0.5%–3.5% band).
  • Sandbox lrs_disclosure arithmetic matches forex.quote × spot rate.
  • Sandbox tcs_disclosure correctly triggers above ₹7L cumulative.
  • Sandbox AD license verification rejects expired licenses (mock one).
  • Sandbox produces all four delivery.mode results when PIN is serviceable.
  • Sandbox rejects instrument: credit_card with ERR_INSTRUMENT_DECLINED_CARD.
  • Sandbox CPC webhook signed HMAC-SHA256 within 5-min replay window — verified at staging.
  • Production AD license list pulled from RBI master directory weekly job.
  • Production rate-integrity guard live (drop > 5% RBI ref divergence).
  • Production TCS calculation tested at ₹6,99,999 / ₹7,00,001 / ₹7,00,000 boundaries.
  • Production LRS headroom verified against partner-reported user FY remittance before quoting.
  • Production refund SLA: T+3 working days for undeliverable, T+1 for pre-dispatch cancel.

12. ANTI-FABRICATION RULES

  • NO paid_placement, ad_bid, sponsored_rank, editor_pick on forex options. Tier order is TTBS-deterministic.
  • NO AI-generated card artwork — partner-supplied signed PNG only.
  • NO synthetic "exchange rate trend" predictions ("USD likely to rise" / "lock now, rate will move up"). RBI ref + partner sell rate + margin only.
  • NO "0 margin" claims — every partner has spread; surface the actual number.
  • NO loyalty/cashback inflation in displayed INR total. INR total is final.
  • NO holding period claims ("free for 6 months") unless partner contractually backs it.
  • NO bundling forex card load into a price unless card_load_count_included is explicit.
  • NO showing rates older than 60s as "current".
  • NO TOMO-issued "best rate guaranteed" — TOMO is a router, not a price-maker.
  • NO insurance claims displayed unless insurance_included: true with insurance_cover_inr value, both partner-attested.

13. REGULATORY FRAMING

  • FEMA 1999 + RBI Master Direction on LRS govern all outward remittance.
  • A2 form is the legally required declaration — partner collects, TOMO renders + relays.
  • TCS under Income Tax Act §206C(1G): 5% non-tour above ₹7L; 20% tour-overseas above ₹7L (effective Oct 2023 thresholds).
  • PMLA reporting: partner files CTR for cash > ₹10L cumulative. TOMO does not handle cash itself, never falls in PMLA reporter slot.
  • Only AD-I banks, AD-II FFMCs (Full-Fledged Money Changers licensed by RBI), and RBI-authorized aggregators with an AD-I sponsor allowed. Display ad_license_no always.
  • Credit card on cross-currency direct purchase is murky territory; partners may decline. TOMO surfaces decline plainly.
  • KYC retention at partner is 8 years per PMLA Rules 2005, §3(1)(g). TOMO never retains documents.