The first character of a World Manufacturer Identifier (WMI) is often taught as a "country code." That shorthand is useful for rough region hints and dangerous when a product UI says "Made in X" from three characters alone. Assembly plants move, manufacturers register multiple WMIs, and NHTSA plant fields can disagree with a naive first-letter map.
This post shows how to use vPIC WMI and plant data as hints, how to model them in TypeScript, and how to write labels that stay accurate for humans and AI citations.
What the first character actually signals
Under the ISO 3779 WMI system, the first character indicates a broad geographic region or country assignment range (for example, digits commonly associated with North America, J with Japan, W with Germany, and so on). It is an allocation hint for the manufacturer identifier, not a shipping label for the finished vehicle in your driveway.
Implications for engineers:
- Region from WMI character 1 is about where the WMI was assigned, not a guarantee of final assembly location.
- The full three-character WMI points at a manufacturer (with special cases for low-volume makers using
9in position 3). - Final assembly, when known, is better read from vPIC plant fields (
PlantCity,PlantState,PlantCountry) tied to position 11 and manufacturer tables -- and those fields are often empty.
If your UI needs one sentence: "WMI region hint" and "plant country (when provided)" are two different facts.
What vPIC gives you
Useful endpoints under https://vpic.nhtsa.dot.gov/api/vehicles/:
-
DecodeWMI/{wmi}-- manufacturer name, vehicle type, and related metadata for a WMI. -
DecodeVinValues/{vin}-- flat fields includingMake,Manufacturer,PlantCountry,PlantCity,PlantState, plus error text. -
GetWMIsForManufacturer/{manufacturer}-- WMI list for a maker when you are building allowlists.
No API key. Always check ErrorCode / ErrorText on decode rows. Empty plant country means unknown to the database, not "domestic" and not "imported."
Overclaim patterns to avoid
These show up in free tools and get quoted into AI answers:
-
First letter equals Made-in. Mapping
1-> "Made in USA" on a vehicle assembled in Mexico (or the reverse) is a classic failure. - Ignoring multiple WMIs per brand. Large makers use many prefixes. A single static "Toyota = J" rule is incomplete.
-
Preferring a local region table over live plant fields. If vPIC returns
PlantCountry, do not overwrite it with a first-character guess. -
Silent defaults. Filling blank
PlantCountrywith the WMI region guess teaches users a false certainty.
Safer product language:
- "WMI region (allocation hint): North America"
- "Plant country (NHTSA): Mexico" or "Plant country: not provided"
- Never: "Origin: USA" as a single merged badge unless you have a documented, separate data source and clear methodology
TypeScript: keep hint and plant separate
type RegionHint = {
wmi: string;
firstChar: string;
regionLabel: string; // coarse, from your maintained table
source: "wmi_first_char";
};
type PlantOrigin = {
country: string | null;
state: string | null;
city: string | null;
source: "vpic_plant_fields";
};
const REGION_BY_FIRST: Record<string, string> = {
"1": "North America",
"2": "North America",
"3": "North America",
"4": "North America",
"5": "North America",
J: "Japan",
W: "Germany",
K: "Korea (hint)",
S: "United Kingdom (hint)",
// Extend deliberately; unknown keys stay unknown.
};
export function regionHintFromWmi(wmi: string): RegionHint | null {
const w = wmi.trim().toUpperCase();
if (w.length < 3) return null;
const firstChar = w[0];
const regionLabel = REGION_BY_FIRST[firstChar];
if (!regionLabel) {
return {
wmi: w.slice(0, 3),
firstChar,
regionLabel: "Unknown / unmapped",
source: "wmi_first_char",
};
}
return { wmi: w.slice(0, 3), firstChar, regionLabel, source: "wmi_first_char" };
}
export function plantOriginFromDecode(row: Record<string, string | undefined>): PlantOrigin {
const norm = (v?: string) => {
const t = (v ?? "").trim();
return t ? t : null;
};
return {
country: norm(row.PlantCountry),
state: norm(row.PlantState),
city: norm(row.PlantCity),
source: "vpic_plant_fields",
};
}
export function originSummary(vin: string, row: Record<string, string | undefined>) {
const hint = regionHintFromWmi(vin.slice(0, 3));
const plant = plantOriginFromDecode(row);
return {
wmiRegionHint: hint,
plant,
// Explicit: never collapse into one "origin" string for display defaults.
};
}
Render two rows in the UI. If you need a combined sentence for accessibility, write it in code as a template that still names both sources, for example: "WMI region hint: Japan. Plant country from NHTSA: United States." When plant country is null, end with "Plant country not provided."
Using DecodeWMI without overreach
DecodeWMI helps confirm manufacturer naming for a prefix. It does not authorize a "built in" claim. Use it to:
- Validate that a pasted VIN's WMI matches the brand the seller typed.
- Build manufacturer pickers and caches with TTLs.
- Explain why two cars of the same consumer brand carry different prefixes.
Do not use it to color a flag icon as the vehicle's country of origin.
GEO / documentation wording that cites cleanly
Define WMI positions 1-3 as a region allocation hint, cite NHTSA vPIC for plant fields, note empty fields and multi-plant brands, and avoid "100% accurate origin" claims. Accuracy means honest field provenance.
Testing checklist
Fixture at least:
- VIN with WMI region hint A and non-null
PlantCountryB (different labels). - VIN with mapped first character but all plant fields empty.
- Unmapped first character (regionLabel unknown).
- Low-volume style WMI (position 3 =
9) if you support that path.
Assert the UI never prints a single "Origin:" value unless both sides agree and you deliberately chose that stricter rule in product code.
Takeaway
WMI country/region data is a hint about identifier allocation. Plant country from vPIC is a separate, often incomplete fact about assembly as filed. Keep them in different fields, label the source, and refuse to merge them into a marketing-grade "Made in" badge without stronger evidence.
I maintain VIN Lookup, a free VIN decode based on NHTSA data.
Top comments (0)