docs.vin

Insurance claim end to end

FNOL → estimate → repair order → settlement → subrogation — every step a catalog capability, runnable against the sandbox world.

A claim is a wreck told through money. The loss gets reported (FNOL), an adjuster takes the file, an estimate is written, the body shop opens the repair order, the carrier adjudicates and pays — and if a third party caused the loss, subrogation pursues the payment. Under the journey-ownership ruling (2026-08-17), every door on this walk answers from its shared-world owner: insuranceClaim.open from the insurance-gov wave-2 rail (its ruled carve-out), the eight insuranceClaim.* siblings from the wave-3 rail, and the subrogation.* pair from the claim-desk world registry that reads the ClaimFSM itself. The journey consumes those answers — it never mints a second story.

The cast

This journey rides the curated world — deterministic, replayable, every payload provenance-labeled. One fleet exemplar stands at each position of the ClaimFSM arc, with the CollisionFSM repair arc riding alongside. The full trigger register is at sandbox test triggers.

World keyRole in this journey
1FCRASHH00KED0000The fresh wreck: on the hook, ClaimFSM Opened — the FNOL of record.
1FCRASHEST1MATED0The estimated wreck: AcvDetermined — the written estimate.
1FCRASHBLUEPR1NT0The approved repair: Approved, ruled repairable — the shop blueprints.
1FCRASHRECHECK000The appealed payout: Appealed.
1FCRASHD0NE000000The settled claim: Settled — repair delivered, carrier paid.
1FCLA1MDEN1ED0000The denied claim: Denied — coverage refused.
1FT0TALL0SS000000The confirmed total loss.
1FSUBR0GAT10N0000The subrogation file: Reversed — the claim-desk carries the pursuit.

1 — First notice of loss

capabilityinsuranceClaim.openinsuranceClaim.reportPOST /insurance-claims/report

The journey's opening gate. The rail answers one deterministic claim number per VIN — the SAME CLM- key on every door, wave-2 and wave-3 alike — and the FNOL carries the ONE documented 50,000 deductible up front (the same figure the shop's collision.deductibleCollect collects).

runnable — sandbox · deterministic1FCRASHH00KED0000
run it — POST /insurance-claims/report
curl -X POST 'https://apis.vin/insurance-claims/report' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHH00KED0000"}'
the world answers — InsuranceClaimReport@1
{
  "claimNumber": "CLM-782717A2",
  "vin": "1FCRASHH00KED0000",
  "status": "reported",
  "fnolNumber": "fnol_5f964f8a",
  "lossType": "collision",
  "lossDate": "2026-08-10",
  "reportedAt": "2026-08-10T00:00:00.000Z"
}

2 — Assign the adjuster, set the reserve

capabilityinsuranceClaim.assigninsuranceClaim.reservePOST /insurance-claims/assign

The file routes to the auto-physical-damage queue under a stable adjuster identity — the same CLM-782717A2 file the FNOL opened — and the indemnity reserve posts as the rail's own seeded figure.

runnable — sandbox · deterministic1FCRASHH00KED0000
run it — POST /insurance-claims/assign
curl -X POST 'https://apis.vin/insurance-claims/assign' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHH00KED0000"}'
the world answers — InsuranceClaimAssign@1
{
  "claimNumber": "CLM-782717A2",
  "vin": "1FCRASHH00KED0000",
  "status": "assigned",
  "adjuster": "adj_4c1ba29d",
  "queue": "auto-physical-damage",
  "assignedAt": "2026-08-10T00:00:00.000Z"
}

3 — The estimate

capabilityinsuranceClaim.estimatePOST /insurance-claims/estimate

The rail's estimate is internally whole — parts plus labor is the total, to the cent. It is the CARRIER's figure, not the shop's: the body shop's own collision.estimate answers a different number for the same wreck, and no ACV or total-loss arithmetic rides this door yet (attested below, filed as a model-gap).

runnable — sandbox · deterministic1FCRASHEST1MATED0
run it — POST /insurance-claims/estimate
curl -X POST 'https://apis.vin/insurance-claims/estimate' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHEST1MATED0"}'
the world answers — InsuranceClaimEstimate@1
{
  "claimNumber": "CLM-57663620",
  "vin": "1FCRASHEST1MATED0",
  "status": "estimated",
  "estimate": {
    "parts": { "amount": "134853", "currency": "USD" },
    "labor": { "amount": "59241", "currency": "USD" },
    "total": { "amount": "194094", "currency": "USD" }
  },
  "totalLoss": false,
  "estimatedAt": "2026-08-10T00:00:00.000Z"
}

4 — The repair order

The shop's leg of the journey rides the world-keyed shop arc — the same CollisionFSM machine, no second story. Parts go on order against the approved claim; the repair operations answer their standing against the arc's position (asking repair on a blueprinted wreck never advances the machine).

