Window stickers by VIN

The factory window sticker (Monroney label) we hold for a VIN, or a typed reason there is none. Free when there is none.

Bash
curl "https://api.cardog.app/v2/vin/1GCUYDED1MZ123456/window-sticker" \
  -H "x-api-key: $CARDOG_API_KEY"

The window sticker is the label on the glass of a new vehicle: trim, every factory option with its price, the destination charge, fuel economy, where it was assembled. It is the manufacturer's own statement of what it built. Nobody is required to keep one after the sale and no government holds a copy, so the only source is the manufacturer, and only some manufacturers serve one by VIN.

GET /v2/vin/{vin}/window-sticker tells you whether we hold that label, and if not, why. Both answers are a 200. Only the first costs credits.

When we hold the label

Example

4 keys
"response": {
"vin": "1GCUYDED1MZ123456",
"label": {
"issuer": "gm",
"retrievedAt": "2026-09-14T12:00:00.000Z",
"vinVerified": true,
"document": {4 items}
},
"unavailable": null,
"links": {
"identity": "/v2/vin/1GCUYDED1MZ123456"
}
}
  • issuer is the manufacturer whose service gave us the label. It is null in the rare case where we hold the file but the collecting run did not record who served it.
  • retrievedAt is when we collected it.
  • vinVerified is true only when the VIN was read from inside the document. Some manufacturers render the VIN as an image or in an embedded font, so it cannot always be read. false means the manufacturer's service returned this label when asked for this VIN, and nothing stronger. Treat an unverified label as the manufacturer's answer, not as proof it belongs to this vehicle.
  • document names the file by its content address and SHA-256. The same file always has the same address, so you can cite it. downloadUrl is a signed link to the PDF, good for 24 hours.

A held label costs 5 credits.

The PDF

Bash
curl "$DOWNLOAD_URL" -o sticker.pdf

downloadUrl is a signed link: GET /v2/window-sticker/{sha256}?exp=…&sig=…. Open it exactly as printed. It needs no API key and no session, so you can open it in a browser tab, put it in an <iframe>, or hand it to a PDF viewer. It costs 0 credits, GET or HEAD. The body is the label as the manufacturer's service produced it, served as application/pdf and inline, so a browser displays it rather than downloading it. A viewer that fetches pages on demand can send Range: bytes=N-M and get a 206.

The link is good for 24 hours. After that it answers 403 forbidden, and so does a link that has been altered. The fix is the same in both cases: request the read again and use the new downloadUrl. That read is billed again when the label is held. Do not store the link; keep the VIN. sha256 names the file forever; the link is only a door that is open today.

A signed link to a hash we hold nothing under is a 404 with the usual error envelope, never an empty file. If the file cannot be fetched right now the answer is 503 unavailable; retry with backoff.

When we do not

Example

4 keys
"response": {
"vin": "1FTFW1E84PKE12345",
"label": null,
"unavailable": {
"reason": "not_yet_harvested",
"issuer": "ford",
"detail": "We have not collected this label yet."
},
"links": {
"identity": "/v2/vin/1FTFW1E84PKE12345"
}
}

This costs 0 credits. detail is a sentence you can show a user. reason is what your code should read, because each one asks something different of you:

reasonWhat it meansWhat to do
not_yet_harvestedWe have not collected this label yet, or it was not released when we asked.Retry later. Poll with HEAD (below), which is free.
issuer_has_no_recordThe manufacturer has no label for this VIN.Treat as the manufacturer's answer. Do not retry soon.
lane_us_onlyCoverage for this manufacturer is US-sold vehicles only, and there is no label for this VIN.Do not retry.
pre_lane_model_yearThe vehicle predates our coverage for its manufacturer.Do not retry.
no_laneWe do not collect window stickers for this manufacturer.Do not retry.

Only not_yet_harvested can change. The other four are final.

The free existence check

HEAD on the same path answers with a status code and no body: 204 when we hold a label, 404 when we do not. It costs nothing on every plan, so it is the right way to poll after a not_yet_harvested answer, or to decide whether the GET is worth its credits.

Bash
curl -I "https://api.cardog.app/v2/vin/1FTFW1E84PKE12345/window-sticker" \
  -H "x-api-key: $CARDOG_API_KEY"

Which manufacturers

Ford, Lincoln, GM, Stellantis (Chrysler, Dodge, Jeep, Ram, Fiat, Alfa Romeo), Hyundai, Genesis, Kia, Toyota, Lexus, Nissan and Mitsubishi. Coverage by market and model year varies by manufacturer; reason tells you when a VIN falls outside it.

In the SDKs

import { writeFile } from "node:fs/promises";

const r = await client.v2.vin.windowSticker("1GCUYDED1MZ123456");
if (r.label) {
  console.log(r.label.vinVerified, r.label.document.sha256);
  const pdf = await client.v2.vin.windowStickerDocument(r.label.document.downloadUrl);
  await writeFile("sticker.pdf", Buffer.from(await pdf.arrayBuffer())); // a fetch Response
} else if (r.unavailable.reason === "not_yet_harvested") {
  // poll with HEAD later
}

Not yet

The label's printed contents (options and their prices, MSRP, fuel economy, assembly point) are not served yet; they arrive as typed rows on a later release, additive to this response.