Intent Spec — finance.buy_travel_insurance
FULL ID: finance.buy_travel_insurance
VERSION: v1.0.0
STATUS: draft
LAST UPDATED: 2026-05-13
DOMAIN: finance
PRIMARY AGENT: FinanceAgent
TTBS WEIGHTS: time=0.30 taste=0.15 budget=0.25 safety=0.30
User buys travel insurance for a domestic or international trip. Single-trip or multi-trip (annual), geographic-zone-priced (Schengen, US-Canada, worldwide-excl-US, Asia, India-domestic), Schengen-VFS compliant where needed, with optional COVID, adventure-sports, baggage, trip-cancellation, and student/senior variants.
Partner exemplars: Policybazaar, Acko Travel, Tata AIG Travel, ICICI Lombard Travel, Bajaj Allianz Travel, HDFC ERGO Travel, Reliance Travel, Bharti AXA Travel, Religare Travel.
SECTION 1 — INTENT IDENTITY
User wants short-term travel insurance for a specific trip or annual multi-trip cover. Distinct from:
finance.buy_health_insurance— year-round indemnity health cover (domestic)finance.buy_term_insurance/finance.buy_motor_insurance— non-trip products- Visa application — out of scope v1;
compliance.apply_visaif introduced - Hotel / flight cancellation insurance bundled by OTAs — TOMO-level travel insurance is unbundled
Single intent per trip OR per annual multi-trip policy. Group travel up to 6 insured under one policy via insured_members array.
SECTION 2 — NATURAL LANGUAGE COVERAGE
CLASSIFIES IN
- "Travel insurance for my Schengen visa"
- "US trip insurance, 2 weeks in October"
- "Annual multi-trip insurance for business travel"
- "Insurance for Goa trip next week"
- "Student travel insurance for studying in UK"
- "Senior parent travel insurance, USA visit"
- "Cheapest Schengen visa insurance"
- "Trip cancellation cover for our Europe holiday"
- "Travel insurance with adventure sports cover for our Manali trip"
- "Family travel insurance Dubai 5 days"
CLASSIFIES OUT — BORDERLINE NO
- "Buy life insurance" →
finance.buy_term_insurance - "Health insurance for parents" →
finance.buy_health_insurance - "Book a flight" →
travel.book_flight - "Book a hotel" →
travel.book_hotel - "Visa application" → out of scope v1
- "Forex card" →
finance.book_financial_advisor_session(v1.1+ dedicated) - "File travel insurance claim" → v1.1+
finance.file_travel_claim
MULTI-INTENT TRIGGERS
- "Book flight + travel insurance" →
travel.book_flight+finance.buy_travel_insurance - "Book hotel + flight + travel insurance + forex" → composite mission
- "Adventure trip + insurance" →
travel.book_adventure_activity+finance.buy_travel_insurance
SECTION 3 — INPUT (TOMO → PROVIDER)
{
"intent": "finance.buy_travel_insurance",
"request_id": "req_01J9Z...",
"user_locale": "en-IN",
"user_currency": "INR",
"user_location": { "lat": 17.4475, "lng": 78.3563, "city": "Hyderabad", "pincode": "500032" },
"trip_type": "single_trip", // STRICT ENUM §6
"trip": {
"origin_country": "IN", // ISO_3166_2
"destination_countries": ["FR", "DE", "IT"], // ISO_3166_2 array; ≥1
"destination_zone": "schengen", // STRICT ENUM §6
"departure_date": "2026-10-15", // ISO_DATE
"return_date": "2026-10-26", // ISO_DATE; single_trip only
"trip_duration_days": 12,
"trip_purpose": "leisure", // STRICT ENUM §6
"annual_max_trip_duration_days": null // REQUIRED for multi-trip; null for single_trip
},
"insured_members": [
{
"first_name": "Rakesh", "last_name": "Kumar",
"date_of_birth": "1985-04-18",
"gender": "male",
"passport_number_last4": "5678",
"passport_expiry": "2030-03-15",
"pre_existing_conditions": [], // STRICT ENUM array §6
"is_proposer": true
},
{
"first_name": "Anita", "last_name": "Kumar",
"date_of_birth": "1988-09-12",
"gender": "female",
"passport_number_last4": "9012",
"passport_expiry": "2031-06-22",
"pre_existing_conditions": [],
"is_proposer": false
}
],
"cover_preferences": {
"sum_insured_usd": 100000, // USD denomination for international
"currency_of_cover": "USD", // STRICT ENUM §6
"schengen_compliant_required": true, // ≥€30k medical mandate
"addons_required": ["covid_cover", "adventure_sports_amateur", "trip_cancellation"],
"preferred_insurers": []
},
"ttbs_user_band": {
"time": "fast",
"taste": "balanced",
"budget": "good",
"safety": "good"
},
"session_context": { "tomo_session_id": "ses_01J9Z...", "user_dna_hash": "dna_v3_a7c9..." }
}
| Field | Type | Constraint | Notes |
|---|---|---|---|
intent |
string | REQUIRED, STRICT ENUM | Always finance.buy_travel_insurance |
trip_type |
enum | REQUIRED, STRICT ENUM §6 | single_trip / annual_multi_trip / student / senior |
trip.destination_countries |
array |
REQUIRED, ISO_3166_2, min 1 | |
trip.destination_zone |
enum | REQUIRED, STRICT ENUM §6 | Drives premium banding |
trip.departure_date |
string | REQUIRED, ISO_DATE | ≥ today + insurer-min lead time |
trip.return_date |
string | REQUIRED nullable | Non-null for single_trip / student / senior |
trip.annual_max_trip_duration_days |
int | REQUIRED nullable | Non-null for annual_multi_trip |
insured_members |
array | REQUIRED, min 1, max 6 | Each member needs passport data for international |
insured_members[].pre_existing_conditions |
array |
REQUIRED, STRICT ENUM §6 | May be empty |
cover_preferences.sum_insured_usd |
int | REQUIRED, ≥10000 | USD for international; INR for domestic |
cover_preferences.currency_of_cover |
enum | REQUIRED, STRICT ENUM §6 | USD / EUR / INR |
cover_preferences.schengen_compliant_required |
bool | REQUIRED | When TRUE, partner must guarantee ≥€30k medical |
Anti-fabrication preamble: Provider must guarantee Schengen-compliant medical cover (≥€30,000) when destination_zone is schengen / europe AND schengen_compliant_required=TRUE. Visa rejection due to non-compliant policy = customer-harm + suspension. COVID cover claims must be backed by partner's IRDAI-filed disclosure as of quote timestamp.
SECTION 4 — PROVIDER TOOLS
Tool 1: search_travel_quotes
PURPOSE: Up to 12 quotes matching trip + members + addons
SLA: p50 ≤ 600ms, p95 ≤ 2000ms, p99 ≤ 4000ms
RATE LIMIT: 90 req/min (high — users compare often)
IDEMPOTENCY: request_id; 5min cache (premiums table-driven)
RETRY: 1 on 429, 2 on 5xx
Tool 2: confirm_quote_and_kyc
PURPOSE: Lock quote + KYC + passport verification
SLA: p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT: 45 req/min
IDEMPOTENCY: request_id
RETRY: No retry
Tool 3: issue_policy
PURPOSE: Issue policy after payment; instant for most travel products
SLA: p50 ≤ 1500ms, p95 ≤ 4000ms, p99 ≤ 8000ms
RATE LIMIT: 45 req/min
IDEMPOTENCY: request_id
RETRY: No retry on issuance
Tool 4: cancel_or_freelook
PURPOSE: Pre-departure cancellation OR free-look (travel-specific rules)
SLA: p50 ≤ 1200ms, p95 ≤ 3500ms
RATE LIMIT: 30 req/min
IDEMPOTENCY: policy_id
RETRY: 1 on 5xx
Tool 5: extend_policy
PURPOSE: Extend coverage when trip overruns
SLA: p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT: 30 req/min
IDEMPOTENCY: policy_id
RETRY: 1 on 5xx
SECTION 5 — RESPONSE SHAPE
TravelQuote
TravelQuote:
quote_id: { type: string, constraint: REQUIRED, opaque }
insurer:
insurer_id: { type: string, constraint: REQUIRED }
name: { type: string, constraint: REQUIRED }
irdai_registration_number: { type: string, constraint: REQUIRED }
claim_settlement_ratio_pct: { type: float, constraint: REQUIRED, 0-100 }
travel_claim_settlement_days_avg: { type: float, constraint: REQUIRED, ≥0 }
solvency_ratio: { type: float, constraint: REQUIRED, 1.0-5.0 }
global_assistance_partner: { type: string, constraint: REQUIRED, semantics: "e.g. Allianz Global Assistance, AXA Assistance" }
product_name: { type: string, constraint: REQUIRED }
product_uin: { type: string, constraint: REQUIRED }
trip_type: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
destination_zone: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
is_schengen_compliant: { type: boolean, constraint: REQUIRED, semantics: "Guarantees ≥€30k medical for Schengen visa" }
cover_amounts:
medical_emergency_usd: { type: int, constraint: REQUIRED, ≥0 }
medical_evacuation_usd: { type: int, constraint: REQUIRED, ≥0 }
repatriation_remains_usd: { type: int, constraint: REQUIRED, ≥0 }
dental_emergency_usd: { type: int, constraint: REQUIRED, ≥0 }
accidental_death_usd: { type: int, constraint: REQUIRED, ≥0 }
permanent_disability_usd: { type: int, constraint: REQUIRED, ≥0 }
baggage_loss_usd: { type: int, constraint: REQUIRED, ≥0 }
baggage_delay_usd: { type: int, constraint: REQUIRED, ≥0 }
passport_loss_usd: { type: int, constraint: REQUIRED, ≥0 }
trip_cancellation_usd: { type: int, constraint: REQUIRED, ≥0, semantics: "0 if addon not included" }
trip_curtailment_usd: { type: int, constraint: REQUIRED, ≥0 }
trip_delay_usd: { type: int, constraint: REQUIRED, ≥0 }
missed_connection_usd: { type: int, constraint: REQUIRED, ≥0 }
hijacking_distress_usd: { type: int, constraint: REQUIRED, ≥0 }
personal_liability_usd: { type: int, constraint: REQUIRED, ≥0 }
deductible_usd: { type: int, constraint: REQUIRED, ≥0 }
co_pay_pct: { type: int, constraint: REQUIRED, 0-30 }
premium_breakdown:
base_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
age_loading_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
addon_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
gst_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
total_payable_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
policy_start_date: { type: string, constraint: REQUIRED, ISO_DATE }
policy_end_date: { type: string, constraint: REQUIRED, ISO_DATE }
addons_included:
type: array<Addon>
constraint: REQUIRED, may be empty
shape:
code: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
label: { type: string, constraint: REQUIRED }
sub_limit_usd: { type: int, constraint: REQUIRED, ≥0 }
premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
exclusions_summary:
type: array<enum>
constraint: REQUIRED, STRICT ENUM §6
semantics: "Standard exclusions explicitly disclosed"
pre_existing_coverage:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [none, life_threatening_only, full]
assistance_helpline_phone: { type: string, constraint: REQUIRED, E.164, semantics: "24×7 multilingual" }
cashless_hospital_network_size: { type: int, constraint: REQUIRED, ≥0 }
instant_issuance_possible: { type: boolean, constraint: REQUIRED }
estimated_issuance_minutes: { type: int, constraint: REQUIRED, 1-1440 }
policy_wording_url: { type: string, constraint: REQUIRED, HTTPS URL }
customer_information_sheet_url: { type: string, constraint: REQUIRED, HTTPS URL }
partner_reference:
source: { type: string, constraint: REQUIRED }
deeplink: { type: string, constraint: REQUIRED, HTTPS URL }
KYCResult
KYCResult:
kyc_id: { type: string, constraint: REQUIRED }
quote_id: { type: string, constraint: REQUIRED }
kyc_status:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [verified_passport, verified_aadhaar, verified_pan, pending_manual, failed]
passport_verification_status:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [verified, mismatch, expired_before_return, pending]
documents_pending: { type: array<string>, constraint: REQUIRED, may be empty }
expires_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
IssuedPolicy
IssuedPolicy:
policy_id: { type: string, constraint: REQUIRED, immutable }
policy_number: { type: string, constraint: REQUIRED }
insurer_id: { type: string, constraint: REQUIRED }
product_uin: { type: string, constraint: REQUIRED }
trip_type: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
policy_start_date: { type: string, constraint: REQUIRED, ISO_DATE }
policy_end_date: { type: string, constraint: REQUIRED, ISO_DATE }
is_schengen_compliant: { type: boolean, constraint: REQUIRED }
total_paid_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
policy_pdf_url: { type: string, constraint: REQUIRED, HTTPS URL, semantics: "Visa-compliant document; English; insurer letterhead" }
visa_letter_url: { type: string, constraint: REQUIRED nullable, HTTPS URL, semantics: "Standalone Schengen-compliant letter when needed" }
insured_members_count: { type: int, constraint: REQUIRED, ≥1 }
assistance_helpline_phone: { type: string, constraint: REQUIRED, E.164 }
emergency_evacuation_phone: { type: string, constraint: REQUIRED, E.164 }
freelook_period_days: { type: int, constraint: REQUIRED, 0-15, semantics: "0 if trip has started" }
ExtensionResult
ExtensionResult:
policy_id: { type: string, constraint: REQUIRED }
extended_until: { type: string, constraint: REQUIRED, ISO_DATE }
additional_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
extension_status:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [extended, declined_pre_existing_claim, declined_max_duration, payment_pending]
CancellationResult
CancellationResult:
policy_id: { type: string, constraint: REQUIRED }
cancelled_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
refund_amount_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
refund_method: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
refund_eta_days: { type: int, constraint: REQUIRED, 0-30 }
cancellation_reason: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }
is_freelook_cancellation: { type: boolean, constraint: REQUIRED }
FORBIDDEN FIELDS
paid_placement_score,ad_bid,sponsored_rank,kickback_amountartificial_urgency_text("Visa rejection guarantee!" type misleading)ai_generated_photofor insurer / assistance partner imageryfabricated_schengen_compliance(false schengen_compliant=true when actual medical < €30k)inflated_claim_settlement_ratioeditor_recommended,tomo_pickfalse_covid_cover(covid_cover addon claimed but not in actual product disclosure)
SECTION 6 — CONTROLLED VOCABULARIES
trip_type:
values:
single_trip: "One-off trip, fixed dates"
annual_multi_trip: "Multiple trips in 12 months; per-trip cap"
student: "Long-stay (>180 days) educational travel"
senior: "60+ traveller variant with senior-specific terms"
trip.destination_zone:
values:
schengen: "26 Schengen-area countries"
europe_non_schengen: "UK, Ireland, etc."
usa_canada: "USA + Canada"
asia_excl_japan: "Asian destinations excluding Japan"
japan: "Japan-specific (priced separately)"
worldwide_excl_us: "Global excluding USA / Canada"
worldwide_inc_us: "Global including USA / Canada"
india_domestic: "India domestic travel"
trip.trip_purpose:
values: [leisure, business, education, medical_tourism, religious_pilgrimage, sports, conference]
cover_preferences.currency_of_cover:
values: [USD, EUR, INR, GBP, AUD, JPY, CAD]
insured_members[].pre_existing_conditions:
values:
none, hypertension, diabetes_type1, diabetes_type2, cardiac, cancer_remission,
kidney_disease, liver_disease, mental_health, autoimmune, respiratory_chronic,
neurological, pregnancy, other_disclosed
cover_preferences.addons_required / addons_included.code:
values:
covid_cover: "COVID treatment + quarantine"
adventure_sports_amateur: "Skiing, scuba, trekking ≤6000m (non-professional)"
adventure_sports_pro: "Professional adventure activities"
trip_cancellation: "Pre-departure cancellation reasons"
trip_interruption: "Post-departure curtailment"
trip_delay: "Common-carrier delay benefit"
baggage_protection_extra: "Higher baggage limit"
home_burglary: "Cover while travelling"
gadget_protection: "Electronics protection"
rental_car_excess: "CDW excess waiver"
sports_equipment: "Equipment cover"
cruise_cover: "Cruise-specific perils"
exclusions_summary:
values:
self_inflicted, intoxication, illegal_activity, war_terrorism,
pre_existing_uncovered, professional_sport, pregnancy_routine,
nuclear, mental_health_uncovered, suicide_within_12m
pre_existing_coverage:
values: [none, life_threatening_only, full]
kyc_status: [verified_passport, verified_aadhaar, verified_pan, pending_manual, failed]
passport_verification_status: [verified, mismatch, expired_before_return, pending]
extension_status: [extended, declined_pre_existing_claim, declined_max_duration, payment_pending]
cancellation_reason:
values: [pre_departure_voluntary, freelook, visa_rejected, trip_cancelled_other_reason, duplicate_policy]
refund_method: [original_payment, bank_transfer, cheque]
SECTION 7 — TTBS DIMENSIONS
TIME (weight = 0.30):
signals_used:
- instant_issuance_possible
- estimated_issuance_minutes
- is_schengen_compliant (when schengen_compliant_required)
weighting:
instant: 0.55
minutes: 0.30
schengen_match: 0.15
user_band_handling:
fast: highly favour instant; reject anything >2h issuance
TASTE (weight = 0.15):
signals_used:
- insurer matches preferred_insurers
- insurer matches user DNA history
- global_assistance_partner reputation
weighting:
preferred_insurer: 0.50
dna_familiarity: 0.30
assistance_brand: 0.20
BUDGET (weight = 0.25):
signals_used:
- premium_breakdown.total_payable_inr
- addon_premium_inr fit to addons_required
- deductible_usd (higher = lower premium; balance per user_band)
- co_pay_pct
weighting:
total: 0.65
addon_fit: 0.20
deductible_fit: 0.10
co_pay_balance: 0.05
SAFETY (weight = 0.30):
signals_used:
- insurer.claim_settlement_ratio_pct
- insurer.travel_claim_settlement_days_avg (lower preferred)
- insurer.solvency_ratio
- cashless_hospital_network_size (≥1000 strong, ≥5000 excellent)
- cover_amounts.medical_emergency_usd vs schengen / destination floor
- pre_existing_coverage (full > life_threatening_only > none)
weighting:
csr: 0.25
settlement_speed: 0.20
solvency: 0.15
network_size: 0.20
medical_cover: 0.10
ped_handling: 0.10
user_band_handling:
fast: relax PED handling
balanced: standard
great: prefer pre_existing_coverage=full + cashless ≥5000
Locked weights per finance.buy_travel_insurance: time 0.30 / taste 0.15 / budget 0.25 / safety 0.30. Time-heavy because users typically buy within 1-2 days of departure or visa-deadline pressure.
SECTION 8 — COMPLETION CONTRACT
POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body:
{
"intent": "finance.buy_travel_insurance",
"external_id": "<policy_id>",
"request_id": "<request_id>",
"amount_inr": 450, // NET partner commission only (typically 15-30% of premium)
"gst_inr": 81,
"tips_inr": 0,
"pass_through_inr": 2200, // premium remitted to insurer
"closed_at": "2026-10-12T11:20:00+05:30",
"status": "completed",
"insurer_id": "tata_aig",
"product_uin": "IRDAI/TRV/TAIG/2024-25-011",
"trip_type": "single_trip",
"destination_zone": "schengen",
"is_schengen_compliant": true,
"insured_members_count": 2,
"trip_duration_days": 12
}
HMAC-SHA256, 5-min replay, NET-only commission.
SECTION 9 — WIDGET
TravelInsuranceWidget (planned). Interim: ListingsWidget.
Field mapping:
- TravelQuote.insurer.name + logo → header
- product_name → subhead
- is_schengen_compliant → green "Schengen ✓" badge (top-left)
- premium_breakdown.total_payable_inr → big price
- cover_amounts.medical_emergency_usd → "$X medical" pill
- cover_amounts.baggage_loss_usd → "$X baggage" pill
- addons_included.length → "+X addons" pill
- cashless_hospital_network_size → "X cashless globally" line
- instant_issuance_possible → green instant badge
- assistance_helpline_phone → "24×7 helpline" line
SECTION 10 — CACHING POLICY
| Call | TTL | Rationale |
|---|---|---|
| search_travel_quotes | 5min | Premiums table-driven, very stable |
| confirm_quote_and_kyc | NO CACHE | Idempotent |
| issue_policy | NO CACHE | — |
| extend_policy | NO CACHE | — |
| cancel_or_freelook | NO CACHE | — |
| Insurer static (CSR, solvency, network) | 24h | Insurer publishes periodically |
| Product wording / CIS | 7d | UIN-versioned |
SECTION 11 — ERROR CODES
| Code | HTTP | Meaning | Retry |
|---|---|---|---|
INVALID_REQUEST |
400 | Malformed | No |
RATE_LIMITED |
429 | Throttle | 1, 2s |
INTERNAL_ERROR |
500 | Partner failure | 2, exp |
SIGNATURE_INVALID |
401 | HMAC fail | No |
PASSPORT_EXPIRY_INVALID |
422 | Passport expires within 6mo of return | No |
AGE_OUT_OF_RANGE |
422 | Member age outside product band | No |
DESTINATION_NOT_COVERED |
422 | Country / zone outside insurer appetite | No |
TRIP_DURATION_EXCEEDED |
422 | Duration above product max | No |
SCHENGEN_NOT_COMPLIANT |
422 | Product does not meet €30k floor | No (UI re-quotes) |
PED_DECLINED |
422 | Pre-existing outside appetite | No |
KYC_FAILED |
422 | KYC mismatch | No |
DEPARTURE_DATE_TOO_SOON |
422 | Below insurer min lead time | No |
DEPARTURE_DATE_TOO_FAR |
422 | Above insurer max lead time (typically 180d) | No |
MEMBER_COUNT_EXCEEDED |
422 | More than 6 insured | No |
PAYMENT_FAILED |
402 | Gateway declined | No |
INSURER_DOWN |
503 | Insurer API unavailable | 1 retry, 2s |
FREELOOK_WINDOW_EXPIRED |
410 | Past free-look | No |
EXTENSION_DECLINED |
422 | Trip overrun cannot be extended | No |
SECTION 12 — SANDBOX → PRODUCTION CHECKLIST
[ ] All five tools implemented
[ ] At least 5 insurers in catalog
[ ] All IRDAI registration numbers verifiable
[ ] All product UINs verifiable
[ ] CSR, solvency, travel_claim_settlement_days match IRDAI publication
[ ] Schengen-compliant quotes guarantee ≥€30,000 medical_emergency cover
[ ] Schengen-compliant policy_pdf or visa_letter URL returns valid embassy-acceptable document
[ ] Visa-letter format matches Schengen consulate requirements (English, insurer letterhead)
[ ] Pre-existing handling per IRDAI / product disclosure (full / life-threatening / none)
[ ] Global assistance helpline 24×7 with multilingual support
[ ] cashless_hospital_network_size matches assistance partner's actual network
[ ] All controlled vocabularies respected
[ ] HMAC signing verified
[ ] amount_inr in CPC is partner COMMISSION only (NET), NOT total premium
[ ] pass_through_inr correctly captures remitted premium
[ ] No forbidden fields anywhere
[ ] SLA p95 met
[ ] IRDAI license uploaded
[ ] Compliance: GSTIN, IRDAI license, privacy policy, grievance officer
[ ] COVID addon disclosure matches insurer's IRDAI-filed product
[ ] Adventure-sports addon clearly defines covered activity classes
SECTION 13 — ANTI-FABRICATION RULES
RULE 1: No paid_placement / ad / kickback fields.
RULE 2: claim_settlement_ratio_pct must match IRDAI publication.
RULE 3: travel_claim_settlement_days_avg must reflect insurer's actual
public disclosure.
RULE 4: is_schengen_compliant=true REQUIRES medical_emergency_usd
equivalent to ≥€30,000 AND policy document acceptable to
Schengen consulates. Falsely flagging compliance =
customer-harm (visa rejection) + immediate suspension.
RULE 5: Pre-existing coverage flag must match product's IRDAI-filed
disclosure. "Full" PED cover for a product that excludes PEDs =
suspension.
RULE 6: COVID cover addon, if shown, must be in the actual product as
of the quote timestamp. Removing COVID cover post-quote =
customer-harm + suspension.
RULE 7: cashless_hospital_network_size must match assistance partner's
actual network. Padding network counts = claim-time customer-
harm + suspension.
RULE 8: global_assistance_partner must be the partner actually
contracted. Misstating = customer-harm at emergency moment +
immediate suspension.
RULE 9: artificial_urgency_text forbidden ("Buy now or visa rejected!")
Premium revisions / cover changes must be IRDAI-notified.
RULE 10: No AI-generated insurer / assistance imagery.
RULE 11: amount_inr in CPC is partner's NET commission only — NEVER
total premium. Falsely reporting premium = suspension.
RULE 12: No "Best for Schengen" / "Top Pick" / "TOMO Recommended" badges.
Insurance recommendation is regulated.
RULE 13: information_completeness_score (hidden ranking factor, weight
0.10) rewards full §5 shape.
RULE 14: exclusions_summary must be the actual product exclusions.
Hiding exclusions = customer-harm + suspension.
RULE 15: estimated_issuance_minutes must be honest. Travellers often
need policy in minutes (visa appointments). Padding instant
claims = customer-harm.
RULE 16: assistance_helpline_phone must be operational 24×7. TOMO
spot-checks monthly.
VERSION HISTORY
v1.0.0 — 2026-05-13 — Initial spec. Single-trip / annual / student / senior
variants under one intent via trip_type discriminator.
Schengen-compliance hard-enforced. Time-heavy TTBS
reflecting visa-deadline / pre-departure buying.
NET commission base.