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

  1. Get a token. Exchange your client credentials for an access token using the client-credentials grant (see Authentication).
  2. 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.
  3. 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.
  4. Retrieve derived data. Once processing has advanced, read generated documents (GetTransactionForms) and calculated fees (GetTransactionFees).
  5. Commit. When ready to finalize, call CommitTransaction with 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

  1. POST your client_id, client_secret, grant_type=client_credentials, and the oneapi:access scope to the token endpoint defined in the spec's security scheme.
  2. Attach the returned token to every API request as a bearer token in the Authorization header.

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 retry 403 by re-authenticating; a 403 means 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

TermMeaning
TransactionThe core resource: one title/registration submission for one vehicle in one jurisdiction. Its payload shape is state-specific.
Transaction typeClassifies 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 IDThe integer identifier for a transaction. Resolvable from a reference number via the utility operation.
VehicleThe state-specific vehicle sub-object within a transaction, selected by the same state discriminator.
Trade-in vehicleOptional state-specific vehicle(s) applied against taxable value. Present on many state variants.
Form / documentA generated DMV document produced by a transaction. Listable and downloadable (as PDF), individually or in bulk.
FeeA calculated charge produced by a transaction (state fees, taxes, vendor fees, etc.).
Finalize / commitThe act of finalizing a transaction, supplying shipping and (optionally) plate-destination and signer details.
SignerA participant in the e-signature flow, indexed by signer number (owner = 1, co-owner = 2).
CallbackAn optional server-to-server notification delivered to a callbackUrl you supply, reporting status changes.
Universal status / transaction statusState 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

  1. CreateTransaction — submit the state-specific transaction body. Processing is asynchronous.
  2. Correlate the result — from the create response and/or via GetTransactionIdByRefNumber if you hold only the reference number.
  3. GetTransactionFees — read calculated fees once available.
  4. GetTransactionForms — list generated documents once available.
  5. DownloadTransactionForms / DownloadTransactionDocument — retrieve the PDF(s).
  6. 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

  1. InitiateSign — start the flow, providing sender and signer (owner/co-owner) participant details.
  2. GetSignLink — retrieve a signing URL for a given signer number, to embed or forward.
  3. ResendSignInvitation — re-send the invitation email to a signer if needed.
  4. CancelSign — cancel the sign request (with a required reason); optionally delete already-signed documents.
  5. 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 CallbackDTO variant.
  • 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. The state discriminator 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:

  1. You submit a mutating request with a network-accessible HTTPS callbackUrl.
  2. VITU processes asynchronously and POSTs one or more status-change notifications to your URL.
  3. 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:

ClassMeaningRetryable?Strategy
Auth (unauthenticated)Missing/expired/invalid token.Yes, onceObtain a fresh token, retry once. If it persists, treat as a credentials/config problem.
Auth (forbidden)Authenticated but not permitted for this API/resource.NoDo not re-auth-loop. Verify entitlements with VITU.
ValidationMalformed or non-compliant request (wrong shape for the state, missing required fields).NoFix the payload; inspect the returned error messages. Re-submitting unchanged will fail again.
Not foundThe referenced transaction/resource does not exist (or not yet).ConditionallyIf the resource may not yet be created/processed, back off and retry; otherwise treat as terminal.
Rate limitToo many requests; window exceeded.YesBack off and retry after the window resets (see below).
ServerTransient server-side failure.YesRetry 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].