close
apis.vin

The .vin family API

Every capability, addressed by VIN.

Decode and listings reads, the buy pillar’s deal lifecycle, F&I rating and contracts, credit prequalification — one API behind the family’s doors, one key doctrine, agents welcome.

OK EMPTY BLOCKED OFFER Typed envelopes on every door. Three emptinesses never blend, and no address answers 406.
the zero-friction proof POST /keys
# mint a sandbox key — no email, no approval, no CAPTCHA$ curl -X POST https://apis.vin/keys{"type":"OK","key":"vk_sandbox_…","account":"agent_anon_…","environment":"sandbox",…} # first decode — this door also answers keyless$ curl https://apis.vin/decode/JM3KFBXY1S0597748{"type":"OK","decode":{"vin":"JM3KFBXY1S0597748","year":2025,"make":"Mazda","model":"CX-5 2.5 Turbo",…$ 

The key is returned exactly once; the server stores only a sha256 hash. It adds account context and never unlocks licensed data tiers.

01 / 04 · the record face

GET /{VIN} · seventeen characters, decoded

A VIN is a structured address: every position reserves a meaning, and position 9 certifies the other sixteen. Ask this door for one and the record answers. Everything else at the root is a namespace.

world manufacturerJM3Mazdavehicle attributesKFBXYCX-5check digit1model yearS2025plant0serial597748this one car

the whole surface, projected from the catalog

One catalog, addressed by VIN

317nouns3,927capabilities4,484events20workflows 124 / 3,927live

Every figure here is read from the catalog, not typed onto the page — 3,927 capabilities across 317 nouns, and 124 of them answer in production today. The rest are not hidden; they are on the record.

Five pillars

  • Dataknow it117 live · 1,299 sandbox1,416
  • Servicesdo it1 live · 1,572 sandbox1,573
  • Commercetransact it5 live · 931 sandbox936
  • Workflowscompose it0 live · 20 sandbox20
  • AIapply it1 live · 1 sandbox2

The busiest nouns

Each noun is a job a car needs done; the number is how many capabilities already name it.

  • transport41
  • part37
  • tires36
  • carrier35
  • provider34
  • inspection32
  • recall31
  • telematics31
  • driveline29
  • insurance28
  • recon28
  • brakes27

The precision ladder

Coverage is graded honestly — the key selects the mode, and a mode is posted per capability: what answers in production, what activates on a connection, what answers deterministically in sandbox mode.

  1. 124

    live

    Answering in production today — real fulfilment, on the record. The key selects the mode: the same doors answer deterministically without one.

  2. 141

    live via connection

    Certified, connect to activate — the rail is certified against its counterparty class. 4 of these answer the real wire the moment a vaulted token lands (activation is the token, never a deploy); the rest disclose adapter-pending until their adapter arrives. Live-active today: 0 — a live claim needs a receipt of value flow, and none posts one yet. Until activated they answer in sandbox mode, labeled.

  3. 3,803

    sandbox

    A caller mode, never a status claim — deterministic behind real wire shapes; every simulated payload says so machinably.

02 / 04 · the ways in

Four ways in

The same surface table drives every one of them — the HTTP doors, the SDK, the CLI, and the MCP server state one truth.

HTTP — the doors themselves

Plain HTTP, keyless-first, a typed envelope from every address. The contract is posted at /openapi.json.

  • GET/decode/{vin}the decode read
  • GET/listingsthe listings query
  • POST/buy/dealsopen a deal
  • POST/fi/quotesrate a quote
  • POST/credit/prequalprequalify
  • POST/keysmint the sandbox key
typescript vin.data.decode()
import { createVinClient, originFetcher } from 'apis.vin'

const vin = createVinClient(originFetcher('https://apis.vin'), {
  authorization: 'Bearer vk_sandbox_…',
})
const record = await vin.data.decode('JM3KFBXY1S0597748')
// the typed envelope verbatim —
// record.type: 'OK' | 'EMPTY' | 'BLOCKED' | 'OFFER'

SDK — typed client, pillar namespaces

Namespaces: data / buy / fi / credit / keys — pillars are namespaces of the one package, never separate packages.

apis.vin is on npmnpm i apis.vin; every HTTP door on this page answers today.

CLI — vin, sandbox-first

Every answer is a typed envelope; --json prints it verbatim for agents, --no-browser is for CI. Ships inside the same npm package.

shell vin decode
$ npm i -g apis.vin   # the published package — SDK + CLI in one
$ vin keys create   # mints + stores the anonymous sandbox key
$ vin decode JM3KFBXY1S0597748
$ vin buy JM3KFBXY1S0597748

MCP — for agent runtimes

The one estate MCP server: POST https://apis.vin/mcp — JSON-RPC 2.0 over streamable HTTP, keyless. tools/list names exactly what this deployment answers: search finds a capability, fetch dereferences an address and returns the typed envelope verbatim.

The same surface table drives the SDK, the CLI, and this server — zero drift, test-enforced.

03 / 04 · keyless to metered

The ladder

Keyless works. A key is one anonymous POST. Prices are posted so nothing is ever an ask.

  1. Keyless

    Every read door answers in full with no key — the quartet, /listings, /decode/{vin}, the record face. VIN decode is posted at $0.00 — the anonymous rung.

  2. Sandbox key

    POST /keys mints vk_sandbox_… instantly — fully self-service, no email, no approval, no CAPTCHA. It adds account context (GET /keys/me) and never unlocks licensed or premium data tiers.

  3. Metered

    Posted v0 unit prices: listings query $0.01, F&I rate quote $0.05, hard ceiling $25.00 per caller per day. No terms document binds them yet; the pricing face says so machinably.

The sandbox is deterministic behind real wire shapes: the same input always answers the same way, refusals are named, and every simulated payload carries "environment":"sandbox", "simulated":true.

04 / 04 · the attestations

Read it yourself

Every claim on this page has a machine face you can dereference.

The published suite pins to sha256:20183444abc2251eaa76773ad9e81f1c8ef439c4a7b6fc05719d58e58fab0c4c — the verifier refuses to run a drifted copy.