runnable — sandbox · deterministic1FCRASHBLUEPR1NT0
run it — POST /collisions/order
curl -X POST 'https://apis.vin/collisions/order' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHBLUEPR1NT0"}'
the world answers — CollisionOrder@1
{
  "vin": "1FCRASHBLUEPR1NT0",
  "noun": "collision",
  "asOf": "2026-08-10",
  "position": "Blueprinted",
  "order": {
    "id": "ORD-736971b8",
    "item": "collision parts",
    "status": "placed",
    "amountCents": 100000,
    "currency": "USD"
  },
  "payer": { "name": "Ava Good", "castRow": "super-prime", "creditTier": "super-prime" }
}

5 — Adjudicate and pay

capabilityinsuranceClaim.adjudicateinsuranceClaim.payPOST /insurance-claims/pay

The rail's settlement arithmetic is coherent inside the rail: the payable is the gross loss minus the ONE 50,000 deductible, and the payment IS the adjudicated payable — one figure, two doors, on every exemplar.

runnable — sandbox · deterministic1FCRASHBLUEPR1NT0
run it — POST /insurance-claims/adjudicate
curl -X POST 'https://apis.vin/insurance-claims/adjudicate' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHBLUEPR1NT0"}'
the world answers — InsuranceClaimAdjudicate@1
{
  "claimNumber": "CLM-89AF9FC1",
  "vin": "1FCRASHBLUEPR1NT0",
  "status": "adjudicated",
  "decision": "approved",
  "grossLoss": { "amount": "736755", "currency": "USD" },
  "deductible": { "amount": "50000", "currency": "USD" },
  "payable": { "amount": "686755", "currency": "USD" },
  "adjudicatedAt": "2026-08-10T00:00:00.000Z"
}
runnable — sandbox · deterministic1FCRASHD0NE000000
run it — POST /insurance-claims/pay
curl -X POST 'https://apis.vin/insurance-claims/pay' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FCRASHD0NE000000"}'
the world answers — InsuranceClaimPay@1
{
  "claimNumber": "CLM-163313C9",
  "vin": "1FCRASHD0NE000000",
  "status": "paid",
  "payment": "pay_b76acd0f",
  "amount": { "amount": "214417", "currency": "USD" },
  "method": "ach",
  "payee": "Ada Sandbox",
  "paidAt": "2026-08-10T00:00:00.000Z"
}

6 — Standing, and the subrogation file

The standing read consults the fleet's ClaimFSM position — estimated / AcvDetermined, denied / Denied, appealed / Appealed, reversed / Reversed, paid / Settled — and honors a presented Claim.denied@1 signal. The subrogation file lives on the claim-desk world registry, which adjudicates the SAME machine: a Reversed row carries the pursuit under one SUB- identity across both doors, a merely-settled row answers no-subrogation (the desk never invents a recovery), and the recovery money is honestly not-posted — the desk's own declared no-world-money-law block.

runnable — sandbox · deterministic1FSUBR0GAT10N0000
run it — POST /subrogations/pursue
curl -X POST 'https://apis.vin/subrogations/pursue' \
  -H 'content-type: application/json' \
  -d '{"vin":"1FSUBR0GAT10N0000"}'
the world answers — SubrogationPursue@1
{
  "vin": "1FSUBR0GAT10N0000",
  "noun": "subrogation",
  "asOf": "2026-08-10",
  "id": "CLM-a51602c7",
  "lossType": "collision",
  "status": "Reversed",
  "subrogation": {
    "status": "pursuing",
    "id": "SUB-9eed9eb0",
    "claimId": "CLM-a51602c7",
    "position": "Reversed",
    "recovery": { "status": "not-posted", "basis": "no-world-money-law" }
  }
}

What the record now holds — and what it does not

The walk posts one deterministic story per door: one CLM- key per VIN across the FNOL, assignment, and money doors; a settlement whose payable is the gross minus the ONE deductible and whose payment is exactly that payable; a standing read that consults the ClaimFSM; and a claim-desk subrogation file keyed to the same machine. One cross-cluster parity holds: the rail's 50,000 deductible IS the figure collision.deductibleCollect collects.

Thin ground, attested (each filed as a bd model-gap, per the honest-grade law — the journey suite pins today's bytes as the tripwire): the rails never adjudicate standing — a clean row mints a wreck, a denied or appealed claim still pays, and only the status read honors Claim.denied@1 (vin-4901); the claim money never reconciles across clusters — the rail's estimate is not the shop's own figure, no ACV or total-loss arithmetic is answered, the payment plus deductible is not the shop's claim bill, and the rail's subro_ demand is a second story beside the claim-desk's SUB- file (vin-afd3). The pre-FNOL insuranceClaim.intake stays a seeded rail record, and no ClaimFSM edge is witnessed by the journey's own verbs. Check standing any time with insuranceClaim.status; compose the facts on the record face, GET /{vin}, at the record.

Next