Motor Vehicle Record (MVR) Verification - Developer Guide


1. Overview & Introduction

The MVR Verification API lets you submit an inquiry against a state motor vehicle authority and retrieve the resulting record for a vehicle — identity, title, registration, ownership, and lien/lease details — for permissible-use screening and verification.

The core domain noun is the inquiry. You create an inquiry describing what you want to look up (an identifier such as a VIN, plate, or title number) and the state the lookup targets. Each state has its own inquiry shape: the spec models this with a discriminated union (StateInquiryDTO) keyed on the state property, so a California inquiry and a Wisconsin inquiry carry different state-specific fields on top of a common base (InquiryDTO). The state discriminator determines which additional fields are valid.

Once created, an inquiry is identified two ways: by a server-assigned inquiry ID (integer) and by a client-visible reference number (refNumber, a UUID). Inquiry processing is asynchronous — creation returns an identifier, and the record is populated once the state authority responds. You retrieve results either as a state inquiry record (the inquiry and its state-specific data), a unified vehicle record (MVRBaseRecordDTO, a normalized cross-state shape), or a PDF printout.

The API is served across three environments — production, staging, and test — selected via the server's env variable (see the spec's servers block for exact URLs). All environments use OAuth 2.0 client-credentials authentication.

Sensitive data. Responses include personally identifiable information (owner names, dates of birth, driver license numbers, addresses, and — for some states — SSN in the request). Handle all inquiry data as regulated PII. See Data Sensitivity & Compliance.


2. Getting Started / First Call

Prerequisites

  • OAuth 2.0 client credentials issued by Vitu. Obtain these from the Key Management area within Vitu's Developer Portal.
  • The ability to reach the target environment's base URL (see the spec's servers block).
  • Familiarity with REST and the OAuth 2.0 client-credentials grant.

Happy path

  1. Obtain a token. Exchange your client credentials at the token endpoint defined in the spec's oneVituOauth security scheme, requesting the oneapi:access scope.
  2. Create an inquiry. Call the inquiry-creation operation (CreateInquiry) with a state-specific inquiry body. The state value selects the correct variant of StateInquiryDTO; supply the required base fields plus any state-specific fields the chosen variant defines. The response returns an inquiry ID.
  3. Retrieve the result. Because processing is asynchronous, poll one of the load operations (LoadInquiryById, LoadInquiryByRefNumber, or LoadUnifiedInquiryRecord) until the record indicates completion, or register a callback (see Asynchronous & Callback Patterns).

Refer to the spec for the exact request body, required fields per state, and response schemas.


3. Authentication & Access Walkthrough

Authentication uses the oneVituOauth security scheme (OAuth 2.0 client-credentials grant). The spec's securitySchemes block is the formal definition — token URL, grant type, and scope. This section covers only the operational mechanics.

Obtaining credentials

Client credentials are issued by Vitu and are available from the Key Management area within Vitu's Developer Portal. Treat the client secret as sensitive; do not embed it in client-side code.

Obtaining and attaching a token

  1. Request an access token from the token endpoint in the oneVituOauth scheme using the client-credentials grant and the oneapi:access scope.
  2. Attach the returned token as a bearer token on every API request. All operations in this API require oneVituOauth with oneapi:access.

Token lifecycle

  • Access tokens expire. Cache the token and reuse it until shortly before expiry, then request a new one. (Token lifetime is governed by the authorization server, not the spec — do not hard-code an assumed TTL.)
  • The client-credentials grant has no refresh token; re-request a new token when the current one expires.
  • On an authentication failure response, obtain a fresh token and retry once. If it recurs, treat it as a credential/permission problem rather than retrying in a loop. See Error Handling.

Environment differences

Each environment (production, staging, test) is a separate base URL selected by the env server variable. Credentials are environment-scoped; use the credentials issued for the environment you are calling.

Only one scheme

This API defines a single security scheme. There is no API-key or alternative auth path; all access is via oneVituOauth.


4. Key Concepts & Glossary

TermMeaning
InquiryA request to look up a vehicle record from a state authority. The central resource of the API.
State inquiry (StateInquiryDTO)The inquiry payload, specialized per U.S. state via a discriminator on state. The base fields (InquiryDTO) are common; each state variant adds its own optional or required fields.
Inquiry type (InquiryTypeEnum)How the vehicle is identified for lookup — e.g. by VIN, plate, or title. The enum in the spec is authoritative; the schema's _enumCount indicates more values exist than are shown inline.
Inquiry IDServer-assigned integer identifier for an inquiry. Used by the load, unified-record, and report operations.
Reference number (refNumber)Client-visible UUID identifying an inquiry. Set on creation and usable to load the inquiry independently of the inquiry ID.
Unified vehicle record (MVRBaseRecordDTO)A normalized, cross-state representation of the result, grouping vehicle, title, owner, co-owner, lienholder, lessor, and registration data.
State (MvrStateEnum)The jurisdiction targeted by the inquiry and the discriminator that selects the inquiry variant. The spec's _enumCount (44) indicates the enum is larger than the inline sample; use the spec's mapping in StateInquiryDTO for the full supported set.

Relationships and lifecycle

  • An inquiry is created first; everything else references it by inquiry ID or reference number.
  • The inquiry moves from created to processed asynchronously. The base inquiry carries read-only createdDate, processedDate, charged, and error fields that reflect this lifecycle — inspect these to determine state rather than assuming completion on creation.
  • The unified record and the PDF report are derived views of a processed inquiry; they are meaningful only after the state authority has responded.

Optional request context headers

The creation operation accepts optional context headers (a VITU location ID and an on-behalf-of user ID). These scope or attribute the request; see the spec for their names and types. They are not required for a basic call.


5. Common Use Cases & Integration Patterns

