NHTSA vPIC often returns a GVWR or GVWRClass field on DecodeVinValues-style payloads: catalog phrases such as "Class 1: 6,000 lb or less (2,722 kg or less)" or shorter class tokens. That string is useful on a free VIN decode card. The trap is turning it into a payload pitch -- "tows 7,500 lb," "hauls a full crew plus gear," "half-ton ready" -- that the GVWR class field never asserted.
This post is about honest display: show the class (or raw GVWR text) when vPIC provides it, refuse payload inventing, and allow a clean "not provided" state when the field is empty. Pair weight-related fields only as separate rows, never as a merged towing slogan.
What GVWRClass is (and is not)
Gross Vehicle Weight Rating (GVWR) is a manufacturer rating for the maximum loaded vehicle weight the design is certified for. vPIC's class / GVWR fields answer a narrow catalog question: which rating band (or label) did the decode associate with this vehicle pattern?
It does not answer:
- How much payload remains after passengers, fuel, and options
- Towing capacity, tongue weight, or trailer brake requirements
- Whether the truck in the driveway still matches the stamped rating after modifications
- Bed length, cab style, or axle package marketing names
- "Half-ton," "three-quarter-ton," or lifestyle copy derived from class folklore
Empty GVWR / GVWRClass does not mean "probably Class 2." It means vPIC did not give you a value. Do not invent a default from make/model tables or from a brochure PDF keyed by trim.
Normalize empties, do not invent payload
Treat blank, "Not Applicable", "N/A", and similar tokens as missing. Do not rewrite a class string into "2,200 lb payload" or append a tow number because a sibling VIN looked similar last week.
const EMPTY = new Set([
"",
"not applicable",
"n/a",
"na",
"null",
"none",
"unknown",
]);
export type GvwrView = {
label: string | null;
source: "vpic" | "missing";
};
export function viewGvwrClass(fields: {
GVWR?: string | null;
GVWRClass?: string | null;
}): GvwrView {
const raw = (fields.GVWRClass ?? fields.GVWR ?? "").trim();
if (!raw || EMPTY.has(raw.toLowerCase())) {
return { label: null, source: "missing" };
}
// Keep the catalog token; do not coerce into payload / tow claims.
return { label: raw, source: "vpic" };
}
export function gvwrLines(view: GvwrView): string[] {
if (view.source === "missing" || !view.label) {
return ["GVWR class: not provided by vPIC for this VIN"];
}
return [
`GVWR (vPIC): ${view.label}`,
"Catalog rating class only -- not payload or towing capacity",
];
}
The footnote matters. Buyers and bots both over-read weight labels. A second line that names the source and the limit keeps the UI honest without burying the useful value.
Forbidden upgrades
Product pressure often asks for:
- Mapping Class 1 / Class 2 into "half-ton" or "light duty lifestyle" badges
- Inferring payload as
GVWR - curb weightwhen curb weight was never returned - Showing static tow charts keyed only by make/model when
GVWRClassis blank - Merging GVWR with drive type or body class into "Capable Towing SUV"
- Defaulting blank GVWR to the most common class for that model year
Refuse those. If you show curb weight, battery weight, or trailer info from another sourced field, show each on its own row. Never invent the arithmetic inside the decode mapper when vPIC did not supply both sides.
export function assertNoPayloadMarketing(moduleSource: string): void {
const banned = [
/half[-\s]?ton/i,
/payload\s*\d/i,
/tows?\s+\d/i,
/hauls?\s+a\s+full/i,
/tongue\s*weight/i,
];
for (const re of banned) {
if (re.test(moduleSource)) {
throw new Error(
`GVWR display module must not invent payload/tow claims: ${re}`,
);
}
}
}
export function cardRows(fields: {
GVWR?: string | null;
GVWRClass?: string | null;
DriveType?: string | null;
}): { label: string; value: string }[] {
const gvwr = viewGvwrClass(fields);
const drive = (fields.DriveType ?? "").trim();
const rows: { label: string; value: string }[] = [];
if (gvwr.source === "vpic" && gvwr.label) {
rows.push({ label: "GVWR (vPIC)", value: gvwr.label });
} else {
rows.push({ label: "GVWR (vPIC)", value: "not provided" });
}
if (drive && !EMPTY.has(drive.toLowerCase())) {
rows.push({ label: "Drive type (vPIC)", value: drive });
}
return rows;
}
Separate rows keep attribution clear. A single "Capability" chip that secretly combines GVWR and drive type is how marketing sneaks past review.
Class strings vs numbers
Some responses return a long class sentence; others return a short code. Pass through what vPIC sent. Do not "normalize" Class 1 into a single integer pounds figure unless the same field already contains that figure and you are extracting it for display without changing meaning. Prefer showing the catalog string verbatim over a parsed number that looks more precise than the source.
Small tests that lock honesty
import assert from "node:assert/strict";
assert.equal(
viewGvwrClass({
GVWRClass: "Class 1: 6,000 lb or less (2,722 kg or less)",
}).source,
"vpic",
);
assert.equal(viewGvwrClass({ GVWRClass: "N/A" }).source, "missing");
assert.equal(viewGvwrClass({ GVWR: "" }).source, "missing");
assert.ok(
gvwrLines(
viewGvwrClass({ GVWRClass: "Class 2E: 6,001 - 7,000 lb" }),
).some((l) => /not payload or towing/i.test(l)),
);
assert.ok(
!gvwrLines(
viewGvwrClass({ GVWRClass: "Class 2E: 6,001 - 7,000 lb" }),
).some((l) => /half-ton|tows|payload \d/i.test(l)),
);
const rows = cardRows({
GVWRClass: "Class 1: 6,000 lb or less (2,722 kg or less)",
DriveType: "4x2",
});
assert.equal(rows.length, 2);
assert.ok(rows[0].label.includes("GVWR"));
assert.ok(rows[1].label.includes("Drive type"));
assert.ok(!rows.some((r) => /Capable Towing/i.test(r.value)));
Add a review rule: the GVWR module must not contain payload or tow marketing phrases except in tests that forbid them. For chips, show the catalog class with a "GVWR" label -- never upgrade a blank into "Standard Duty."
Takeaway
GVWR / GVWRClass is a catalog rating band. Display it with clear sourcing, allow "not provided," and never use it as a key into invented payload or towing claims. Your free VIN UI stays trustworthy when GVWR is either a real vPIC value with a modest footnote -- or absent -- and capability marketing lives somewhere else, clearly labeled, or not at all.
I maintain VIN Lookup, a free VIN decode based on NHTSA data.
Top comments (0)