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.
● DRAFTv1.0.0finance.buy_motor_insurance

Intent Spec — finance.buy_motor_insurance

FULL ID:       finance.buy_motor_insurance
VERSION:       v1.0.0
STATUS:        draft
LAST UPDATED:  2026-05-13
DOMAIN:        finance
PRIMARY AGENT: FinanceAgent
TTBS WEIGHTS:  time=0.20 taste=0.20 budget=0.30 safety=0.30

User buys a fresh motor insurance policy from the finance-domain entry point. Covers private cars, two-wheelers, electric vehicles, and commercial vehicles. Distinct from auto.book_insurance_renewal which targets renewal flows from vehicle context. This intent handles new-policy purchase (e.g. just-bought vehicle, lapsed policies that require fresh issuance, switch-insurer purchase).

Partner exemplars: Policybazaar, Acko, Digit, Bajaj Allianz, ICICI Lombard, HDFC ERGO, Tata AIG, SBI General, Reliance General, Liberty General.


SECTION 1 — INTENT IDENTITY

User wants to buy a fresh motor insurance policy. Distinct from:

  • auto.book_insurance_renewal — renewal of an existing live policy from vehicle context; this intent is for new policies
  • finance.buy_term_insurance / finance.buy_health_insurance — non-motor cover
  • auto.file_insurance_claim — claim filing (v1.1+)
  • auto.buy_new_insurance (vehicle-domain) — same logical operation, different domain entry; both route to this contract
  • Renewal where current policy is still live — that intent routes through auto-domain handler with NCB transfer logic

Single intent per vehicle. Multi-vehicle households fire one intent per vehicle.


SECTION 2 — NATURAL LANGUAGE COVERAGE

CLASSIFIES IN

  • "Buy car insurance for my new Tata Punch"
  • "First-time motor insurance, just bought the bike"
  • "Switch my car insurance to a different insurer"
  • "Lapsed insurance for 8 months, get me a fresh policy"
  • "Insurance for my new EV"
  • "Commercial vehicle insurance for my Tata Ace"
  • "Zero-dep cover for the car I bought yesterday"
  • "Cheapest third-party-only for my Activa"
  • "Standalone OD policy after I let the previous one lapse"
  • "New comprehensive cover, my Innova"

CLASSIFIES OUT — BORDERLINE NO

  • "Renew my car insurance" → auto.book_insurance_renewal
  • "File a claim" → v1.1+ auto.file_insurance_claim
  • "Insurance for my home" → out of scope v1
  • "Insurance for my health" → finance.buy_health_insurance
  • "Term life cover" → finance.buy_term_insurance
  • "What's my IDV?" — non-transactional research

MULTI-INTENT TRIGGERS

  • "Buy car + insurance + RC transfer" → marketplace.buy_used_car + finance.buy_motor_insurance + auto.book_rc_transfer
  • "New EV + insurance + charger install" → finance.buy_motor_insurance + auto.book_ev_charger_install
  • "Motor insurance + pollution check" → finance.buy_motor_insurance + auto.book_pollution_check

SECTION 3 — INPUT (TOMO → PROVIDER)

