Safety ratings

NHTSA crash ratings matched to the exact build, with equipment and the regulator's original text.

Crash ratings can be looked up by two different keys. The key you use decides how precise the answer is.

By model year: every configuration NHTSA rated

Bash
curl "https://api.cardog.app/v2/safety/model-year:ram/1500/2026" \
  -H "x-api-key: $CARDOG_API_KEY"

The response carries ratings, one per configuration NHTSA tested for that model year, and best, the highest-scoring one. Use this when you have a year, make, and model but not a specific vehicle.

By build code: the rating for that vehicle

Bash
curl "https://api.cardog.app/v2/safety/nano:1C6SRFVTTN" \
  -H "x-api-key: $CARDOG_API_KEY"

The nano is the build code from a VIN decode: VIN positions 1–8 plus 10, returned as refs.nano on /v2/vin. It identifies the exact configuration: cab, drivetrain, fuel, weight class.

Use this route when you have a VIN. NHTSA does not rate "a 2026 Ram 1500". It rates a crew cab and a quad cab separately, and on that truck the difference is four stars against five. Given the build code, we narrow the model year's ratings to the configurations that can be yours:

JSONC
{
  "matchGrain": "configuration",   // narrowed to exactly one
  "candidates": 5,                 // how many the model year had
  "matched": [ /* the survivors */ ],
  "best": { /* … */ }
}

matchGrain says how far the narrowing got:

grainmeaning
configurationnarrowed to one. This is your vehicle's rating.
partialnarrowed, but more than one survives
model-yearnothing could be ruled out
unratedNHTSA has no ratings for this model year
exemptoutside the programme. NCAP does not test above 10,000 lb GVWR.

When more than one rating survives, the response returns the shortlist instead of picking one. unresolved names what stopped the narrowing.

Equipment is answered at trim grain on this route only. A trim cannot be known without the build, so the model-year route reports NHTSA's answer alone. It is coarser, but it is not wrong.

The shape

A rating comes back in five blocks:

blockanswers
configwhat this rating covers, with every axis as an entity ID
crashwhat NHTSA measured
equipmentwhat the vehicle has
publishedwhat the source said, verbatim
provenancewho said it, and which release

IDs, and when to use them

Identity and configuration ship twice, as an ID and as a display name:

JSONC
"makeRef": "make:honda",  "make": "HONDA",
"config": { "bodyStyleRef": "body-style:pickup", "bodyCabRef": "body-cab:crew-super-crew-crew-max" }

Use the name to show a person. Use the ID for everything else. The ID can be looked up at /v2/entities, it survives a change in how we capitalise, and it is the same string your VIN decode returns. body-style:pickup on a rating is the identical value to body-style:pickup on /v2/vin, so you can verify the join yourself.

"Not published" is not "not available"

This is the most commonly misread field on this surface.

answermeans
standardfitted to every vehicle in this configuration
optionaloffered, not fitted as standard
variesdepends on the trim, the seating position, or the weight rating
unavailablethe vehicle does not have it
not-publishedthe source left the field blank

The last two are different facts. A 2026 Civic has stability control, which US law has required since 2012, and an empty column in NHTSA's data. Reading not-published as unavailable there produces a wrong statement about a safety feature.

If you need a boolean, standard and optional mean present. Treat not-published as unknown, never as absent.

Where each answer came from

JSONC
"blindSpotMonitoring": {
  "availability": "standard",
  "grain": "trim",
  "sourceClaim": "manufacturer",
  "alsoReported": { "availability": "optional", "from": "nhtsa" }
}

Two sources answer equipment questions, and they answer at different grains. NHTSA rates a configuration, which spans trims, so "optional" means "on some trims of this configuration". Our catalogue describes one trim, so "standard" means "on this trim". Both can be true at once, and grain tells you which one you are reading.

alsoReported carries the other source's answer when it differs. That is usually a grain difference, not a disagreement.

conflict: true appears only when the two answers cannot both be true: one says the feature exists and the other says it does not. It is rare, and we report it rather than picking a winner.

nhtsaEvaluation carries the regulator's performance verdict where one exists. test-pending and test-results-not-available mean nobody has tested it yet. They are not failing grades.

Numbers carry units

JSONC
"crash": {
  "overall": { "stars": 5, "outOf": 5 },
  "rollover": {
    "possibility": { "value": 9.5, "unitCode": "P1" },
    "staticStabilityFactor": { "value": 1.48, "unitCode": "C62" }
  }
}

Unit codes are UN/CEFACT Recommendation 20, the same list schema.org's unitCode uses. P1 is percent. C62 is the code for a pure ratio: the static stability factor has no unit, and C62 states that rather than leaving the field empty. The full list is in Units.

stars: null means not rated. It is not a rating of zero.

Why an older car has no overall score

A 2005 vehicle carries frontal and side stars and crash.overall.stars: null. That is not a gap in our data.

NHTSA did not publish an overall vehicle score until the MY2011 programme redesign. Before that it published the individual tests and no roll-up. Frontal ratings go back to the early 1990s, side impact to MY1997, and rollover to MY2001. Roughly 65% of rating rows carry at least one star, and only about a third carry an overall score. Almost all of those are 2011 or later.

Checking our work

published is NHTSA's own text, unedited:

JSONC
"published": {
  "bodyStyle": "PU/CC",
  "driveTrain": "4WD",
  "dynamicTipResult": "No Tip",
  "abs": "S"
}

Every value in config, crash, and equipment is a resolution we performed against that text. published is how you audit it, and how you tell us when we are wrong. If config.bodyStyleRef says one thing and published.bodyStyle says another, report it.

Some source values are left unresolved. NHTSA's ABS column contains S, Std, A, Avl, Sb, and a manufacturer's trim notes. We map the unambiguous values and refuse the rest. A could mean standard or merely available, and guessing would put an invented fact in a safety field. Those become not-published, with the original preserved in published.