estimate
The estimate noun — identity, lifecycle, events, and every capability as an anchored section: 17 capabilities, 0 live, 17 sandbox, 0 declared.
estimate is one of the estate's 317 automotive nouns — a job a car needs done. It carries 17 capabilities: 0 live, 17 sandbox, 0 declared · doors aggregator.vin.
Identity
| Noun | estimate |
| Pillar | Data (facets: 6 data · 6 services · 5 commerce) |
| Capabilities | 17 — 0 live · 17 sandbox · 0 declared |
| Entities | Estimate |
| Doors | aggregator.vin |
| SDK | Vin.estimate.* from apis.vin |
| Address | /catalog/estimate#{action} — the anchor IS the wire name minus estimate. |
Lifecycle
Estimate — EstimateFSM: 5 states, 6 transitions — Built · Approved · PartiallyApproved · Declined · Supplemented. Each transition is a past-tense event on the record.
Events
The vocabulary this noun can append to the record — 22 past-tense, versioned event types, each linked to the capability that emits it:
Estimate.approveRequested@1— emitted byapproveEstimate.approved@1— emitted byapproveEstimate.buildRequested@1— emitted bybuildEstimate.built@1— emitted bybuildEstimate.convertToRoRequested@1— emitted byconvertToRoEstimate.declineRequested@1— emitted bydeclineEstimate.declined@1— emitted bydeclineEstimate.depositRequested@1— emitted bydepositEstimate.deposited@1— emitted bydepositEstimate.expireRequested@1— emitted byexpireEstimate.expired@1— emitted byexpireEstimate.partialApproveRequested@1— emitted bypartialApproveEstimate.partiallyApproved@1— emitted bypartialApproveEstimate.reviseRequested@1— emitted byreviseEstimate.revised@1— emitted byreviseEstimate.roConverted@1— emitted byconvertToRoEstimate.sendRequested@1— emitted bysendEstimate.sent@1— emitted bysendEstimate.supplementRequested@1— emitted bysupplementEstimate.supplemented@1— emitted bysupplementEstimate.taxCalculated@1— emitted bytaxCalcEstimate.teardownAuthorized@1— emitted byteardownAuthorize
Discover & read
read
estimate.read · GET /estimates/read · gate none · sandbox · answers EstimateRead@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.read({"vin":"1C6RR7NT6GS251541"})curl 'https://apis.vin/estimates/read?vin=1C6RR7NT6GS251541'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": "EstimateRead@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"estimate": {
"id": "EST-3ffb9920",
"stance": "Supplemented",
"totalCents": 317999,
"currency": "USD"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"estimate": {
"id": "EST-3ffb9920",
"stance": "Supplemented",
"totalCents": 317999,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}history
estimate.history · GET /estimates/history · gate none · sandbox · answers EstimateHistory@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.history({"vin":"1C6RR7NT6GS251541"})curl 'https://apis.vin/estimates/history?vin=1C6RR7NT6GS251541'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": "EstimateHistory@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"events": [
{
"date": "2026-08-01",
"kind": "estimate-built",
"id": "EST-3ffb9920"
},
{
"date": "2026-08-06",
"kind": "estimate-supplemented",
"id": "EST-3ffb9920"
}
]
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"events": [
{
"date": "2026-08-01",
"kind": "estimate-built",
"id": "EST-3ffb9920"
},
{
"date": "2026-08-06",
"kind": "estimate-supplemented",
"id": "EST-3ffb9920"
}
]
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}compare
estimate.compare · GET /estimates/compare · gate none · sandbox · answers EstimateCompare@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.compare({"vin":"1C6RR7NT6GS251541"})curl 'https://apis.vin/estimates/compare?vin=1C6RR7NT6GS251541'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": "EstimateCompare@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"comparison": {
"id": "EST-3ffb9920",
"estimateCents": 317999,
"marketMedianCents": 302099,
"currency": "USD",
"stance": "Supplemented"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"comparison": {
"id": "EST-3ffb9920",
"estimateCents": 317999,
"marketMedianCents": 302099,
"currency": "USD",
"stance": "Supplemented"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}laborLookup
estimate.laborLookup · GET /estimates/labor-lookup · gate none · sandbox · answers EstimateLaborLookup@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
system | string | no | one of brakes, engine, suspension, collision, electrical; Repair system whose labor operations to list (LaborTimeGuide.lookupOperations). |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.laborLookup({"vin":"1C6RR7NT6GS251541","system":"brakes"})curl 'https://apis.vin/estimates/labor-lookup?vin=1C6RR7NT6GS251541&system=brakes'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": "EstimateLaborLookup@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"system": "brakes",
"operations": [
{
"operationId": "MOT-BRK-0100",
"system": "brakes",
"description": "Front brake pads — replace",
"standardHours": 1.2,
"warrantyHours": 0.9,
"skillLevel": "B",
"combos": [
"MOT-BRK-0110"
]
},
{
"operationId": "MOT-BRK-0110",
"system": "brakes",
"description": "Front brake rotors — replace (with pads)",
"standardHours": 0.7,
"warrantyHours": 0.4,
"skillLevel": "B",
"combos": [
"MOT-BRK-0100"
]
},
{
"operationId": "MOT-BRK-0200",
"system": "brakes",
"description": "Brake system — bleed / flush",
"standardHours": 0.9,
"warrantyHours": 0.6,
"skillLevel": "C",
"combos": []
}
]
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"system": "brakes",
"operations": [
{
"operationId": "MOT-BRK-0100",
"system": "brakes",
"description": "Front brake pads — replace",
"standardHours": 1.2,
"warrantyHours": 0.9,
"skillLevel": "B",
"combos": [
"MOT-BRK-0110"
]
},
{
"operationId": "MOT-BRK-0110",
"system": "brakes",
"description": "Front brake rotors — replace (with pads)",
"standardHours": 0.7,
"warrantyHours": 0.4,
"skillLevel": "B",
"combos": [
"MOT-BRK-0100"
]
},
{
"operationId": "MOT-BRK-0200",
"system": "brakes",
"description": "Brake system — bleed / flush",
"standardHours": 0.9,
"warrantyHours": 0.6,
"skillLevel": "C",
"combos": []
}
]
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "labor-time-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}partsLookup
estimate.partsLookup · GET /estimates/parts-lookup · gate none · sandbox · answers EstimatePartsLookup@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
system | string | no | one of brakes, engine, suspension, collision, electrical; Repair system whose fitting parts to list (PartsCatalog.lookupParts). |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.partsLookup({"vin":"1C6RR7NT6GS251541","system":"brakes"})curl 'https://apis.vin/estimates/parts-lookup?vin=1C6RR7NT6GS251541&system=brakes'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": "EstimatePartsLookup@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"system": "brakes",
"parts": [
{
"partNumber": "OE-BRP-4501",
"description": "Front brake pad set",
"source": "oem",
"system": "brakes",
"listPrice": {
"amount": "12937",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 1
},
{
"partNumber": "OE-ROT-2210",
"description": "Front brake rotor",
"source": "oem",
"system": "brakes",
"listPrice": {
"amount": "9731",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 2
},
{
"partNumber": "AM-BRP-8801",
"description": "Front brake pad set",
"source": "aftermarket",
"system": "brakes",
"listPrice": {
"amount": "6439",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 1
},
{
"partNumber": "AM-ROT-9130",
"description": "Front brake rotor",
"source": "aftermarket",
"system": "brakes",
"listPrice": {
"amount": "5915",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 2
}
]
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"system": "brakes",
"parts": [
{
"partNumber": "OE-BRP-4501",
"description": "Front brake pad set",
"source": "oem",
"system": "brakes",
"listPrice": {
"amount": "12937",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 1
},
{
"partNumber": "OE-ROT-2210",
"description": "Front brake rotor",
"source": "oem",
"system": "brakes",
"listPrice": {
"amount": "9731",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 2
},
{
"partNumber": "AM-BRP-8801",
"description": "Front brake pad set",
"source": "aftermarket",
"system": "brakes",
"listPrice": {
"amount": "6439",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 1
},
{
"partNumber": "AM-ROT-9130",
"description": "Front brake rotor",
"source": "aftermarket",
"system": "brakes",
"listPrice": {
"amount": "5915",
"currency": "USD"
},
"corePrice": {
"amount": "0",
"currency": "USD"
},
"quantityPerJob": 2
}
]
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "parts-catalog-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Quote & price
taxCalc
estimate.taxCalc · GET /estimates/tax-calc · gate key · sandbox · answers EstimateTaxCalc@1
| Field | Type | Required | Notes |
|---|---|---|---|
vin | string | no | — |
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 — Estimate.taxCalculated@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.taxCalc({"vin":"1C6RR7NT6GS251541"})curl 'https://apis.vin/estimates/tax-calc?vin=1C6RR7NT6GS251541'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": "EstimateTaxCalc@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"tax": {
"subtotalCents": 317999,
"taxCents": 26235,
"totalCents": 344234,
"currency": "USD",
"rateBps": 825
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"tax": {
"subtotalCents": 317999,
"taxCents": 26235,
"totalCents": 344234,
"currency": "USD",
"rateBps": 825
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Pay & settle
deposit
estimate.deposit · POST /estimates/deposit · gate offer · sandbox · answers EstimateDeposit@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) · /1C6RR7NT6GS251541 (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 — Estimate.depositRequested@1 · Estimate.deposited@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.deposit({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/deposit \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateDeposit@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"deposit": {
"id": "ED-1b2bc5c4",
"amountCents": 31800,
"currency": "USD",
"status": "held"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"deposit": {
"id": "ED-1b2bc5c4",
"amountCents": 31800,
"currency": "USD",
"status": "held"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Fulfill & operate
build
estimate.build · POST /estimates/build · gate offer · sandbox · answers EstimateBuild@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) · /1C6RR7NT6GS251541 (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 — Estimate.buildRequested@1 · Estimate.built@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.build({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/build \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateBuild@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"build": {
"status": "built",
"id": "EST-3ffb9920",
"stance": "Built",
"totalCents": 317999,
"currency": "USD"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"build": {
"status": "built",
"id": "EST-3ffb9920",
"stance": "Built",
"totalCents": 317999,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}send
estimate.send · POST /estimates/send · gate offer · sandbox · answers EstimateSend@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) · /1C6RR7NT6GS251541 (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 — Estimate.sendRequested@1 · Estimate.sent@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.send({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/send \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateSend@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"delivery": {
"id": "EST-3ffb9920",
"to": "Ava Good",
"channel": "email",
"status": "sent"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"delivery": {
"id": "EST-3ffb9920",
"to": "Ava Good",
"channel": "email",
"status": "sent"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Authorize & resolve
approve
estimate.approve · POST /estimates/approve · gate offer · sandbox · answers EstimateApprove@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) · /1C6RR7NT6GS251541 (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 — Estimate.approveRequested@1 · Estimate.approved@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.approve({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/approve \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateApprove@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"approval": {
"status": "approved",
"id": "EST-3ffb9920",
"approvedCents": 317999,
"currency": "USD"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"approval": {
"status": "approved",
"id": "EST-3ffb9920",
"approvedCents": 317999,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}decline
estimate.decline · POST /estimates/decline · gate offer · sandbox · answers EstimateDecline@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) · /1C6RR7NT6GS251541 (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 — Estimate.declineRequested@1 · Estimate.declined@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.decline({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/decline \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateDecline@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"decline": {
"status": "declined",
"id": "EST-3ffb9920"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"decline": {
"status": "declined",
"id": "EST-3ffb9920"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}teardownAuthorize
estimate.teardownAuthorize · POST /estimates/teardown-authorize · gate key · sandbox · answers EstimateTeardownAuthorize@1
No input — this capability takes no request body.
Door — aggregator.vin serves this noun on its two routes: / (the landing) · /1C6RR7NT6GS251541 (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 — Estimate.teardownAuthorized@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.teardownAuthorize()curl -X POST https://apis.vin/estimates/teardown-authorize \
-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": "EstimateTeardownAuthorize@1",
"value": {
"vin": "1HGCM82633A004352",
"noun": "estimate",
"asOf": "2026-08-10",
"authorization": {
"status": "authorized",
"id": "EST-b4600466",
"authorizedCents": 36897,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"evidence": {
"vin": "1HGCM82633A004352",
"noun": "estimate",
"asOf": "2026-08-10",
"authorization": {
"status": "authorized",
"id": "EST-b4600466",
"authorizedCents": 36897,
"currency": "USD"
},
"payer": {
"name": "Ava Good",
"castRow": "super-prime",
"creditTier": "super-prime"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}partialApprove
estimate.partialApprove · POST /estimates/partial-approve · gate offer · sandbox · answers EstimatePartialApprove@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) · /1C6RR7NT6GS251541 (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 — Estimate.partialApproveRequested@1 · Estimate.partiallyApproved@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.partialApprove({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/partial-approve \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimatePartialApprove@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"approval": {
"status": "partially-approved",
"id": "EST-3ffb9920",
"approvedCents": 190799,
"currency": "USD"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"approval": {
"status": "partially-approved",
"id": "EST-3ffb9920",
"approvedCents": 190799,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}Lifecycle & state
expire
estimate.expire · POST /estimates/expire · gate offer · sandbox · answers EstimateExpire@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) · /1C6RR7NT6GS251541 (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 — Estimate.expireRequested@1 · Estimate.expired@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.expire({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/expire \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateExpire@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"expiry": {
"id": "EST-3ffb9920",
"expires": true,
"expiresOn": "2026-08-24",
"stance": "Supplemented"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"expiry": {
"id": "EST-3ffb9920",
"expires": true,
"expiresOn": "2026-08-24",
"stance": "Supplemented"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}More actions
convertToRo
estimate.convertToRo · POST /estimates/convert-to-ro · gate offer · sandbox · answers EstimateConvertToRo@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) · /1C6RR7NT6GS251541 (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 — Estimate.convertToRoRequested@1 · Estimate.roConverted@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.convertToRo({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/convert-to-ro \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateConvertToRo@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"conversion": {
"status": "not-yet-approved",
"estimateId": "EST-3ffb9920",
"stance": "Supplemented"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"conversion": {
"status": "not-yet-approved",
"estimateId": "EST-3ffb9920",
"stance": "Supplemented"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}revise
estimate.revise · POST /estimates/revise · gate offer · sandbox · answers EstimateRevise@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) · /1C6RR7NT6GS251541 (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 — Estimate.reviseRequested@1 · Estimate.revised@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.revise({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/revise \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateRevise@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"revision": {
"id": "EST-3ffb9920",
"revision": 2,
"totalCents": 343439,
"currency": "USD",
"status": "revised"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"revision": {
"id": "EST-3ffb9920",
"revision": 2,
"totalCents": 343439,
"currency": "USD",
"status": "revised"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-sandbox"
},
"events": [],
"meter": {
"charged": "0.00",
"posted": false
}
}supplement
estimate.supplement · POST /estimates/supplement · gate offer · sandbox · answers EstimateSupplement@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) · /1C6RR7NT6GS251541 (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 — Estimate.supplementRequested@1 · Estimate.supplemented@1.
import { estimate } from 'apis.vin'
// the gate law is in the type system: Answer<T> = Ok | Empty | Blocked | Offer
const answer = await estimate.supplement({"vin":"1C6RR7NT6GS251541"})curl -X POST https://apis.vin/estimates/supplement \
-H 'content-type: application/json' \
-d '{"vin":"1C6RR7NT6GS251541"}'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": "EstimateSupplement@1",
"value": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"supplement": {
"status": "already-supplemented",
"id": "EST-3ffb9920",
"supplementCents": 63600,
"currency": "USD"
}
},
"evidence": {
"vin": "1C6RR7NT6GS251541",
"noun": "estimate",
"asOf": "2026-08-10",
"supplement": {
"status": "already-supplemented",
"id": "EST-3ffb9920",
"supplementCents": 63600,
"currency": "USD"
}
},
"provenance": {
"simulated": true,
"environment": "sandbox",
"source": "paper-commerce-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.
Estimate
Schema
| Property | Type |
|---|---|
id | id |
roId | ref→RepairOrder |
laborOps | LaborOp[] |
partsCost | money |
laborCost | money |
total | money |
status | EstimateFSM |
Relationships
| From | To | Cardinality | As |
|---|---|---|---|
repairOrder | estimate | 1:0..* | estimated by |
Generated from the catalog. Every capability, answer, gate, and entity on this page is a rendered descriptor — it cannot drift from the wire.