{
  "intent": "finance.buy_motor_insurance",
  "request_id": "req_01J9Z...",
  "user_locale": "en-IN",
  "user_currency": "INR",
  "user_location": { "lat": 17.4475, "lng": 78.3563, "city": "Hyderabad", "pincode": "500032" },
  "purchase_context":  "newly_purchased",              // STRICT ENUM §6
  "vehicle": {
    "type": "car",                                       // STRICT ENUM §6
    "subtype": "private_car",                            // STRICT ENUM §6
    "make": "Tata", "model": "Punch", "variant": "Pure",
    "fuel_type": "petrol",                               // STRICT ENUM §6
    "engine_cc": 1199,
    "kw_rating": null,                                   // REQUIRED for EVs
    "battery_kwh": null,                                 // REQUIRED for EVs
    "year_of_manufacture": 2026,
    "year_of_first_registration": 2026,
    "registration_number": "TS09HZ1234",
    "registration_state": "TS",                          // STRICT ENUM §6
    "rto_office": "TS09",
    "chassis_number_last4": "5678",
    "engine_number_last4": "9012",
    "invoice_value_inr": 750000,                         // REQUIRED for newly_purchased
    "carrying_capacity_persons": 5,                      // private car
    "carrying_capacity_tonnes": null                     // commercial only
  },
  "previous_policy": {
    "has_prior_policy": false,
    "insurer_name": null,
    "expiry_date": null,
    "claims_filed_last_year": 0,
    "ncb_pct_carry_forward": 0,
    "lapse_days": null
  },
  "buyer_preferences": {
    "target_policy_type": "comprehensive",               // STRICT ENUM §6
    "idv_preference": "invoice_value",                   // STRICT ENUM §6
    "addons_required": ["zero_dep", "engine_protect", "rsa_24x7", "consumables"],
    "preferred_tenure_years": 1,                          // 1 | 3 (long-term cars/2W: 1+3 / 1+5)
    "long_term_tp_years": 0,                              // 3 or 5 for new vehicle TP bundle
    "instant_issuance_required": true,
    "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_motor_insurance
purchase_context enum REQUIRED, STRICT ENUM §6 newly_purchased / switching / lapsed_fresh / used_vehicle_first_policy
vehicle.type enum REQUIRED, STRICT ENUM §6 car / two_wheeler / commercial / ev
vehicle.fuel_type enum REQUIRED, STRICT ENUM §6 petrol / diesel / cng / lpg / electric / hybrid
vehicle.kw_rating int REQUIRED nullable Non-null required when fuel_type=electric
vehicle.battery_kwh float REQUIRED nullable Non-null required when fuel_type=electric
vehicle.registration_state enum REQUIRED, STRICT ENUM §6
vehicle.invoice_value_inr int REQUIRED, INR_INTEGER Non-null when purchase_context=newly_purchased
previous_policy.has_prior_policy bool REQUIRED When TRUE, expiry_date + insurer_name REQUIRED
buyer_preferences.target_policy_type enum REQUIRED, STRICT ENUM §6
buyer_preferences.long_term_tp_years int REQUIRED, 0/3/5 0 for non-new; new car=3yr TP mandatory, new 2W=5yr TP mandatory (Sup.Ct ruling)
buyer_preferences.addons_required array REQUIRED, STRICT ENUM §6 May be empty

Anti-fabrication preamble: Provider may not quote a premium below the IRDAI tariff floor for the third-party portion. New 4-wheelers (private) mandate a 3-year TP bundle by Supreme Court order; new 2-wheelers mandate a 5-year TP bundle. NCB carry-forward applies only when previous policy exists AND no claim was filed.


SECTION 4 — PROVIDER TOOLS

Tool 1: search_motor_quotes

PURPOSE:      Up to 15 quotes matching vehicle + policy_type + addons + tenure
SLA:          p50 ≤ 800ms, p95 ≤ 2500ms, p99 ≤ 5000ms
RATE LIMIT:   60 req/min
IDEMPOTENCY:  request_id; 30s cache
RETRY:        1 on 429, 2 on 5xx

Tool 2: confirm_quote_and_kyc

PURPOSE:      Lock quote + KYC + nominee (if applicable)
SLA:          p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT:   30 req/min
IDEMPOTENCY:  request_id
RETRY:        No retry

Tool 3: issue_policy

PURPOSE:      Issue policy after KYC + payment
SLA:          p50 ≤ 2500ms, p95 ≤ 7000ms, p99 ≤ 15000ms
RATE LIMIT:   30 req/min
IDEMPOTENCY:  request_id
RETRY:        No retry on issuance

Tool 4: schedule_inspection

PURPOSE:      Book vehicle inspection (lapsed >90d, post-claim, used-vehicle first policy)
SLA:          p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT:   30 req/min
IDEMPOTENCY:  quote_id
RETRY:        1 on 5xx

Tool 5: cancel_or_freelook

PURPOSE:      15-day IRDAI free-look OR pre-issuance cancellation
SLA:          p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT:   30 req/min
IDEMPOTENCY:  policy_id
RETRY:        1 on 5xx

SECTION 5 — RESPONSE SHAPE

MotorQuote

MotorQuote:
  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 }
    motor_claim_settlement_days_avg: { type: float, constraint: REQUIRED, ≥0, semantics: "Avg days from FIR to claim settlement" }
    solvency_ratio: { type: float, constraint: REQUIRED, 1.0-5.0 }

  product_name: { type: string, constraint: REQUIRED }
  product_uin: { type: string, constraint: REQUIRED }

  policy_type:
    type: enum
    constraint: REQUIRED, STRICT ENUM §6
    values: [third_party_only, comprehensive, own_damage_only, standalone_od_with_separate_tp, long_term_tp_bundle]

  idv_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
  idv_basis: { type: enum, constraint: REQUIRED, STRICT ENUM §6 }

  premium_breakdown:
    own_damage_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    third_party_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0, semantics: "IRDAI-tariff floor enforced" }
    long_term_tp_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0, semantics: "3yr or 5yr TP bundle for new vehicles" }
    addons_premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    ncb_discount_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    other_discount_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 }

  ncb_applied_pct: { type: int, constraint: REQUIRED, 0-50 }
  long_term_tp_years: { type: int, constraint: REQUIRED, 0/3/5 }

  tenure_years: { type: int, constraint: REQUIRED, 1-3 }
  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 }
      premium_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }

  cashless_garage_count_in_state: { type: int, constraint: REQUIRED, ≥0 }
  cashless_garage_count_in_city: { type: int, constraint: REQUIRED, ≥0 }
  garage_directory_url: { type: string, constraint: REQUIRED, HTTPS URL }

  inspection_required: { type: boolean, constraint: REQUIRED, semantics: "TRUE when prior policy lapsed >90 days, used-vehicle first policy, etc." }
  instant_issuance_possible: { type: boolean, constraint: REQUIRED }
  estimated_issuance_minutes: { type: int, constraint: REQUIRED, 1-2880 }

  policy_wording_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_aadhaar, verified_pan, verified_dl, pending_manual, failed]
  documents_required: { type: array<string>, constraint: REQUIRED, may be empty }
  ckyc_id: { type: string, constraint: REQUIRED nullable }
  expires_at: { type: string, constraint: REQUIRED, ISO_DATETIME }

