The batch product · Data
Upload the file.
It comes back enriched.
A spreadsheet of VINs is a spreadsheet of unanswered questions. CSV or XLSX, one VIN column: every row returns with the VIN decoded and the licensed record fields appended, each with value, source, and timestamp. Your columns stay yours; the record joins them.
The enriched row at enrich.vin/{VIN}: decode plus the licensed record fields. The file runs the same, row by row.
- vin
- JM3KFBXY1S0597748
- Your remaining rows
- VINJM3KFBXY1S0597748
- Decode2025 Mazda CX-5
- Record fieldsPosts where licensed
- Resolutionresolved
Every appended field posts value · source · timestamp; a field without a bound license posts as a gap. Figures render in the file, not on this page: the per-row fee posts before the tier transacts.
What appends.
The columns people check first, appended first.
Ten thousand VINs in column A and nothing beside them: no trim, no value, no flag. The portfolio gets priced, insured, or floored on rows nobody resolved. Enrichment closes that in one pass: the file you sent, plus the record.
- decodeYear · make · model · trim · style · drivetrain, resolved per row. Always appends: the structure reads free.
- specsThe trim’s factory numbers, where the catalog licenses them.specs.vinreads singly, free
- valuesThe posted market numbers with their basis, where licensed.values.vinone row’s numbers, with their basis
- listingsThe live-listing state: is the row for sale, where licensed.listings.vinthe live-listings spine
- stickerThe birth-record fields: MSRP and factory options as printed, where licensed.sticker.vinthe window sticker, as printed
- flagsRecall status, and title-brand and odometer-consistency flags where licensed. The full history report is the deepening step, priced at its own address, never bundled silently into a row.recalls.vinopen campaigns, freevhr.vinthe full report, the deepening step
- resolutionPer-row state: resolved · INVALID_VIN · no record. Typed, never silently dropped: INVALID_VIN is an answer, not an error page.
Columns render per the catalog’s licensed fields. This page states structure, not coverage.
The free faces lead. The full history report stays a deepening step at its own address: priced there, chosen per row, never the front door here.
The same batch, machine-read.
One capability. Upload, API, or MCP.
The file a person downloads and the rows an agent reads render from the same record. Key, SDK, quota, and MCP are apis.vin’s job: one key, batch or row at a time; one MCP server for the whole platform at apis.vin/mcp.
- The identical column sets by upload, API, and MCP: nothing an agent reads differs from the file.
- Unresolved rows come back typed: INVALID_VIN is an answer, not an error page.
- Before any paid batch moves, the offer is typed and on paper: posted per-row amount, x402 settlement, expiry. An agent enriching a file reads this same page.
- One account, every address: auth.vin.
Posted, or absent.
The structure reads free. The fee is on the page first.
The structure is free to read: the format, the column sets, the per-row states, no account. The paid batch tier posts its per-row fee on this page before it transacts, and not before.
- ReadThe format · the per-row structure · no account$0
- BatchPer row · posted before it transactsNot yet posted
Not yet open · the upstream license must name batch enrichment delivery before a paid file transacts
The batch tier transacts when the gate clears; the format read and the per-row structure stay free meanwhile.
Your rows are your rows: the enrichment appends and returns the file; it does not retain a portfolio.
What appends is what the catalog licenses.
This door runs the batch. The catalog posts the terms.
The catalog
Coverage, license, posted price
Every field a row can carry is cataloged at the pillar door, data.vin: coverage, license, posted price. What the catalog licenses is what appends here; a field without a bound license posts as a gap, never a guess. Coverage is posted there, not promised here.
Provider-keyed files
The crosswalk first
A file keyed to a provider’s IDs instead of VINs takes the crosswalk first at vindex.vin: the Vindex ladder resolves each provider ID to its identity, and the enrichment runs from there, every edge scored, never a silent join.
For the agent you send.
The agent reads the same record you do.
Same two routes, three representations: the numbers never differ between them.
- Motionsb2aThe buyer is an agent: no human leaf; discover, bind, pay, worst-case cost posted before the call
- Machine surfaces/llms.txt/icp.json/.well-known/agents.json
- One MCP serverapis.vin/mcp serves the whole platform: every door’s tools in one server, each result carrying its door’s URL.
- AttributionX-Client-Type: html | md | json | mcp names which reader arrived; it never changes the record.