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.

2025 Mazda CX-5 · check digit 1 · verified

The enriched row at enrich.vin/{VIN}: decode plus the licensed record fields. The file runs the same, row by row.

The file, before and after
inventory.csvBefore · one column
  • vin
  • JM3KFBXY1S0597748
  • Your remaining rows
inventory.enriched.csvAfter · the same rows, plus the record
  • VINJM3KFBXY1S0597748
  • Decode2025 Mazda CX-5
  • Record fieldsPosts where licensed
  • Resolutionresolved
Appended column setsdecodespecsvalueslistingsstickerflags

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 batch envelopeapis.vin/mcp
1// the typed offer, on paper before the first byte moves
2{
3 "type": "enrich.batch",
4 "in": {
5 "file": "inventory.csv",
6 "vin_column": <named or detected>
7 },
8 "offer": {
9 "per_row": <posted, or absent while the gate is open>,
10 "settlement": "x402",
11 "expiry": <RFC 3339>
12 },
13 "out": {
14 "columns": <the licensed record fields: value · source · timestamp>,
15 "resolution": ["resolved", "INVALID_VIN", "no record"]
16 }
17}
Evidence
  • 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.

Three representationsenrich.vin
1curl https://enrich.vin/ -H 'accept: text/markdown'
2 # the markdown twin of this page
3curl https://enrich.vin/{VIN} -H 'accept: application/json'
4 # the record as typed evidence objects
5curl https://enrich.vin/{VIN} -H 'accept: text/markdown'
6 # the record's markdown twin
On this host
  • Motionsb2aThe buyer is an agent: no human leaf; discover, bind, pay, worst-case cost posted before the call
  • 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.