InspectionResult

InspectionResult:
  inspection_id: { type: string, constraint: REQUIRED }
  quote_id: { type: string, constraint: REQUIRED }
  scheduled_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
  location:
    type: object
    constraint: REQUIRED
    shape:
      mode: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [self_video, in_person_garage, surveyor_home_visit] }
      address: { type: string, constraint: REQUIRED nullable }
      garage_name: { type: string, constraint: REQUIRED nullable }
  expected_completion_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
  inspector_contact: { type: string, constraint: REQUIRED, E.164 }

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 }
  policy_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 }
  long_term_tp_end_date: { type: string, constraint: REQUIRED nullable, ISO_DATE, semantics: "non-null for 3yr/5yr TP bundle" }
  total_paid_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
  policy_pdf_url: { type: string, constraint: REQUIRED, HTTPS URL }
  certificate_of_insurance_url: { type: string, constraint: REQUIRED, HTTPS URL }
  freelook_period_days: { type: int, constraint: REQUIRED, 7-30 }
  freelook_ends_at: { type: string, constraint: REQUIRED, ISO_DATE }
  claim_helpline_phone: { type: string, constraint: REQUIRED, E.164 }
  emergency_assistance_phone: { type: string, constraint: REQUIRED nullable, E.164, semantics: "RSA addon helpdesk" }

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 }
  is_freelook_cancellation: { type: boolean, constraint: REQUIRED }

