evBattery
The evBattery noun — identity, lifecycle, events, and every capability as an anchored section: 25 capabilities, 0 live, 25 sandbox, 0 declared.
evBattery is one of the estate's 317 automotive nouns — a job a car needs done. It carries 25 capabilities: 0 live, 25 sandbox, 0 declared · doors aggregator.vin.
Identity
| Noun | evBattery |
| Pillar | Services (facets: 9 data · 10 services · 6 commerce) |
| Capabilities | 25 — 0 live · 25 sandbox · 0 declared |
| Entities | RepairOrder |
| Doors | aggregator.vin |
| SDK | Vin.evBattery.* from apis.vin |
| Address | /catalog/evBattery#{action} — the anchor IS the wire name minus evBattery. |
Events
The vocabulary this noun can append to the record — 45 past-tense, versioned event types, each linked to the capability that emits it:
EvBattery.balanceFailed@1— emitted bybalanceEvBattery.balanceRequested@1— emitted bybalanceEvBattery.balanced@1— emitted bybalanceEvBattery.boughtBack@1— emitted bybuybackEvBattery.buybackRequested@1— emitted bybuybackEvBattery.buybacked@1— emitted bybuybackEvBattery.cellBalanced@1— emitted bycellBalanceEvBattery.charged@1— emitted bypayEvBattery.completed@1— emitted byorderEvBattery.coolantServiced@1— emitted bycoolantServiceEvBattery.coreChargeRequested@1— emitted bycoreChargeEvBattery.coreCharged@1— emitted bycoreChargeEvBattery.diagnoseRequested@1— emitted bydiagnoseEvBattery.diagnosed@1— emitted bydiagnoseEvBattery.dispatched@1— emitted byorderEvBattery.moduleReplaceFailed@1— emitted bymoduleReplaceEvBattery.moduleReplaceRequested@1— emitted bymoduleReplaceEvBattery.moduleReplaced@1— emitted bymoduleReplaceEvBattery.ordered@1— emitted byorderEvBattery.paid@1— emitted bypayEvBattery.payFailed@1— emitted bypayEvBattery.payRequested@1— emitted bypayEvBattery.quoteRequested@1— emitted byquoteEvBattery.quoted@1— emitted byquoteEvBattery.rangeEstimated@1— emitted byrangeEstimateEvBattery.reconditionFailed@1— emitted byreconditionEvBattery.reconditionRequested@1— emitted byreconditionEvBattery.reconditioned@1— emitted byreconditionEvBattery.recycleFailed@1— emitted byrecycleEvBattery.recycleRequested@1— emitted byrecycleEvBattery.recycled@1— emitted byrecycleEvBattery.replaceFailed@1— emitted byreplaceEvBattery.replaceRequested@1— emitted byreplaceEvBattery.replaced@1— emitted byreplaceEvBattery.repurposed@1— emitted bysecondLifeEvBattery.secondLifeRequested@1— emitted bysecondLifeEvBattery.sohRead@1— emitted bysohEvBattery.thermalServiced@1— emitted bythermalServiceEvBattery.warrantyClaimFailed@1— emitted bywarrantyClaimEvBattery.warrantyClaimFiled@1— emitted bywarrantyClaimEvBattery.warrantyClaimRequested@1— emitted bywarrantyClaimOrder.placed@1— emitted byorderServiceOrder.settled@1— emitted byorder·payWarrantyClaim.approved@1— emitted bywarrantyClaimWarrantyClaim.reimbursed@1— emitted bywarrantyClaim
Discover & read
spec
evBattery.spec · GET /ev-batteries/spec · gate none · sandbox · answers EvBatterySpec@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.spec({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/spec?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatterySpec@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"component": "traction battery",
"chemistry": "NMC 811",
"packKwh": 82,
"modules": 12,
"nominalVoltage": 355,
"coolant": "liquid-glycol"
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"component": "traction battery",
"chemistry": "NMC 811",
"packKwh": 82,
"modules": 12,
"nominalVoltage": 355,
"coolant": "liquid-glycol"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}history
evBattery.history · GET /ev-batteries/history · gate none · sandbox · answers EvBatteryHistory@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.history({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/history?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryHistory@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"events": [
{
"date": "2024-03-14",
"kind": "maintenance",
"description": "scheduled traction battery service"
}
]
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"events": [
{
"date": "2024-03-14",
"kind": "maintenance",
"description": "scheduled traction battery service"
}
]
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}chemistryLookup
evBattery.chemistryLookup · GET /ev-batteries/chemistry-lookup · gate none · sandbox · answers EvBatteryChemistryLookup@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.chemistryLookup({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/chemistry-lookup?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryChemistryLookup@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"component": "traction battery",
"chemistry": "NMC 811",
"packKwh": 82,
"modules": 12,
"nominalVoltage": 355,
"coolant": "liquid-glycol"
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"component": "traction battery",
"chemistry": "NMC 811",
"packKwh": 82,
"modules": 12,
"nominalVoltage": 355,
"coolant": "liquid-glycol"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}sohRead
evBattery.sohRead · GET /ev-batteries/soh-read · gate none · sandbox · answers EvBatterySohRead@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.sohRead({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/soh-read?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatterySohRead@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"withinSpec": true
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"withinSpec": true
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}dcFastDamageCheck
evBattery.dcFastDamageCheck · GET /ev-batteries/dc-fast-damage-check · gate none · sandbox · answers EvBatteryDcFastDamageCheck@1
No input — this capability takes no request body.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.dcFastDamageCheck()curl 'https://apis.vin/ev-batteries/dc-fast-damage-check'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryDcFastDamageCheck@1",
"value": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"damage": "none"
},
"evidence": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"damage": "none"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Quote & price
quote
evBattery.quote · POST /ev-batteries/quote · gate offer · sandbox · answers EvBatteryQuote@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.quoteRequested@1 · EvBattery.quoted@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.quote({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/quote \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryQuote@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"band": "pass",
"estimateId": "EST-64be9fad",
"laborCents": 120000,
"partsCents": 360000,
"subtotalCents": 480000,
"partSource": "aftermarket",
"currency": "USD"
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"band": "pass",
"estimateId": "EST-64be9fad",
"laborCents": 120000,
"partsCents": 360000,
"subtotalCents": 480000,
"partSource": "aftermarket",
"currency": "USD"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}rangeEstimate
evBattery.rangeEstimate · GET /ev-batteries/range-estimate · gate key · sandbox · answers EvBatteryRangeEstimate@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.rangeEstimated@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.rangeEstimate({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/range-estimate?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryRangeEstimate@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"rangeMiles": 237
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"rangeMiles": 237
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Apply & book
order
evBattery.order · POST /ev-batteries/order · gate offer · sandbox · answers EvBatteryOrder@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.completed@1 · EvBattery.dispatched@1 · EvBattery.ordered@1 · Order.placed@1 · ServiceOrder.settled@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.order({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/order \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryOrder@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"order": {
"id": "ORD-8a6c3e6d",
"item": "traction battery",
"status": "placed",
"amountCents": 480000,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"order": {
"id": "ORD-8a6c3e6d",
"item": "traction battery",
"status": "placed",
"amountCents": 480000,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Pay & settle
pay
evBattery.pay · POST /ev-batteries/pay · gate offer · sandbox · answers EvBatteryPay@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.charged@1 · EvBattery.paid@1 · EvBattery.payFailed@1 · EvBattery.payRequested@1 · ServiceOrder.settled@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.pay({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/pay \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryPay@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"payment": {
"id": "PAY-cb1e8efb",
"status": "settled",
"amountCents": 120000,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"payment": {
"id": "PAY-cb1e8efb",
"status": "settled",
"amountCents": 120000,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}coreCharge
evBattery.coreCharge · POST /ev-batteries/core-charge · gate offer · sandbox · answers EvBatteryCoreCharge@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.coreChargeRequested@1 · EvBattery.coreCharged@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.coreCharge({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/core-charge \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryCoreCharge@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"fee": {
"kind": "core-deposit",
"amountCents": 45000,
"currency": "USD",
"status": "charged"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"fee": {
"kind": "core-deposit",
"amountCents": 45000,
"currency": "USD",
"status": "charged"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Fulfill & operate
replace
evBattery.replace · POST /ev-batteries/replace · gate offer · sandbox · answers EvBatteryReplace@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.replaceFailed@1 · EvBattery.replaceRequested@1 · EvBattery.replaced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.replace({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/replace \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryReplace@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-4e56bea5",
"operation": "replace",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-4e56bea5",
"operation": "replace",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}diagnose
evBattery.diagnose · POST /ev-batteries/diagnose · gate offer · sandbox · answers EvBatteryDiagnose@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.diagnoseRequested@1 · EvBattery.diagnosed@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.diagnose({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/diagnose \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryDiagnose@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"faults": [],
"faultCount": 0
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"faults": [],
"faultCount": 0
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}moduleReplace
evBattery.moduleReplace · POST /ev-batteries/module-replace · gate offer · sandbox · answers EvBatteryModuleReplace@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.moduleReplaceFailed@1 · EvBattery.moduleReplaceRequested@1 · EvBattery.moduleReplaced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.moduleReplace({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/module-replace \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryModuleReplace@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-608149e1",
"operation": "moduleReplace",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-608149e1",
"operation": "moduleReplace",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Authorize & resolve
warrantyClaim
evBattery.warrantyClaim · POST /ev-batteries/warranty-claim · gate offer · sandbox · answers EvBatteryWarrantyClaim@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.warrantyClaimFailed@1 · EvBattery.warrantyClaimFiled@1 · EvBattery.warrantyClaimRequested@1 · WarrantyClaim.approved@1 · WarrantyClaim.reimbursed@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.warrantyClaim({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/warranty-claim \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryWarrantyClaim@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"warranty": "expired",
"claim": {
"id": "WC-a56c59e5",
"decision": "denied",
"reason": "coverage-expired"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"warranty": "expired",
"claim": {
"id": "WC-a56c59e5",
"decision": "denied",
"reason": "coverage-expired"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}warrantyCheck
evBattery.warrantyCheck · GET /ev-batteries/warranty-check · gate none · sandbox · answers EvBatteryWarrantyCheck@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.warrantyCheck({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/warranty-check?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryWarrantyCheck@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"warranty": "expired",
"void": false,
"coverageMilesLeft": 0
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"warranty": "expired",
"void": false,
"coverageMilesLeft": 0
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}More actions
balance
evBattery.balance · POST /ev-batteries/balance · gate offer · sandbox · answers EvBatteryBalance@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.balanceFailed@1 · EvBattery.balanceRequested@1 · EvBattery.balanced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.balance({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/balance \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryBalance@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-8a8cb799",
"operation": "balance",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-8a8cb799",
"operation": "balance",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}buyback
evBattery.buyback · POST /ev-batteries/buyback · gate offer · sandbox · answers EvBatteryBuyback@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.boughtBack@1 · EvBattery.buybackRequested@1 · EvBattery.buybacked@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.buyback({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/buyback \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryBuyback@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"grade": "grade-a",
"offer": {
"id": "BB-152346f6",
"amountCents": 384000,
"currency": "USD",
"status": "extended"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"grade": "grade-a",
"offer": {
"id": "BB-152346f6",
"amountCents": 384000,
"currency": "USD",
"status": "extended"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}cellBalance
evBattery.cellBalance · POST /ev-batteries/cell-balance · gate offer · sandbox · answers EvBatteryCellBalance@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.cellBalanced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.cellBalance({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/cell-balance \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryCellBalance@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"imbalanceMv": 12
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"imbalanceMv": 12
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}coolantService
evBattery.coolantService · POST /ev-batteries/coolant-service · gate key · sandbox · answers EvBatteryCoolantService@1
No input — this capability takes no request body.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.coolantServiced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.coolantService()curl -X POST https://apis.vin/ev-batteries/coolant-service \
-H 'content-type: application/json' \
-d '{}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryCoolantService@1",
"value": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-d304a9a7",
"operation": "coolantService",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-d304a9a7",
"operation": "coolantService",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}degradationForecast
evBattery.degradationForecast · GET /ev-batteries/degradation-forecast · gate none · sandbox · answers EvBatteryDegradationForecast@1
No input — this capability takes no request body.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.degradationForecast()curl 'https://apis.vin/ev-batteries/degradation-forecast'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryDegradationForecast@1",
"value": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"remainingLifePct": 59,
"failureRiskPct": 5,
"horizonMiles": 12000
},
"evidence": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"remainingLifePct": 59,
"failureRiskPct": 5,
"horizonMiles": 12000
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}recondition
evBattery.recondition · POST /ev-batteries/recondition · gate offer · sandbox · answers EvBatteryRecondition@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.reconditionFailed@1 · EvBattery.reconditionRequested@1 · EvBattery.reconditioned@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.recondition({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/recondition \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryRecondition@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-51cf502f",
"operation": "recondition",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-51cf502f",
"operation": "recondition",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}recycle
evBattery.recycle · POST /ev-batteries/recycle · gate offer · sandbox · answers EvBatteryRecycle@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.recycleFailed@1 · EvBattery.recycleRequested@1 · EvBattery.recycled@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.recycle({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/recycle \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryRecycle@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"route": "reuse-evaluation"
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"route": "reuse-evaluation"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}secondLife
evBattery.secondLife · POST /ev-batteries/second-life · gate offer · sandbox · answers EvBatterySecondLife@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
The gate is a 402 OFFER — the price and a hard ceiling on the wire, with a durable intent that executes on settlement. Never a wall, never "contact sales". Price: not posted — see /pricing.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.repurposed@1 · EvBattery.secondLifeRequested@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.secondLife({"vin":"5FNRL6H81PB048923"})curl -X POST https://apis.vin/ev-batteries/second-life \
-H 'content-type: application/json' \
-d '{"vin":"5FNRL6H81PB048923"}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatterySecondLife@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"route": "second-life-storage"
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"route": "second-life-storage"
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}soh
evBattery.soh · GET /ev-batteries/soh · gate key · sandbox · answers EvBatterySoh@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.sohRead@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.soh({"vin":"5FNRL6H81PB048923"})curl 'https://apis.vin/ev-batteries/soh?vin=5FNRL6H81PB048923'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatterySoh@1",
"value": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"withinSpec": true
},
"evidence": {
"vin": "5FNRL6H81PB048923",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"sohPct": 91,
"withinSpec": true
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}thermalService
evBattery.thermalService · POST /ev-batteries/thermal-service · gate key · sandbox · answers EvBatteryThermalService@1
No input — this capability takes no request body.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /5FNRL6H81PB048923 (the VIN lens).
Try it — sandbox: every call answers a deterministic, provenance-labeled simulated payload ({ environment, simulated } in the body). Force any documented outcome with the magic triggers. Going live is a connect, never a ballot: submit the credential at integrates.vin (dealer systems) or connects.vin (consumer accounts) — submissions enter the activation queue and rank live rollout.
Emits — EvBattery.thermalServiced@1.
import { evBattery } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await evBattery.thermalService()curl -X POST https://apis.vin/ev-batteries/thermal-service \
-H 'content-type: application/json' \
-d '{}'Receipt — the sandbox wire answered the request above with this exact body at build time. Captured by the receipts runner (timestamped, provenance in the payload), never authored; it re-executes only when this descriptor changes.
{
"type": "OK",
"answers": "EvBatteryThermalService@1",
"value": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-0d3c7d8c",
"operation": "thermalService",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"evidence": {
"vin": "1HGCM82633A004352",
"system": "evBattery",
"asOf": "2026-08-10",
"verdict": "pass",
"workOrder": {
"id": "WO-0d3c7d8c",
"operation": "thermalService",
"status": "scheduled",
"costCents": 120000,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "aftersales-data-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Data model
The record shape behind this noun — one entity, each property an evidence field. See the whole estate model on the data model page.
RepairOrder
Modeled
The noun drawn out — its record shape, its lifecycle, and how it is exercised end to end. 2 diagrams, rendered from the estate model.
EvBattery · Class model
EvBattery · State machine
Generated from the catalog. Every capability, answer, gate, and entity on this page is a rendered descriptor — it cannot drift from the wire.