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.0auto.book_battery_replacement

Intent Spec — auto.book_battery_replacement

FULL ID:       auto.book_battery_replacement
VERSION:       v1.0.0
STATUS:        draft
LAST UPDATED:  2026-05-11
DOMAIN:        auto
PRIMARY AGENT: AutoServicesAgent
TTBS WEIGHTS:  time=0.30 taste=0.15 budget=0.25 safety=0.30

User books a battery replacement — diagnosis confirmed (or self-declared) and they want a new battery fitted. Covers both planned ("battery is 3 years old, time to swap") and semi-urgent ("battery sometimes fails, want to replace before stranding"). Distinct from breakdown assist where vehicle is already dead at roadside.

Partner exemplars: Battery Bhai, Battery Mantra, BatteryAtHome, Exide Care, Amaron Quanta dealers, GoMechanic Battery, manufacturer authorised workshops.


SECTION 1 — INTENT IDENTITY

This intent fires when a user wants their battery swapped — usually at home or workshop. Distinct from:

  • auto.book_breakdown_assist — vehicle is already non-functional at roadside, emergency
  • auto.book_general_service — full periodic service, battery is one of many checks
  • auto.book_ev_charger_install — home EV charger fitment, not vehicle battery

Single intent fires. If the user actually wants diagnostic first (uncertain battery), partner may decline to ship without diagnosis OR include diagnosis_first in the service scope.


SECTION 2 — NATURAL LANGUAGE COVERAGE

CLASSIFIES IN

  • "Replace my car battery"
  • "Need a new battery for my Swift"
  • "Old battery, want to swap it"
  • "Battery dying, get me a new one fitted at home"
  • "Exide battery for Honda City"
  • "How much for an Amaron battery doorstep fitment"
  • "Two-wheeler battery replacement"
  • "My bike battery is 4 years old, replace it"
  • "Best battery for diesel SUV with warranty"
  • "Battery at home today"

CLASSIFIES OUT — BORDERLINE NO

  • "My battery is dead right now, I'm stranded" → auto.book_breakdown_assist (with category=battery_dead)
  • "Just check my battery" → ambiguous; if standalone diagnostic → auto.book_general_service (inspection variant)
  • "Install EV charger at home" → auto.book_ev_charger_install
  • "Battery for inverter at home" → not a vehicle intent; not in TOMO scope v1

MULTI-INTENT TRIGGERS

  • "Replace battery and service the car" → auto.book_battery_replacement + auto.book_general_service
  • "New battery and tyre alignment" → auto.book_battery_replacement + auto.book_tyre_alignment

SECTION 3 — INPUT (TOMO → PROVIDER)