FORBIDDEN FIELDS

  • paid_placement_score, ad_bid, sponsored_rank, kickback_amount, commission_padded_premium
  • artificial_urgency_text ("Rates go up tomorrow!" without verifiable revision)
  • ai_generated_photo for insurer logos
  • below_irdai_floor_premium (any premium below IRDAI tariff floor is per-se invalid)
  • inflated_claim_settlement_ratio
  • editor_recommended, tomo_pick, best_for_new_vehicle

SECTION 6 — CONTROLLED VOCABULARIES

purchase_context:
  values:
    newly_purchased:           "Vehicle bought ≤30 days ago, no prior policy"
    switching:                 "Live policy exists, switching at renewal"
    lapsed_fresh:              "Previous policy lapsed >0 days; fresh issuance"
    used_vehicle_first_policy: "Used vehicle bought; first policy under new owner"

vehicle.type:
  values: [car, two_wheeler, commercial, ev]

vehicle.subtype:
  values:
    private_car, suv, mpv, hatchback, sedan,
    scooter, motorcycle, moped, e_scooter, e_motorcycle,
    taxi, school_bus, goods_carrier_lcv, goods_carrier_hcv, passenger_carrier
    e_car, e_bike_commercial

vehicle.fuel_type:
  values: [petrol, diesel, cng, lpg, electric, hybrid]

vehicle.registration_state: [AP, AR, AS, BR, CG, GA, GJ, HR, HP, JH, KA, KL, MP, MH, MN, ML, MZ, NL, OD, PB, RJ, SK, TN, TS, TR, UP, UK, WB, AN, CH, DN, DD, DL, JK, LA, LD, PY]

buyer_preferences.target_policy_type / policy_type:
  values:
    third_party_only:                "TP-only (legal minimum)"
    comprehensive:                   "TP + Own Damage"
    own_damage_only:                 "OD only (TP held separately)"
    standalone_od_with_separate_tp:  "Standalone OD + separately purchased TP"
    long_term_tp_bundle:             "1yr OD + 3yr/5yr TP (new vehicle mandatory)"

idv_preference / idv_basis:
  values:
    invoice_value:  "Ex-showroom + on-road (newly purchased)"
    market_value:   "Depreciated market value (used vehicle)"
    declared_max:   "Max IDV permissible per IRDAI"
    custom:         "User-declared within IRDAI bounds"

addons_required / addons_included.code:
  values:
    zero_dep, engine_protect, rsa_24x7, return_to_invoice, consumables,
    ncb_protect, key_replacement, passenger_cover, tyre_protect,
    daily_allowance, geo_extension_nepal_bhutan, battery_protect_ev,
    charger_protect_ev, ev_assistance

kyc_status: [verified_aadhaar, verified_pan, verified_dl, pending_manual, failed]

InspectionResult.location.mode: [self_video, in_person_garage, surveyor_home_visit]

refund_method: [original_payment, bank_transfer, cheque]

SECTION 7 — TTBS DIMENSIONS

TIME (weight = 0.20):
  signals_used:
    - instant_issuance_possible
    - estimated_issuance_minutes
    - inspection_required (FALSE preferred)
  weighting:
    instant: 0.50
    minutes: 0.30
    inspection_avoided: 0.20

TASTE (weight = 0.20):
  signals_used:
    - insurer matches preferred_insurers
    - insurer matches user DNA history
    - cashless_garage_count_in_city
    - product_name brand familiarity (OEM-branded insurance preference)
  weighting:
    preferred_insurer: 0.40
    dna_familiarity: 0.25
    cashless_in_city: 0.20
    oem_signal: 0.15

BUDGET (weight = 0.30):
  signals_used:
    - premium_breakdown.total_payable_inr
    - addons_premium_inr fit to addons_required exactly
  weighting:
    total: 0.75
    addon_fit: 0.25

