# JDM VIN Decoder - Japanese Chassis Number to Production Date (`scrapersdelight/jdm-vin-chassis-decoder`) Actor

Decode Japanese chassis numbers (JDM VINs) that ordinary VIN decoders reject: production month and year, model, colour, trim, engine and grade codes - plus the exact dates each car clears the US 25-year and Canadian 15-year import rules. Searches all 9 makers itself.

- **URL**: https://apify.com/scrapersdelight/jdm-vin-chassis-decoder.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 per chassis decodeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## JDM VIN Decoder — Japanese Chassis Number to Production Date

Japanese domestic vehicles do not have ISO VINs. A JDM chassis number looks like **`BNR34-001234`** —
a model code, a dash, a serial — and every ordinary 17-character VIN decoder rejects it outright.

This Actor decodes them: **factory production month and year**, the full build specification, and the
exact dates the car clears the **US 25-year** and **Canadian 15-year** import exemptions.

***

### What one row looks like

```json
{
  "chassisNo": "BNR34-001234",
  "inputModelCode": "BNR34",
  "serial": "001234",
  "status": "HIT",
  "resolvedMaker": "NISSAN",
  "makerHint": "NISSAN",
  "makersTried": ["NISSAN"],
  "matchIndex": 1,
  "matchCount": 1,
  "productionYear": "1999",
  "productionMonth": "1",
  "productionDate": "1999-01",
  "usEligibleDate": "2024-01",
  "caEligibleDate": "2014-01",
  "usEligibleNow": true,
  "caEligibleNow": true,
  "monthsUntilUsEligible": -32,
  "modelName": "SKYLINE",
  "catalogModelCode": "GGJPRVYR34ZDAAAJCD",
  "frameCode": "R34",
  "colorCode": "QM1",
  "trimCode": "G",
  "optionCodes": ["2K", "RB26DETT [ ＲＢ２６ＤＥＴＴ型エンジン ]", "HI.4WD", "GTR", "MT.F6"],
  "optionCodeSplit": "single"
}
```

| field | what it is |
|---|---|
| `productionDate` | **The answer most buyers came for** — factory build month, `YYYY-MM` |
| `usEligibleDate` · `caEligibleDate` | Month the car clears the US 25-year / Canadian 15-year rule |
| `usEligibleNow` · `caEligibleNow` | Whether it is admissible **today** |
| `monthsUntilUsEligible` | Months remaining; negative if it already cleared |
| `resolvedMaker` · `makersTried` | Which maker's catalogue held the car, and which were searched |
| `matchIndex` · `matchCount` | See **When one chassis returns two cars** below |
| `modelName` · `catalogModelCode` · `frameCode` | Model identity. `inputModelCode` is what you typed (`BNR34`); `catalogModelCode` is the catalogue's own long code |
| `colorCode` · `trimCode` | Factory paint and interior codes — what you need to order matching parts or verify originality |
| `engineNo` · `gradeCode` · `transCode` · `bodyCode` · `doorStyle` | Build specification, where the maker publishes it |
| `optionCodes` | Factory option codes, **verbatim** in the catalogue's own mixed Japanese |
| `raw` | The untouched upstream payload, once per chassis |

### Input

| input | default | what it does |
|---|---|---|
| `chassisNumbers` | three worked examples | One per line, `<model code>-<serial>`. **You do not supply the maker** |
| `maxChassis` | `0` (all) | Hard cap on how many are looked up, delivered and charged |
| `proxyConfiguration` | Apify Proxy (datacenter) | Datacenter is fine here — 530 of 530 lookups measured clean |

#### You do not need to know the maker

The site publishes a maker-lookup endpoint, and it is **only 65% accurate** — measured 13 of 20,
with **confidently wrong answers rather than blanks**: `S15` → MINI, `DC2` → JAGUAR, `FD2` → HINO,
`K11` → TOYOTA, `BP5` → MAZDA. Those are the Silvia, Integra Type R, Civic Type R, March and
Legacy — squarely the cars this trade moves.

A wrong maker returns *exactly* the same "information not found" a genuine miss returns. So this
Actor treats that lookup as a hint that only **orders** the search, then searches all nine makers
(Toyota, Nissan, Honda, Mazda, Mitsubishi, Subaru, Suzuki, Daihatsu, Isuzu). **A chassis is only
reported `NOT_FOUND` once all nine have missed**, and `makersTried` shows you exactly which were
searched so the coverage claim is auditable rather than asserted.

### The three statuses, and why they are separate

| status | meaning | charged |
|---|---|---|
| `HIT` | Decoded | `chassis-decoded` |
| `NOT_FOUND` | All nine makers searched, none held it | `chassis-not-found` |
| `ERROR` | **Could not be looked up** — the source errored | **never charged** |

