# Changelog of VIN Decoder API (`prodiger/vin-decoder`) Actor

- **URL**: https://apify.com/prodiger/vin-decoder/changelog.md
- **Full Actor documentation**: https://apify.com/prodiger/vin-decoder.md

## Changelog

All notable changes to this project are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### \[0.2] — 2026-04-29

#### Added

- **Extended decode mode.** New `decodeMode: basic | extended` toggle. Extended mode calls NHTSA's `DecodeVinValuesExtended/{vin}` per VIN for ~30% more fields (extra ADAS, EV battery, plant metadata) at the cost of losing batching. Basic mode (default) keeps the 50-VIN batched call.
- **Active recalls.** New `includeRecalls` toggle. Fetches NHTSA recalls by make/model/year and attaches the list to each decoded record. Per-run cache keyed by make+model+year so duplicate VINs cost zero extra upstream calls. Charged as `recalls-fetched` events.
- **NCAP safety ratings.** New `includeSafetyRatings` toggle. Two-step lookup against `api.nhtsa.gov/SafetyRatings/...` returning star ratings, complaint counts, recall counts, and ADAS availability per trim. Cached per make+model+year. Charged as `safety-rating-fetched` events.
- **VIN structural breakdown.** Every record now includes a `structure` object with WMI, VDS, VIS, check digit, model year character, plant code, sequential number — fully offline parse.
- **Check-digit validation** (ISO 3779). VINs with forbidden characters (I/O/Q) or bad length are flagged before any upstream call and surfaced as `valid: false` records with `errors: [...]`. Failed check-digit math is reported via `structure.checkDigitValid` but does not reject the VIN (non-NA VINs frequently fail the math while still being real).
- **Structured output.** Replaced the flat `vehicleInfo` blob with semantic categories: `identification`, `body`, `engine`, `drivetrain`, `electric`, `safety`, `advancedDriverAssistance`, `manufacturing`, `diagnostics`, plus an `other` bucket for unmapped fields. NHTSA's original PascalCase keys are preserved within each category.
- **Tiered PPE pricing.** Four event types: `vin-decoded`, `recalls-fetched`, `safety-rating-fetched`, `invalid-vin` (intended free-tier). Configure prices in Console → Settings → Monetization.

#### Changed

- Output shape is **breaking** vs. 0.1: `vehicleInfo` is gone; consumers should read from the category buckets or the new `other` field.
- Dataset schema gained a second view ("Recalls & ratings") for users who turn the enrichment toggles on.

#### Migration note

- Existing 0.1 consumers reading `record.vehicleInfo.Make` should switch to `record.identification.Make`. All NHTSA field names within categories are unchanged.

### \[0.1] — 2026-04-29

#### Added

- Initial release. VIN decoder API backed by the free NHTSA `DecodeVINValuesBatch` endpoint.
- Bulk-friendly input: array of strings, comma-separated string, or semicolon-separated string. VINs are uppercased, trimmed, length-validated (17 chars), and deduplicated before any upstream call.
- Automatic batching at the NHTSA cap of 50 VINs per request, with capped exponential-backoff retries on transient failures.
- Pay-per-event pricing: synthetic `apify-actor-start` (configured in Console → Settings → Monetization) plus one `vin-decoded` event per VIN successfully written to the dataset.
- `maxVinsPerRun` hard cap (default 1000) so a single run cannot accidentally rack up unbounded charges.
- Graceful abort handler that flushes state and exits cleanly when the run is stopped.