SAFETY (weight = 0.30):
  signals_used:
    - insurer.claim_settlement_ratio_pct
    - insurer.motor_claim_settlement_days_avg (lower preferred)
    - insurer.solvency_ratio
    - cashless_garage_count_in_state
    - policy_wording_url present
  weighting:
    csr: 0.30
    settlement_speed: 0.25
    solvency: 0.20
    cashless_state: 0.15
    wording_present: 0.10
  user_band_handling:
    fast: relax CSR to 90%
    balanced: floor 92%
    great: prefer CSR ≥95% AND settlement_days ≤21

Locked weights per finance.buy_motor_insurance: time 0.20 / taste 0.20 / budget 0.30 / safety 0.30. Matches the renewal intent's weights for cross-flow consistency.


SECTION 8 — COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body:
{
  "intent":           "finance.buy_motor_insurance",
  "external_id":      "<policy_id>",
  "request_id":       "<request_id>",
  "amount_inr":       3600,    // NET partner commission only (typically 10-15% of first-year premium)
  "gst_inr":          648,
  "tips_inr":         0,
  "pass_through_inr": 24000,   // first-year premium remitted to insurer
  "closed_at":        "2026-05-30T11:20:00+05:30",
  "status":           "completed",
  "insurer_id": "tata_aig",
  "product_uin": "IRDAI/MV/PCL/2023-24-007",
  "policy_type": "long_term_tp_bundle",
  "long_term_tp_years": 3,
  "addons_count": 4
}

Important: amount_inr = partner commission only. Premium remitted to insurer = pass_through_inr. TOMO charges 10% × commission only.

HMAC-SHA256, 5-min replay, NET-only commission.


SECTION 9 — WIDGET

MotorInsuranceWidget (planned). Interim: comparison ListingsWidget.

Field mapping:
  - MotorQuote.insurer.name + logo → header
  - product_name → subhead
  - claim_settlement_ratio_pct + motor_claim_settlement_days_avg → dual pill
  - premium_breakdown.total_payable_inr → big price
  - idv_inr → "IDV ₹X" pill
  - long_term_tp_years → "Xyr TP bundle" badge when >0
  - addons_included.length → "+X addons" pill
  - cashless_garage_count_in_city → "X cashless garages" pill
  - instant_issuance_possible → green badge
  - policy_wording_url → "Read wording" link

SECTION 10 — CACHING POLICY

Call TTL Rationale
search_motor_quotes 30s Premiums fluctuate; live insurer pricing
confirm_quote_and_kyc NO CACHE Idempotent
schedule_inspection NO CACHE Live calendar
issue_policy NO CACHE
cancel_or_freelook NO CACHE
Insurer static (CSR, solvency, garage counts) 24h IRDAI publishes annually; garage updated periodically
Product wording 7d UIN-versioned
Garage directory 24h Insurer-published

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
VEHICLE_NOT_FOUND_IN_VAHAN 422 Registration not in govt VAHAN database No
INVOICE_VALUE_INVALID 422 Invoice value missing for newly_purchased No
LONG_TERM_TP_REQUIRED 422 New car/2W requires 3yr/5yr TP bundle No (UI re-quotes)
IDV_OUT_OF_RANGE 422 Declared IDV outside permissible band No
ADDON_INCOMPATIBLE 422 Addon unavailable for policy_type / vehicle_type No
INSPECTION_REQUIRED 200 (advisory) inspection_required=true in quote n/a
KYC_FAILED 422 KYC mismatch No
PAYMENT_FAILED 402 Gateway declined No
INSURER_DOWN 503 Insurer API unavailable 1 retry, 2s
FREELOOK_WINDOW_EXPIRED 410 Past free-look No
EV_KW_MISSING 422 kw_rating / battery_kwh missing for EV 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, motor_claim_settlement_days match latest IRDAI publication
[ ] IRDAI third-party tariff floor enforced; no below-floor quotes
[ ] Long-term TP bundle correctly applied for new 4W (3yr) and 2W (5yr)
[ ] IDV bounds correctly enforced per IRDAI for vehicle age band
[ ] EV-specific fields (kw_rating, battery_kwh) handled
[ ] Cashless garage counts reflect ACTIVE (not historical) network
[ ] garage_directory_url returns live, browsable list
[ ] All controlled vocabularies respected
[ ] HMAC signing verified
[ ] amount_inr in CPC is partner COMMISSION only (NET), NOT premium
[ ] pass_through_inr correctly captures premium remitted
[ ] freelook_period_days ≥ 7 (IRDAI minimum, default 15)
[ ] inspection_required TRUE for lapsed >90d / used-vehicle-first scenarios
[ ] No forbidden fields anywhere
[ ] SLA p95 met
[ ] IRDAI POSP / corporate-agent / broker license uploaded
[ ] Compliance: GSTIN, IRDAI license, privacy policy, grievance officer
[ ] Customer support: 24×7 claims + RSA helpdesk (if RSA addon offered)