`ERROR` exists because conflating it with `NOT_FOUND` would be a lie with consequences: it would
tell you your car is not in the catalogue when the truth is nobody ever asked. Those rows carry
`httpStatus`, `attempts` and `reason`.

The source occasionally returns server errors. When that happens the Actor retries on a widening
backoff, and if it keeps failing it **stops the run** rather than marching through your remaining
chassis numbers reporting them all as "not found".

One subtlety worth stating, because it bit us in testing: when the source is degraded it returns the
same "no such chassis" response it returns for a genuine miss. We measured a chassis return that
response three times during a wobble and then decode perfectly hours later. So once a run has seen
any server error, that response is treated as **indeterminate**, not as a miss.

### When one chassis returns two cars

Some chassis numbers match **two catalogue records**, and the source merges them field-wise rather
than returning a list. `K11-012345` comes back with `year: ["1992","1992"]` and an option list whose
two halves **disagree** — so these are genuinely two vehicles, not a display duplicate.

This Actor emits **one row per record**, stamped `matchIndex` / `matchCount`, and splits the option
codes between them. **Both rows cost one decode.** If the option list cannot be divided cleanly
across the records, `optionCodes` is `null`, the untouched list is kept in `optionCodesRaw`, and
`optionCodeSplit` says `ambiguous` — it will never invent an allocation.

### Coverage — measured, not promised

The catalogue does **not** hold every Japanese chassis number. Across randomly constructed but
plausible chassis numbers the hit rate measured **53–65%**; against real chassis numbers off actual
vehicles it is considerably better, because those cars exist. **This Actor does not promise 100%
coverage and you should not buy it expecting that.** A `NOT_FOUND` means nine catalogues were
searched and none held the car — that is a real, auditable answer, and it is priced at a twentieth
of a decode.

### Pricing

| event | price | when |
|---|---|---|
| `chassis-decoded` | **$0.02** | Once per chassis decoded — the same whether it took one lookup or nine, and the same if it returns two catalogue records |
| `chassis-not-found` | **$0.001** | Once per chassis searched across all nine makers and not found |
| — | **free** | A chassis that could not be looked up (`ERROR`) |

Verified on the platform: a five-chassis run with four decodes (one of them a two-record match) and
one genuine miss billed exactly **4 × `chassis-decoded` + 1 × `chassis-not-found`**.

Every run also writes a `RUN_SUMMARY` to the key-value store: submitted, malformed, looked up,
decoded, missing, not-looked-up, the hit rate, total HTTP requests, and whether the source was
erroring during the run.

### Source and provenance

Data comes from the public chassis lookup at `jpauc.com/vin`, which serves it to anonymous clients
with no key, no login and no session. `robots.txt` is literally `User-agent: *` with no restrictions.

The site presents this as third-party catalogue data and states it is not responsible for its
accuracy — so treat a decode as strong evidence, not as a legal certification. **For an actual
import, verify the production date against the vehicle's own export certificate or de-registration
paperwork before you commit money or book shipping.** The 25- and 15-year dates this Actor computes
are straightforward arithmetic on the production month; they are not legal advice, and they do not
account for any other admissibility question (modifications, recalls, state-level rules).

# Actor input Schema

## `chassisNumbers` (type: `array`):

One per line, formatted <model code>-<serial>, e.g. BNR34-001234, ANH10-0012345, JZX100-0012345. You do NOT need to supply the maker: the Actor searches all nine (Toyota, Nissan, Honda, Mazda, Mitsubishi, Subaru, Suzuki, Daihatsu, Isuzu), because the site's own maker lookup is only 65% accurate and a wrong maker is indistinguishable from a car that isn't in the catalogue.

## `maxChassis` (type: `integer`):

Hard cap on how many of the submitted numbers are looked up, delivered and charged. 0 means all of them.

## `proxyConfiguration` (type: `object`):

Apify Proxy. Datacenter is fine for this source and is the default - 530 of 530 correct lookups measured with zero transport failures.

## Actor input object example

```json
{
  "chassisNumbers": [
    "BNR34-001234",
    "ANH10-0012345",
    "JZX100-0012345"
  ],
  "maxChassis": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per catalogue match. Production month and year, the full factory build spec, and the dates the car clears the US 25-year and Canadian 15-year import exemptions. A chassis that merges two catalogue records yields two rows carrying matchIndex and matchCount.

## `runSummary` (type: `string`):

RUN\_SUMMARY: how many chassis were submitted, malformed, looked up, decoded, genuinely missing and not-looked-up; the hit rate; total HTTP requests; and whether jpauc.com was returning server errors during the run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/jdm-vin-chassis-decoder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/jdm-vin-chassis-decoder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call scrapersdelight/jdm-vin-chassis-decoder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/jdm-vin-chassis-decoder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/98T7xVtgXYqwdkaYC/builds/bheMjtSXxxyrocTin/openapi.json
