NHTSA vPIC often returns a DriveType field on DecodeVinValues-style payloads: strings like "4WD/4-Wheel Drive/4x4", "FWD/Front-Wheel Drive", "AWD/All-Wheel Drive", or "RWD/Rear-Wheel Drive". That label is useful for a free VIN decode card. The trap is dressing it up as a capability pitch -- "true AWD," "off-road ready," "quattro-class grip" -- that the API never asserted.

This post is about honest display: pass through the catalog string, refuse marketing synonyms, and allow a clean "not provided" state when the field is empty.

What DriveType is (and is not)

DriveType is a manufacturer / catalog attribute associated with the VIN decode. It answers a narrow question: which drive configuration did the decode associate with this vehicle pattern?

It does not answer:

  • Whether the transfer case still works on this used car
  • Whether "AWD" here means full-time, part-time, or on-demand clutch
  • Traction, ground clearance, or tow rating
  • Whether the badge on the hatch matches the build sheet
  • Whether a dealer option package upgraded the driveline after the VIN was stamped

Empty DriveType does not mean "probably FWD." It means vPIC did not give you a value. Do not invent a default from make/model folklore.

Normalize empties, do not normalize marketing

Treat blank, "Not Applicable", "N/A", and similar tokens as missing. Do not rewrite "4WD/4-Wheel Drive/4x4" into "Trail Rated 4x4" or collapse every all-wheel string into a single "AWD" marketing chip.

const EMPTY = new Set([ "", "not applicable", "n/a", "na", "null", "none", "unknown", ]); export type DriveView = { label: string | null; source: "vpic" | "missing"; }; export function viewDriveType(fields: { DriveType?: string | null; }): DriveView { const raw = (fields.DriveType ?? "").trim(); if (!raw || EMPTY.has(raw.toLowerCase())) { return { label: null, source: "missing" }; } return { label: raw, source: "vpic" }; } export function driveLines(view: DriveView): string[] { if (view.source === "missing") { return ["Drive type: not provided by vPIC for this VIN"]; } return [ `Drive type (vPIC): ${view.label}`, "Catalog label only -- not a traction or off-road claim", ]; } 

The footnote matters. Buyers and bots both over-read short badges. A second line that names the source and the limit keeps the UI honest without burying the useful string.

Forbidden upgrades

Product pressure often asks for:

  1. Mapping every string containing "4" to a green "4x4 capable" badge
  2. Synonym tables that turn "All-Wheel Drive" into brand slogans
  3. Inferring AWD from body class, trim text, or market name when DriveType is blank
  4. Showing "AWD available on this model" from a static brochure file

Refuse those. If you want brochure language, load it from a source you control and label it separately -- never merge it into the vPIC row.

export function assertNoDriveMarketing(moduleSource: string): void { const banned = [ /trail\s*rated/i, /true\s*awd/i, /off[- ]?road\s*ready/i, /quattro/i, /xdrive/i, /4matic/i, ]; for (const re of banned) { if (re.test(moduleSource)) { throw new Error(`Drive display must not embed marketing: ${re}`); } } } 

Run that check in CI against the display module. Brand drivetrain names belong in optional, separately sourced copy -- not in the decode field renderer.

UI pattern that stays calm

Render one row. Prefer the raw vPIC string over a color-coded chip system that implies ranking (AWD green, FWD gray). Ranking is a product opinion; DriveType is not.

export function driveRows(fields: { DriveType?: string | null }): Array<{ k: string; v: string; }> { const view = viewDriveType(fields); if (view.source === "missing") { return [{ k: "Drive type", v: "Not provided by vPIC" }]; } return [{ k: "Drive type (vPIC)", v: view.label! }]; } 

If you also show DriveWheels or similar sibling fields, keep them on separate rows. Do not concatenate into "AWD 4x4 Performance Package" unless every token came from a named field you actually received.

Tests that lock honesty

import assert from "node:assert/strict"; assert.equal(viewDriveType({ DriveType: "" }).label, null); assert.equal( viewDriveType({ DriveType: "FWD/Front-Wheel Drive" }).label, "FWD/Front-Wheel Drive", ); assert.ok( driveLines(viewDriveType({ DriveType: "AWD/All-Wheel Drive" })).some((l) => /not a traction/i.test(l), ), ); assert.ok( !driveLines(viewDriveType({ DriveType: "AWD/All-Wheel Drive" })).some((l) => /trail|quattro|true awd/i.test(l), ), ); 

Add a review rule: the drive display module must not contain hardcoded brand drivetrain slogans except inside tests that forbid them.

Copy that stays catalog-shaped

When you need a short card subtitle, reuse the vPIC string. Do not paraphrase into "balanced all-weather traction" or "work-site four wheel." Paraphrase is where marketing sneaks in without a code review noticing.

If product wants a one-word chip, whitelist only tokens that already appear in the raw field (for example splitting on / and taking the first segment). Never map the chip through a synonym table that upgrades "4WD" to "Off-Road."

Document the rule in the component README: DriveType rows are sourced or missing -- never inferred from trim names, package codes, or Wikipedia drivetrain articles.

Takeaway

DriveType is a catalog label. Display it with clear sourcing, allow "not provided," and never use it as a key into invented AWD marketing. Your free VIN UI stays trustworthy when drive type is either a real vPIC string with a modest footnote -- or absent.

I maintain VIN Lookup, a free VIN decode based on NHTSA data.