SECTION 13 — ANTI-FABRICATION RULES

RULE 1: No paid_placement / ad / kickback fields.

RULE 2: claim_settlement_ratio_pct MUST match IRDAI's latest annual
        publication. Inflation = suspension.

RULE 3: motor_claim_settlement_days_avg must match insurer's IRDAI-filed
        public disclosure. Faking faster settlement = customer-harm at
        claim time + suspension.

RULE 4: third_party_premium_inr cannot be below IRDAI tariff floor for the
        vehicle cc / GVW band. Below-floor = per-se invalid.

RULE 5: long_term_tp_premium_inr must be calculated per IRDAI's long-term
        TP rate card. Discounting below the rate card = suspension.

RULE 6: ncb_applied_pct must reflect verifiable past claim history. NCB
        carry-forward is permitted only between consecutive policy years
        (with grace per IRDAI). Awarding NCB to fresh / claim-filed users =
        customer-harm + insurer-relationship breach + immediate suspension.

RULE 7: irdai_registration_number must be current.
        product_uin must be on IRDAI's approved product list.

RULE 8: policy_wording_url must be IRDAI-compliant for the specific UIN.
        Marketing brochures = customer-harm + regulatory risk + suspension.

RULE 9: Cashless garage counts must reflect ACTIVE empanelment as of the
        quote timestamp. Counting historical / paused garages = customer-
        harm at claim time + suspension.

RULE 10: garage_directory_url must return live, searchable directory.
         Stale PDF >90 days = warning then suspension.

RULE 11: artificial_urgency_text forbidden ("Rate increases tomorrow!")
         unless backed by IRDAI-notified revision date.

RULE 12: No AI-generated insurer logos / garage imagery.

RULE 13: amount_inr in CPC is partner's NET commission only — NEVER the
         total premium remitted to insurer. Falsely reporting premium as
         revenue = suspension.

RULE 14: No "Best for new vehicle" / "Top Pick" / "TOMO Recommended" badges.
         Insurance recommendation is regulated; TOMO orchestrates source-
         blind TTBS only.

RULE 15: information_completeness_score (hidden ranking factor, weight 0.10)
         rewards full §5 shape. Sparse responses rank lower.

RULE 16: addons_premium_inr must match insurer-published addon rate cards.
         Padding addon prices to inflate commission = suspension.

RULE 17: For EVs, kw_rating-banded TP floor applies (IRDAI EV tariff).
         Quoting petrol-TP-floor for EVs = customer-harm + suspension.

VERSION HISTORY

v1.0.0 — 2026-05-13 — Initial spec. Finance-domain new-policy entry point;
                       sibling to auto.book_insurance_renewal. Long-term TP
                       bundle (3yr 4W / 5yr 2W) enforced per Supreme Court
                       ruling. EV kw / battery fields mandatory for electric
                       vehicles. NET commission base in §8.