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, emergencyauto.book_general_service— full periodic service, battery is one of many checksauto.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_prioritykickback_amount,referral_fee_kickback,_partner_revenue_shareartificial_urgency_textai_generated_photofor battery / crew imagerycommission_padded_pricebrand_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.