VIN Decoder - Developer Guide
1. Overview & Introduction
The VIN Decoder API resolves a 17-character Vehicle Identification Number into structured vehicle attributes — make, model, year, body type, engine details, weights, fuel economy, and related manufacturing data. It solves a common integration problem: turning an opaque VIN string into usable, structured vehicle data without maintaining your own decode tables.
The domain model is intentionally small. The single core operation, the VIN decode operation, takes a VIN and an optional U.S. state and returns a decoded-VIN result. That result is organized into two parallel views:
- Raw values — attributes as decoded directly from the VIN, independent of jurisdiction.
- State values — attributes normalized to a specific state's reference data, where some fields resolve to coded lookup values (a code plus a human-readable description) rather than free text.
Both views are described by their respective schemas in the spec (VinDecodedRawInfo and VinDecodedInfo). The distinction matters: use raw values for vendor-neutral vehicle facts, and state values when you need data aligned to a particular state's classification system.
The API is served across three environments — production, staging, and test — distinguished by an environment segment in the base URL (see the servers block in the spec). All access requires OAuth 2.0 client-credentials authentication with credentials issued by Vitu. No personally identifiable or regulated owner data is returned by this API; results describe the vehicle, not a person.
2. Getting Started / First Call
Prerequisites
- A Vitu-issued OAuth 2.0 client ID and secret. Obtain these from the Key Management area within Vitu's Developer Portal.
- The ability to reach the token endpoint and the API base URL for your target environment (see the spec's
serversandsecuritySchemes).
Happy path
- Obtain an access token. Perform a client-credentials token request against the token endpoint defined in the
oneVituOauthscheme, requesting theoneapi:accessscope. - Call the VIN decode operation (
decodeVin), passing the VIN as a required query parameter. Optionally supply a state; if omitted, the service defaults toCA. - Read the response. A successful call returns the decoded-VIN result (
VinDecoded) containing the raw and state views described above.
Minimal example
# 1. Get a token (client-credentials grant)
curl -X POST "$TOKEN_URL" \
-d grant_type=client_credentials \
-d client_id="$CLIENT_ID" \
-d client_secret="$CLIENT_SECRET" \
-d scope=oneapi:access
# 2. Decode a VIN (token from step 1)
curl "https://api-test.vitu.com/one/vindecoder/api/v1/decode?vin=1HGCM82633A004352&state=CA" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Refer to the spec for the exact query parameters, response schema, and status codes.
3. Authentication & Access Walkthrough
The API uses a single security scheme, oneVituOauth — the OAuth 2.0 client-credentials grant. There is no user-interactive flow and no alternative scheme; if you expected authorization-code or API-key options, they do not apply here. See securitySchemes in the spec for the formal definition, including the token URL and the oneapi:access scope.
Obtaining credentials
Client credentials are issued by Vitu and retrieved from the Key Management area within Vitu's Developer Portal. Treat the client secret as confidential; do not embed it in client-side code.
Obtaining and attaching a token
- Request a token from the scheme's token endpoint using the client-credentials grant and the
oneapi:accessscope. - Attach the returned token as a bearer credential on the
Authorizationheader of each API request.
Token lifecycle
- Access tokens expire. Cache and reuse a token until shortly before expiry rather than requesting one per call.
- There is no refresh token in the client-credentials grant; when a token expires, request a new one using your credentials.
- On an authentication failure (the unauthenticated response class), obtain a fresh token once and retry. If a valid token still yields an authorization failure (the forbidden response class), the credentials lack the required permission — do not retry; resolve access with Vitu.
4. Key Concepts & Glossary
| Term | Meaning |
|---|---|
| VIN | The 17-character Vehicle Identification Number that is the sole required input to the decode operation. The spec enforces the character set and length via pattern. |
| Decoded-VIN result | The output of the decode operation (VinDecoded), containing both a raw view and a state view. |
| Raw values | Decoded attributes independent of any jurisdiction (VinDecodedRawInfo). Fields are primarily plain text and numeric values. |
| State values | Decoded attributes normalized to a specific state's reference data (VinDecodedInfo). Certain fields carry coded lookup values instead of free text. |
| Lookup value | A structured code-plus-description pair (LookupValueDTO) used for state-normalized fields such as make, body type, motive power, and vehicle type. Use the description for display and the code for programmatic matching against state reference data. |
| State | A U.S. state code selecting which state's reference data the state view is normalized against. Optional; defaults to CA. Valid values are enumerated in StateEnum. |
| Location ID | An optional Vitu location identifier supplied via the x-location-id header. Its effect on decode behavior is not described in the spec (see flag below). |
Relationships
There are no parent/child resources or lifecycle states in this API. Each decode call is independent and stateless: input a VIN, receive a result. The only structural relationship is within the result — raw and state views describe the same vehicle from two perspectives, and state-view lookup fields pair a code with its description.
5. Common Use Cases & Integration Patterns
The API exposes one operation, so integration patterns center on how you request and consume the decode result.
Scenario A - Basic VIN decode
Goal: Turn a VIN into vehicle attributes.
- Obtain a token (Section 3).
- Call
decodeVinwith the VIN. - Read the raw values view for jurisdiction-neutral vehicle facts.
Use this when you need general vehicle attributes and do not care about a specific state's classification.
Scenario B - State-normalized decode
Goal: Obtain vehicle attributes aligned to a specific state's reference data.
- Obtain a token.
- Call
decodeVinwith the VIN and the targetstate. - Read the state values view, resolving coded lookup fields via their code/description pairs.
Use this when downstream processing (e.g., registration or titling workflows) requires state-specific classifications. If state is omitted, the state view defaults to CA.
Recommended patterns
- Synchronous only. The decode operation is a single synchronous request/response. There are no async jobs, callbacks, or webhooks.
- Cache by VIN (and state). A VIN's decoded attributes are stable; caching results keyed by VIN (and state, when supplied) reduces call volume and helps stay within rate limits.
- Validate before calling. Enforce the VIN character-set and length constraints (defined in the spec) client-side to avoid avoidable validation failures.
6. Behavioral & Operational Notes
- Read-only and stateless. The decode operation has no side effects and creates no resources. Repeated calls with the same input are safe and return equivalent results (subject to reference-data updates).
- Two views, possibly divergent. Raw and state views are independent representations. Expect a field present in one view to be absent or differently typed in the other — for example,
makeis free text in the raw view but a lookup value in the state view. Do not assume field parity across views. - State defaulting. Omitting
stateyields aCA-normalized state view rather than an error. If you need an explicit jurisdiction, always sendstate. - Sparse results are normal. Not every attribute can be derived from every VIN. Treat missing fields as "unknown," not as an error, and code defensively for absent values.
7. Environments
Three environments are available, selected by the environment segment of the base URL (see the spec's servers block): production, staging, and test. Use the non-production environments for integration and validation before promoting to production.
8. Rate Limiting & Quotas
The API enforces rate limiting: exceeding the allowed volume returns the too-many-requests response class (TooManyRequests). The spec's description of that response indicates callers should retry after the window resets.
9. Error Handling & Troubleshooting
Errors are returned using the spec's error schema (Errors, an array of Error objects, each carrying a message). Handle failures by class rather than by specific code, since codes and messages may evolve.
| Failure class | Meaning | Retryable? | Action |
|---|---|---|---|
| Validation (bad-request class) | Input failed validation (e.g., malformed VIN, invalid state). | No | Fix the request; validate VIN format client-side first. |
| Unauthenticated | Missing/expired/invalid token. | Once | Obtain a fresh token, retry once. |
| Forbidden | Authenticated but lacking permission. | No | Resolve access scope with Vitu. |
| Rate-limited (too-many-requests class) | Rate limit exceeded. | Yes | Back off and retry after the window resets. |
| Server error | Server-side failure. | Yes (cautiously) | Retry with exponential backoff; escalate if persistent. |
Backoff convention: for retryable classes, use exponential backoff with jitter and a bounded maximum attempt count. Stop retrying on any non-retryable class.
10. Support & Resources
For any API assistance, contact Vitu's API support team at [email protected].