Use case A - Look up a vehicle record and read the result

  1. CreateInquiry — submit the state-specific inquiry. Capture the returned inquiry ID (and retain your refNumber).
  2. Wait for processing to complete (poll or callback).
  3. LoadUnifiedInquiryRecord — retrieve the normalized cross-state record when you want a consistent shape regardless of state.

Use the unified record when your integration must handle many states uniformly.

Use case B - Retrieve the raw state inquiry

  1. CreateInquiry.
  2. LoadInquiryById or LoadInquiryByRefNumber — retrieve the inquiry and its state-specific fields, including the read-only lifecycle fields (processedDate, charged, error).

Use LoadInquiryByRefNumber when you track requests by your own UUID; use LoadInquiryById when you hold the server-assigned integer.

Use case C - Produce a shareable/printable record

  1. CreateInquiry, then wait for completion.
  2. GetPrintout — retrieve the record as a PDF for archival or downstream review.

Ordering and dependency rules

  • All retrieval operations depend on a prior successful CreateInquiry.
  • Retrieval before processing completes will return an inquiry that is not yet populated (check processedDate/error) — the read itself may succeed while the result is still pending.
  • Choose one correlation key (inquiry ID or refNumber) and use it consistently.

Poll vs. callback

The creation operation supports a callback (see Asynchronous & Callback Patterns). Prefer the callback where your infrastructure can receive it; fall back to polling one of the load operations otherwise.


6. Behavioral & Operational Notes

  • Asynchronous completion. CreateInquiry returns an identifier, not a finished record. A successful creation response does not mean the state lookup is done. Determine completion from the inquiry's read-only processedDate (and check error) — not from the HTTP status of the create call.
  • State-conditional request validity. The valid set of request fields depends on the state discriminator. Fields accepted for one state's variant are not accepted for another. Some states impose additional required fields beyond the common base (for example, one state variant marks a company identifier as required). Consult the specific variant in StateInquiryDTO.
  • Two identifiers, one inquiry. Inquiry ID and refNumber refer to the same inquiry. Loading by either returns equivalent data.
  • Billing signal. The read-only charged field on the inquiry indicates whether the inquiry was billable. Do not infer billing from success/failure alone.
  • Partial results. The unified record groups multiple optional sections (owner, co-owner, lienholder, lessor, etc.). Any section may be absent depending on what the state returns; treat all sections as optional and null-safe.
  • State-specific search semantics. Some state variants define their own search rules — for example, one state's customer search may be satisfied by license number, SSN, or a name-plus-date-of-birth combination. Honor the per-variant description in the spec.

7. Asynchronous / Callback Patterns

The creation operation defines a callback (transactionCompleted) delivered to a caller-supplied callbackUrl. This is the recommended way to learn that an inquiry has finished processing.

  • Flow. You supply a callback URL when creating the inquiry; when processing completes, Vitu POSTs a notification (CallbackDTO) to that URL.
  • Correlation. The callback payload carries both refNumber and inquiryId, plus a processedDate and an error field. Correlate the notification to your original request using refNumber (your UUID) or inquiryId.
  • After notification. On receipt, call a load operation or LoadUnifiedInquiryRecord to fetch the full result.
  • Fallback. If you cannot receive callbacks, poll a load operation and check processedDate/error.

Corresponding MVR Notifications product: The Motor Vehicle Record Verification Notifications product serves as a complementary offering to this MVR verification service. Together, the inquiry and notification capabilities provide a complete ecosystem for both initiating vehicle record verification requests and staying informed of relevant updates through secure, automated notifications. See that product in the Catalog for more details.


8. Rate Limiting & Quotas

Every operation can return a rate-limit response (the spec's shared TooManyRequests response). When you receive it:

  • Stop issuing new requests and back off before retrying (see the backoff convention in Error Handling).
  • Retry after the limit window resets.

9. Error Handling & Troubleshooting

Error responses (other than the binary PDF and the rate-limit case) use the spec's Errors schema — an array of Error objects, each carrying a human-readable message. Treat errors by class, not by hard-coded code, so this guidance survives spec changes.

ClassMeaningRetryable?Action
Auth (unauthenticated)Token missing, invalid, or expired.After refresh, onceObtain a fresh token and retry once. If it persists, verify credentials.
Auth (forbidden)Authenticated but lacks permission for the operation/resource.NoDo not retry. Verify scope/entitlements with the API owner.
ValidationMalformed request or invalid field combination — often a field not valid for the chosen state variant, or a missing required field.NoFix the request against the correct StateInquiryDTO variant. Read message for specifics.
Rate limitToo many requests.Yes, after backoffBack off and retry after the window resets.
ServerServer-side failure.Yes, with backoffRetry with exponential backoff; stop after a bounded number of attempts and escalate.

Backoff convention. For retryable classes, use exponential backoff with jitter and a capped maximum number of attempts. Do not retry non-retryable classes (validation, forbidden).

Inquiry-level errors vs. transport errors. A processed inquiry may itself carry an error value even when the HTTP call succeeded (the lookup failed at the state authority). Inspect the inquiry's read-only error field in addition to HTTP status.


10. Data Sensitivity & Compliance Notes

Inquiry requests and results contain regulated PII: owner and co-owner names, dates of birth, driver license numbers, addresses, and — in at least one state variant — SSN. Handling expectations:

  • Access this data only for permissible-use screening and verification consistent with your agreement with Vitu and applicable law.
  • Transmit and store results over encrypted channels; minimize retention of PII and the PDF printout.
  • Restrict access to inquiry results and credentials to authorized systems and personnel.

This is guidance on handling, not legal advice. Confirm your permissible-use obligations with the API owner and your compliance function.


11. Support & Resources

For any API assistance, contact Vitu's API support team at [email protected].