{
  "intent": "auto.book_battery_replacement",
  "request_id": "req_01J9Z...",
  "user_locale": "en-IN",
  "user_currency": "INR",
  "user_location": { "lat": 17.4475, "lng": 78.3563, "max_radius_km": 12, "city": "Hyderabad" },
  "vehicle": {
    "type": "car",
    "make": "Maruti Suzuki",
    "model": "Swift",
    "variant": "VXi",
    "fuel_type": "petrol",
    "year_of_manufacture": 2021,
    "registration_number_last4": "1234"
  },
  "battery_preferences": {
    "preferred_brand": "any",                 // STRICT ENUM §6: any | exide | amaron | sf_sonic | tata_green | luminous | livguard
    "min_warranty_months": 36,
    "preferred_amp_hours": null,              // user-declared if known; else null
    "old_battery_buyback": true               // user wants buyback credit on old battery
  },
  "service_preferences": {
    "doorstep_fitment": true,
    "preferred_window": {
      "start": "2026-05-13T10:00:00+05:30",
      "end":   "2026-05-13T20:00:00+05:30"
    }
  },
  "ttbs_user_band": {
    "time":   "balanced",
    "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 auto.book_battery_replacement
vehicle.year_of_manufacture int REQUIRED, 1990-2026 Drives compatible battery catalog
battery_preferences.preferred_brand enum REQUIRED, STRICT ENUM §6 any = all brands acceptable
battery_preferences.min_warranty_months int REQUIRED, 0-60 Filter
battery_preferences.preferred_amp_hours int REQUIRED nullable, 30-200 Vehicle-spec match
battery_preferences.old_battery_buyback bool REQUIRED Buyback credit affects final price
service_preferences.doorstep_fitment bool REQUIRED Filter

Anti-fabrication preamble: Provider may not steer toward higher-commission brands. Compatibility recommendations must be technical, not commercial.


SECTION 4 — PROVIDER TOOLS

Tool 1: search_battery_options

PURPOSE:      Return up to 15 compatible batteries with provider availability
INPUT:        §3
OUTPUT:       array<BatteryOption> per §5
SLA:          p50 ≤ 600ms, p95 ≤ 1800ms, p99 ≤ 3500ms
RATE LIMIT:   60 req/min
IDEMPOTENCY:  request_id; 60s cache
RETRY:        1 on 429, 2 on 5xx

Tool 2: create_battery_booking

PURPOSE:      Confirm battery + slot + buyback amount
INPUT:        { request_id, battery_sku, slot_id, vehicle.*, address?, contact_phone }
OUTPUT:       BatteryBooking per §5
SLA:          p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT:   30 req/min
IDEMPOTENCY:  request_id
RETRY:        No retry on create

Tool 3: cancel_battery_booking

PURPOSE:      Cancel before fitment
INPUT:        { request_id, booking_id, reason_code }
OUTPUT:       CancellationResult per §5
SLA:          p50 ≤ 600ms, p95 ≤ 1800ms
RATE LIMIT:   30 req/min
RETRY:        1 on 5xx

SECTION 5 — RESPONSE SHAPE

BatteryOption

BatteryOption:
  battery_sku: { type: string, constraint: REQUIRED, opaque }
  brand:
    type: enum
    constraint: REQUIRED, STRICT ENUM §6
    values: [exide, amaron, sf_sonic, tata_green, luminous, livguard, oem_default]
  model_name: { type: string, constraint: REQUIRED, e.g. "Exide Mileage MGN70" }
  amp_hours: { type: int, constraint: REQUIRED, 30-200 }
  cca_rating: { type: int, constraint: REQUIRED, 200-1200, semantics: "Cold Cranking Amps" }
  battery_type:
    type: enum
    constraint: REQUIRED, STRICT ENUM §6
    values: [lead_acid_flooded, lead_acid_smf, agm, efb, lithium_ion]
  compatibility_verified: { type: boolean, constraint: REQUIRED, semantics: "TRUE only if make/model/year confirmed by partner catalog" }

  warranty:
    pro_rata_months: { type: int, constraint: REQUIRED, 0-60 }
    full_replacement_months: { type: int, constraint: REQUIRED, 0-36 }
    warranty_card_provided: { type: boolean, constraint: REQUIRED }
    warranty_terms_url: { type: string, constraint: REQUIRED, HTTPS URL }

  provider:
    provider_id: { type: string, constraint: REQUIRED }
    name: { type: string, constraint: REQUIRED }
    provider_type:
      type: enum
      constraint: REQUIRED, STRICT ENUM §6
      values: [oem_authorised, brand_authorised, multi_brand_garage, doorstep_mobile, online_retailer]
    address: { type: string, constraint: REQUIRED }
    location: { type: object, shape: { lat, lng }, constraint: REQUIRED }
    distance_from_user_km: { type: float, constraint: REQUIRED, 0-30 }

  pricing:
    base_battery_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    fitment_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    doorstep_surcharge_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    gst_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
    old_battery_buyback_credit_inr:
      type: int
      constraint: REQUIRED, INR_INTEGER, ≥0
      semantics: when user opts for buyback, partner credits this amount
    total_after_buyback_inr: { type: int, constraint: REQUIRED, INR_INTEGER }

  fitment:
    slot_window:
      start: { type: string, constraint: REQUIRED, ISO_DATETIME }
      end: { type: string, constraint: REQUIRED, ISO_DATETIME }
    typical_fitment_minutes: { type: int, constraint: REQUIRED, 10-60 }
    crew_id_verifiable: { type: boolean, constraint: REQUIRED }

  ratings:
    avg_rating: { type: float, constraint: REQUIRED, 0-5 }
    review_count: { type: int, constraint: REQUIRED, ≥0 }
    warranty_claim_resolution_pct: { type: int, constraint: REQUIRED, 0-100 }

  partner_reference:
    source: { type: string, constraint: REQUIRED }
    deeplink: { type: string, constraint: REQUIRED, HTTPS URL }

BatteryBooking

BatteryBooking:
  booking_id: { type: string, constraint: REQUIRED, immutable }
  battery_sku: { type: string, constraint: REQUIRED }
  brand: { type: enum, constraint: REQUIRED }
  fitment_window:
    start: { type: string, constraint: REQUIRED, ISO_DATETIME }
    end: { type: string, constraint: REQUIRED, ISO_DATETIME }
  crew:
    crew_id: { type: string, constraint: REQUIRED nullable, required for doorstep_mobile }
    crew_name: { type: string, constraint: REQUIRED nullable, required for doorstep_mobile }
    crew_phone: { type: string, constraint: REQUIRED nullable, E.164 }
  warranty_certificate_url: { type: string, constraint: REQUIRED, HTTPS URL, signed token }
  payment_due_at:
    type: enum
    constraint: REQUIRED, STRICT ENUM §6
    values: [now, on_fitment, on_completion]
  partner_booking_reference: { type: string, constraint: REQUIRED }

CancellationResult

CancellationResult:
  booking_id: { type: string, constraint: REQUIRED }
  cancelled_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
  cancellation_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
  refund_amount_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
  refund_eta_days: { type: int, constraint: REQUIRED, 0-14 }

FORBIDDEN FIELDS

  • paid_placement_score, ad_bid, sponsored_rank, promotion_priority
  • kickback_amount, referral_fee_kickback, _partner_revenue_share
  • artificial_urgency_text
  • ai_generated_photo for battery / crew imagery
  • commission_padded_price
  • brand_inflated_warranty (any field claiming warranty beyond manufacturer's published warranty)

SECTION 6 — CONTROLLED VOCABULARIES

battery_preferences.preferred_brand:
  values:
    any:         "User open to any brand"
    exide:       "Exide Industries"
    amaron:      "Amara Raja Batteries (Amaron)"
    sf_sonic:    "SF Sonic"
    tata_green:  "Tata Green"
    luminous:    "Luminous Power"
    livguard:    "Livguard"

battery_type:
  values:
    lead_acid_flooded: "Conventional flooded lead-acid"
    lead_acid_smf:     "Sealed Maintenance-Free lead-acid"
    agm:               "Absorbent Glass Mat"
    efb:               "Enhanced Flooded Battery"
    lithium_ion:       "Li-ion (limited two-wheeler / EV applications)"

provider_type:
  values:
    oem_authorised:    "Vehicle OEM's authorised workshop"
    brand_authorised:  "Battery brand's authorised dealer"
    multi_brand_garage: "Independent multi-brand"
    doorstep_mobile:   "Mobile fitment at user location"
    online_retailer:   "Online seller with logistics partner fitment"

payment_due_at:
  values:
    now:          "Pay at booking confirmation"
    on_fitment:   "Pay when crew arrives / before work"
    on_completion: "Pay after fitment done"

Vocabulary changes require v1.x bump.


SECTION 7 — TTBS DIMENSIONS

TIME (weight = 0.30):
  signals_used:
    - provider.distance_from_user_km
    - fitment.slot_window.start vs user's window center
    - fitment.typical_fitment_minutes
  weighting:
    distance: 0.35
    slot_fit: 0.40
    fitment_speed: 0.25
  user_band_handling:
    fast: prefer next-available + shortest fitment time
    balanced: standard
    flexible: any in window

TASTE (weight = 0.15):
  signals_used:
    - brand match vs user DNA history (or explicit preferred_brand)
    - provider_type (some users prefer brand_authorised; some price-conscious go multi_brand_garage)
    - battery_type vs vehicle compatibility expectation
  weighting:
    brand: 0.50
    provider_type: 0.30
    battery_type: 0.20
  user_band_handling: standard

BUDGET (weight = 0.25):
  signals_used:
    - pricing.total_after_buyback_inr
    - pricing.old_battery_buyback_credit_inr (higher = better)
  weighting:
    total: 0.70
    buyback_credit: 0.30
  user_band_handling:
    ok: prefer cheapest meeting min_warranty_months
    good: balance price vs warranty
    great: prefer premium brand (Exide / Amaron) + long warranty

SAFETY (weight = 0.30):
  signals_used:
    - warranty.full_replacement_months
    - warranty.warranty_card_provided
    - compatibility_verified
    - ratings.warranty_claim_resolution_pct
  weighting:
    warranty_length: 0.30
    warranty_card: 0.20
    compatibility: 0.20
    claim_resolution: 0.30
  user_band_handling:
    fast: relax warranty length floor
    balanced: standard
    flexible: prefer longest-warranty / best-claim-resolution

SECTION 8 — COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body:
{
  "intent":           "auto.book_battery_replacement",
  "external_id":      "<booking_id>",
  "request_id":       "<request_id>",
  "amount_inr":       4200,   // NET (battery margin + fitment fee + doorstep surcharge, supplier-kept)
  "gst_inr":          756,    // government
  "tips_inr":         0,
  "pass_through_inr": 0,
  "closed_at":        "2026-05-13T14:30:00+05:30",
  "status":           "completed",
  "brand":            "exide",
  "battery_sku":      "exide_MGN70",
  "buyback_credited_inr": 350,
  "warranty_card_issued": true
}

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


SECTION 9 — WIDGET

BatteryOptionsWidget (planned). Interim: generic ListingsWidget.

Field mapping:
  - BatteryOption.brand + model_name → header
  - BatteryOption.amp_hours + cca_rating + battery_type → tech spec subline
  - BatteryOption.warranty.full_replacement_months + pro_rata_months → "Warranty: Xm + Ym pro-rata" pill
  - BatteryOption.pricing.total_after_buyback_inr → price (with strikethrough on pre-buyback when buyback > 0)
  - BatteryOption.provider.provider_type + distance_from_user_km → provider subline
  - BatteryOption.compatibility_verified=true → green "Verified compatible with your Swift 2021" badge

SECTION 10 — CACHING POLICY

Call TTL Rationale
search_battery_options 60s Battery stock fairly stable
create_battery_booking NO CACHE Idempotent by request_id
cancel_battery_booking NO CACHE
Battery catalog metadata (compatibility, specs, MRP) 6h Static

SECTION 11 — ERROR CODES

Code HTTP Meaning Retry
INVALID_REQUEST 400 Payload malformed No
INVALID_AUTH 401 Bad creds No
RATE_LIMITED 429 Throttle 1, 2s
INTERNAL_ERROR 500 Partner failure 2, exp
IDEMPOTENCY_VIOLATION 409 request_id reused No
SIGNATURE_INVALID 401 (webhook) HMAC fail No
NO_COMPATIBLE_BATTERY 200 (empty) Valid response, no SKUs match vehicle n/a
OUT_OF_STOCK 409 (create) SKU available at search, gone at create No; UI surfaces
SLOT_GONE 409 (create) Fitment slot taken No
INCOMPATIBLE_VEHICLE 422 Vehicle make/model/year not in partner catalog No
DOORSTEP_UNAVAILABLE_AT_LOCATION 422 User location outside doorstep area No
OLD_BATTERY_NOT_ACCEPTED 422 (create) Buyback declined (e.g. battery too damaged); partner returns true total_inr without credit No; UI re-confirms

SECTION 12 — SANDBOX → PRODUCTION CHECKLIST

[ ] All three tools implemented; shapes per §5
[ ] At least 3 brands + 10 SKUs available in test catalog
[ ] compatibility_verified flag correctly TRUE only when partner catalog confirms vehicle match
[ ] All warranty terms_url return live HTTPS pages
[ ] HMAC signing verified
[ ] amount_inr is NET in CPC payload
[ ] buyback_credited_inr correctly populated when buyback occurred (not zero by default)
[ ] No forbidden fields in any responses
[ ] SLA p95 met: search ≤1800ms, create ≤4000ms
[ ] Idempotency tested
[ ] Doorstep fitment: crew_id + crew_phone returned in BatteryBooking
[ ] Warranty certificate URL returns valid certificate document on test booking
[ ] Compliance docs: GSTIN, MSME registration (if claimed), privacy policy URL live
[ ] Battery brand authorisation document on file (TOMO requires)

SECTION 13 — ANTI-FABRICATION RULES

RULE 1: No paid_placement / ad / kickback fields. Rejects entire response.
        Partners may not return higher-margin brands first irrespective of
        vehicle compatibility or user preference.

RULE 2: compatibility_verified=true MUST mean partner's catalog explicitly
        confirms this SKU fits the user's make/model/year. Sustained
        mis-fitments (verified via crew callouts) are suspension triggers.

RULE 3: warranty.full_replacement_months must match the battery manufacturer's
        published warranty for that SKU. Inflating warranty to win rank is
        explicitly forbidden. TOMO cross-checks with manufacturer warranty
        registries on sample SKUs.

RULE 4: old_battery_buyback_credit_inr must be honoured when partner accepts
        the old battery. Reneging on buyback at fitment time is suspension
        after 2 incidents (verified via CPC buyback_credited_inr vs slot
        old_battery_buyback_credit_inr).

RULE 5: ratings.warranty_claim_resolution_pct must reflect real claims
        processed in past 12 months. TOMO field-tests by initiating a
        synthetic claim on a sandbox-tagged booking and measuring response.

RULE 6: provider_type=brand_authorised requires uploaded authorisation
        document during compliance review (signed agreement with the
        battery brand for that geography).

RULE 7: No fast_selling / urgency text. Battery purchase is rarely time-
        critical (truly urgent cases use breakdown_assist intent).

RULE 8: AI-generated battery / crew photos forbidden. Real product imagery
        from manufacturer catalogs required.

RULE 9: warranty_card_provided=true requires partner to issue a real warranty
        card (physical or signed PDF). TOMO spot-checks via user post-fitment
        questionnaire.

RULE 10: No "Top Pick" / "TOMO Recommended" badges. TTBS ranks source-blind.

VERSION HISTORY

v1.0.0 — 2026-05-11 — Initial spec. NET commission base in §8.