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_codeMUST 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}. Ifforeign, partner converts at quote time. Ifinr, foreign amount derived.lrs_fy_used_inr_equivalentenforced HARD against ₹2.07 Cr (USD 250k × ~83) FY ceiling. Ifcurrent + new > ceiling, reject.tcs_consent_givenmandatory if (cumulative FY remittance + current order INR equivalent) > ₹7,00,000. Provider rejects withERR_TCS_CONSENT_MISSINGotherwise.
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_unitMUST be backed byquote_idwith TTL — UI shows countdown.margin_pctMUST be displayed in plain English ("partner adds 1.57% over RBI rate").ad_license_no+ad_license_verified_atenforced HARD — any option missing this is dropped before ranking.tier_reasonis 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_totalratio 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)
ad_license_verified_atwithin 14 days — else drop.- LRS headroom sufficient — else reject before quoting.
- Currency present in partner's authorized list — else drop.
- Delivery PIN serviceable — else drop or remap to branch pickup.
- Cumulative TCS calculation correct — else reject.
7. COMPLETION CONTRACT
Success criteria
- RBI A2 form e-signed.
- PAN + passport + visa (where applicable) submitted and encrypted at partner.
- Quote confirmed within TTL.
- Payment captured (NEFT/RTGS/UPI/Net banking — never credit card, per RBI cross-currency-on-credit rules being murky; partner may explicitly disallow).
- Order ID + tracking pin + ETA returned to TOMO.
- 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.quoteoutput: TTL =quote_ttl_secondsreturned 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_disclosurearithmetic matchesforex.quote× spot rate. - Sandbox
tcs_disclosurecorrectly triggers above ₹7L cumulative. - Sandbox AD license verification rejects expired licenses (mock one).
- Sandbox produces all four
delivery.moderesults when PIN is serviceable. - Sandbox rejects
instrument: credit_cardwithERR_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_pickon 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_includedis 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: truewithinsurance_cover_inrvalue, 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_noalways. - 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.