Lien Add - Developer Guide
1. Overview & Introduction
The VITU National API automates motor-vehicle title and registration processing across U.S. jurisdictions. Rather than integrating separately with each state DMV, you submit a single structured transaction to VITU and receive back the generated forms, calculated fees, and status updates that flow from downstream processing.
The central noun is the transaction. A transaction represents one title/registration submission for one vehicle in one jurisdiction. Its shape is state-specific: the request body resolves to a per-state variant selected by a discriminator (state), and each variant carries its own vehicle model, fee inputs, plate/use/exemption enumerations, and required fields. The same discriminator pattern applies to the vehicle sub-object. This means the "same" operation accepts materially different payloads depending on the jurisdiction — consult the spec's BaseTransactionDTO variants for the target state.
A transaction also has a transaction type (see TransactionTypeEnum) that governs how it is routed and processed. A transaction produces two derived artifacts you can retrieve: forms (generated documents, downloadable as PDF) and fees (calculated charges). Some transactions additionally support an e-signature flow, in which one or more signers (owner, co-owner) sign generated documents before the transaction is committed.
The base URL is environment-templated: a single host pattern with an {env} variable selects production or one of the lower environments. The spec defines the available environment values; see Environments. All operations require an OAuth 2.0 access token.
Sensitive-data note: Transactions carry personally identifiable information (owner names, addresses, VINs) and financial detail (fees, payment terms). Generated forms are legal DMV documents. Treat all request/response payloads and downloaded PDFs as sensitive; see Data sensitivity.
2. Getting Started / First Call
Prerequisites
- OAuth 2.0 client credentials (Client ID and Client Secret). These are obtained from the Key Management area within Vitu's Developer Portal.
- The ability to reach the token endpoint and the API host over HTTPS.
Shortest path to a successful call
- Get a token. Exchange your client credentials for an access token using the client-credentials grant (see Authentication).
- Create a transaction. Call the create operation (
CreateTransaction) with a state-appropriate transaction body. The response is asynchronous (accepted for processing), and it returns a reference by which you can later address the transaction. - Resolve the numeric ID (if needed). If you were given a reference number (UUID) on create and need the integer transaction ID, use
GetTransactionIdByRefNumber. Note that transaction-scoped operations accept either the integer ID or the UUID reference number in the path. - Retrieve derived data. Once processing has advanced, read generated documents (
GetTransactionForms) and calculated fees (GetTransactionFees). - Commit. When ready to finalize, call
CommitTransactionwith the required finalize/shipping information.
Minimal example (token → create)
# 1. Obtain 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. Create a transaction (body shape is state-specific; see spec)
curl -X POST "https://api.vitu.com/national-public-api/v2/transaction" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data @transaction-body.json
The exact fields of transaction-body.json depend on the target state and transaction type; build it from the appropriate BaseTransactionDTO variant in the spec.
3. Authentication & Access Walkthrough
All operations are protected by the OAuth 2.0 client-credentials grant. The formal security scheme is defined in the spec as keycloak, requiring the oneapi:access scope. Do not treat any operation as anonymous — every path in this product declares this requirement.
Obtaining credentials
Client ID and Client Secret are issued through the Key Management area within Vitu's Developer Portal. The Client ID is a public identifier; the Client Secret is private and must never be embedded in client-side code or committed to source control.
Obtaining and attaching a token
- POST your
client_id,client_secret,grant_type=client_credentials, and theoneapi:accessscope to the token endpoint defined in the spec's security scheme. - Attach the returned token to every API request as a bearer token in the
Authorizationheader.
Token lifecycle
- Tokens expire. Cache a token and reuse it until shortly before expiry, then request a new one. (The spec does not publish a fixed lifetime; rely on the token response's expiry field rather than hard-coding a value.)
- The client-credentials grant has no refresh token — on expiry, request a new token with the same credentials.
- On a
401, treat the token as invalid or expired: obtain a fresh token and retry once. Do not retry403by re-authenticating; a403means the authenticated client lacks permission (see Error handling).
Environment differences
The token endpoint and API host are environment-specific. Use the token endpoint matching the environment whose host you are calling. Only one authentication scheme exists for this API — there is no API-key or basic-auth alternative.
Acting on behalf of a user
Most operations accept an optional header identifying a user on whose behalf the request is made (x-on-behalf-of-user). Use it when your integration acts for a specific end user; omit it otherwise. See the spec for the exact header name and type.
4. Key Concepts & Glossary
| Term | Meaning |
|---|---|
| Transaction | The core resource: one title/registration submission for one vehicle in one jurisdiction. Its payload shape is state-specific. |
| Transaction type | Classifies routing/processing of a transaction (TransactionTypeEnum). Passed as a query parameter on transaction operations. |
| Reference number (refNumber) | A UUID returned on creation. Can be used interchangeably with the integer transaction ID on transaction-scoped paths. |
| Transaction ID | The integer identifier for a transaction. Resolvable from a reference number via the utility operation. |
| Vehicle | The state-specific vehicle sub-object within a transaction, selected by the same state discriminator. |
| Trade-in vehicle | Optional state-specific vehicle(s) applied against taxable value. Present on many state variants. |
| Form / document | A generated DMV document produced by a transaction. Listable and downloadable (as PDF), individually or in bulk. |
| Fee | A calculated charge produced by a transaction (state fees, taxes, vendor fees, etc.). |
| Finalize / commit | The act of finalizing a transaction, supplying shipping and (optionally) plate-destination and signer details. |
| Signer | A participant in the e-signature flow, indexed by signer number (owner = 1, co-owner = 2). |
| Callback | An optional server-to-server notification delivered to a callbackUrl you supply, reporting status changes. |
| Universal status / transaction status | State fields on callbacks/results that report processing progress. |
Resource relationships & lifecycle
- A transaction is created first and is the parent of everything else. Forms and fees are derived from a transaction and only become meaningful once processing has produced them.
- Commit is a lifecycle transition applied to an existing transaction. It requires the transaction to exist and be in a committable state.
- The e-sign flow is a sub-lifecycle on a transaction: initiate → (retrieve signer links / resend invitations) → signing occurs externally → the transaction proceeds. Cancelling the sign flow is a distinct operation from cancelling the transaction.
- A transaction can be updated or cancelled while in an appropriate state.
5. Common Use Cases & Integration Patterns
Use case A - Submit a transaction and retrieve its outputs
CreateTransaction— submit the state-specific transaction body. Processing is asynchronous.- Correlate the result — from the create response and/or via
GetTransactionIdByRefNumberif you hold only the reference number. GetTransactionFees— read calculated fees once available.GetTransactionForms— list generated documents once available.DownloadTransactionForms/DownloadTransactionDocument— retrieve the PDF(s).CommitTransaction— finalize with shipping (and plate-destination/signer info as required).
Ordering: Fees and forms are only meaningful after the transaction has been processed enough to generate them. Do not assume they are immediately available after create.
Use case B - Update or cancel before finalizing
UpdateTransaction— modify an in-progress transaction (full state-specific body).CancelTransaction— cancel an in-progress transaction, optionally with a message.
These apply to transactions not yet finalized; cancellability depends on current state.
Use case C - E-signature flow
InitiateSign— start the flow, providing sender and signer (owner/co-owner) participant details.GetSignLink— retrieve a signing URL for a given signer number, to embed or forward.ResendSignInvitation— re-send the invitation email to a signer if needed.CancelSign— cancel the sign request (with a required reason); optionally delete already-signed documents.- After signing completes, proceed to commit as in Use case A.
Async & notification pattern
The mutating operations (create, update, cancel, commit) return an accepted-for-processing response rather than a completed result, and they support an optional callback (callbackUrl) that receives status-change notifications. Recommended pattern:
- Prefer callbacks for status transitions where you can host a network-accessible HTTPS endpoint. Callbacks are delivered as POSTs carrying a
CallbackDTOvariant. - Fall back to polling the transaction's forms/fees (and any status you receive) where you cannot host a callback endpoint.
See Asynchronous & callback patterns.
6. Behavioral & Operational Notes
- Asynchronous acceptance. Create, update, cancel, and commit are accepted asynchronously. A successful response means the request was accepted for processing, not that processing has completed. Determine completion from callback notifications or status fields, not from the acceptance response alone.
- ID/reference interchangeability. Transaction-scoped paths accept either the integer transaction ID or the UUID reference number in the same path position. Choose one consistently to avoid confusion in logs.
- State-specific payloads. Because the request body and vehicle object are discriminated by
state, a payload valid for one state will generally be invalid for another. Thestatediscriminator determines which variant (and which required fields and enums) applies. - Update semantics. The update operation takes a full state-specific transaction body. Whether it replaces or merges is not stated in the schema — assume replace semantics for the submitted body and send a complete representation unless VITU confirms otherwise. (Flagged — confirm with VITU.)
- Forms/fees availability is time-dependent. These lists may be empty until processing generates content. Treat an empty list as "not yet produced," not as an error.
- Callback signing. When an HMAC key is configured for callbacks, callback payloads are signed (HMAC/SHA-256, base64-encoded) so you can verify authenticity. The spec's callback description is truncated on the exact header/format — confirm the signature header name and canonicalization with VITU before enforcing verification.
- Blank-form generation. Document download supports generating a blank form variant. Use this only when you need an unfilled template rather than the transaction's populated document.
7. Environments & Sandbox Access
The API host is templated with an environment variable that selects among a production environment and lower (staging/test) environments; the spec's servers block enumerates the valid values. Use a lower environment for integration and testing, and the production environment only for live submissions.
Each environment has its own OAuth token endpoint — always authenticate against the token endpoint matching the environment you are calling. Credentials appropriate to each environment are issued via the Key Management area; contact VITU if you need access to a specific environment.
8. Asynchronous / Callback Patterns
Mutating operations support an optional callbackUrl query parameter. When supplied, VITU POSTs status-change notifications to that URL. The callback body is a CallbackDTO, which is a discriminated union (by callbackType) covering success, failure, and processing-channel-specific variants — consult the spec for the variant shapes.
Conceptual flow:
- You submit a mutating request with a network-accessible HTTPS
callbackUrl. - VITU processes asynchronously and POSTs one or more status-change notifications to your URL.
- Your endpoint acknowledges with a success response so VITU knows the callback was accepted.
Correlation: Callback payloads carry identifiers (transaction ID, VIN, and status fields) to correlate an event back to the originating transaction. Persist your transaction ID / reference number at create time and match incoming callbacks against it.
Delivery/authenticity: When an HMAC key is configured, callbacks are signed so you can verify them. Retry/back-off behavior for callback delivery is not specified — confirm with VITU whether failed callback deliveries are retried and design your endpoint to be idempotent regardless.
9. Pagination Conventions
List operations (forms, fees) use a cross-cutting limit/offset convention via shared query parameters (limit, offset). The default page size and bounds are defined in the spec's shared parameters — read them from the spec rather than hard-coding. To page through results, increment offset by your chosen limit until a page returns fewer items than requested.
10. Error Handling & Troubleshooting
Error responses use the spec's error schema (Errors, an array of Error messages). Handle by class, not by memorizing specific codes:
| Class | Meaning | Retryable? | Strategy |
|---|---|---|---|
| Auth (unauthenticated) | Missing/expired/invalid token. | Yes, once | Obtain a fresh token, retry once. If it persists, treat as a credentials/config problem. |
| Auth (forbidden) | Authenticated but not permitted for this API/resource. | No | Do not re-auth-loop. Verify entitlements with VITU. |
| Validation | Malformed or non-compliant request (wrong shape for the state, missing required fields). | No | Fix the payload; inspect the returned error messages. Re-submitting unchanged will fail again. |
| Not found | The referenced transaction/resource does not exist (or not yet). | Conditionally | If the resource may not yet be created/processed, back off and retry; otherwise treat as terminal. |
| Rate limit | Too many requests; window exceeded. | Yes | Back off and retry after the window resets (see below). |
| Server | Transient server-side failure. | Yes | Retry with exponential backoff; stop after a bounded number of attempts. |
Backoff convention: For retryable classes (rate-limit, server), use exponential backoff with jitter, capped at a small number of attempts. For rate-limit responses specifically, wait for the limit window to reset before retrying rather than retrying immediately.
Diagnosing validation errors: Because request shape is state-specific, most validation failures stem from sending a payload that doesn't match the target state's variant or omits its required fields. Confirm the state discriminator and required fields against the correct BaseTransactionDTO variant.
11. Data Sensitivity & Compliance Notes
Transactions and their generated forms contain PII (names, addresses, VINs) and financial data, and the PDFs are official DMV documents. Handling expectations:
- Transmit only over HTTPS (enforced by the API and required for callbacks).
- Do not log full request/response bodies or downloaded documents in plaintext; redact PII where you must log.
- Store Client Secrets and access tokens securely; never expose them client-side.
- Restrict access to downloaded forms to authorized users, and dispose of cached PDFs when no longer needed.
This is guidance on handling, not legal advice. Confirm any jurisdiction-specific retention or disclosure obligations with VITU and your own counsel.
12. Support & Resources
For any API assistance, contact Vitu's API support team at [email protected].