California (CA) Title & Registration - Developer Guide


1. Overview & Introduction

The California (CA) Title & Registration API submits and processes vehicle title and registration transactions with the California Department of Motor Vehicles (DMV), returning transaction status and confirmation data. It is designed for dealers, service providers, and platforms that need to originate DMV title/registration work programmatically rather than through manual data entry.

The central noun is the transaction: a single title and/or registration submission describing a vehicle, its owners, and the parties involved (seller, lessor, lessee, lienholder). A transaction carries a set of participant records (owner, co-owner, lessee, lessor, lienholder), a vehicle record, and registration details. As a transaction progresses it can produce forms (documents, downloadable as PDFs), and it moves through lifecycle states reported via status fields and asynchronous callbacks. Transactions are identified either by a numeric transaction id or by a UUID reference number (refNumber); most operations accept either interchangeably in the path.

The API is asynchronous by design. Submitting, updating, or committing a transaction is accepted for processing rather than completed inline — the operation acknowledges receipt, and the true outcome arrives later via callback (webhook) or is discoverable by re-reading transaction-derived resources. Developers should build around this model from the start rather than expecting a synchronous result.

Access is over HTTPS against a single environment-parameterized base URL, with three deployment environments (production and two non-production). See the spec's servers block for exact URLs and environment names. All access is authenticated via OAuth 2.0 client credentials; credentials are issued by Vitu.

Because the payloads contain regulated personal data — driver license numbers, names, addresses, and vehicle identifiers — treat all request and response bodies as sensitive. See Data sensitivity & compliance notes.

Corresponding Title & Registration Notifications product: The Title & Registration Notifications product serves as a complementary offering to this Title & Registration service. Together, the transaction and notification capabilities provide a complete ecosystem for both initiating vehicle transaction requests and staying informed of relevant updates through secure, automated notifications. See that product in the Catalog for more details.


2. Getting started / First call

Prerequisites

  • OAuth 2.0 client credentials issued by Vitu.
  • A confirmed target environment (start in a non-production environment).
  • A network-accessible HTTPS endpoint if you intend to receive status callbacks.

Obtain access

Credentials can be obtained from the Key Management area within Vitu's Developer Portal. These are the client credentials you will exchange for an access token.

Minimal happy path

  1. Get a token. Exchange your client credentials at the token endpoint defined by the keycloak security scheme, requesting the oneapi:access scope.
  2. Create a transaction. Call the transaction-creation operation (CreateTransaction) with a transaction body. Optionally pass a callbackUrl to receive status updates. The response acknowledges acceptance for asynchronous processing; capture the identifier/reference you use to address the transaction going forward.
  3. Track progress. Wait for a status-change callback (if you supplied a callbackUrl), or inspect transaction-derived resources such as forms.
  4. Retrieve forms. Once the transaction has produced documents, list them with the forms-listing operation (GetTransactionForms) and download a specific document with the document-download operation (DownloadTransactionDocument).
  5. Commit. When ready to finalize, call the commit operation (CommitTransaction) with the finalize body (shipping and, where applicable, plate-destination and signer details).

Refer to the spec for the exact request and response shapes of each operation. Do not hard-code field lists from this guide.


3. Authentication & Access Walkthrough

Authentication uses OAuth 2.0 client credentials. The formal definition lives in the spec under the keycloak security scheme; that scheme is the source of truth for the token URL, the grant type, and the available scope. This API exposes a single scope, oneapi:access, and a single security scheme — there is no alternative auth mechanism, so do not build for API keys or user-interactive flows.

Obtaining credentials. Client credentials are issued by Vitu and retrieved from the Key Management area of Vitu's Developer Portal.

Obtaining a token. Perform a client-credentials token request against the token endpoint declared in the keycloak scheme, requesting oneapi:access. You receive a bearer access token.

Attaching the token. Send the token as a bearer credential on every API request. Requests without a valid token are rejected as unauthorized; authenticated callers lacking permission are rejected as forbidden. (See the spec's 401 and 403 responses.)

Token lifecycle. Access tokens expire. Cache and reuse a token until shortly before expiry, then request a new one; do not fetch a fresh token per request. On an unauthorized failure for a previously working token, obtain a new token once and retry — do not loop.

On behalf of a user. Operations accept an optional x-on-behalf-of-user header identifying the user the request is made for. Use it only when your integration acts for a specific Vitu user; see the spec for its definition.


4. Key Concepts & Glossary

Transaction — The core resource: a title and/or registration submission. Created, updated, committed, and the parent of forms. Addressable by numeric id or UUID refNumber.

refNumber — A UUID reference for a transaction. Interchangeable with the numeric transaction id in operation paths and echoed in callbacks, making it the reliable key for correlating callbacks to your originating request.

transactionType — Distinguishes the processing lane (EVR, INTERSTATE, DMVDESK). An optional parameter on the shared operations and a discriminator concept across callbacks.

applicationType — The nature of the filing (e.g. title-and-registration, title-only). See the spec for the valid set; note the request body and the success-callback use overlapping-but-not-identical application-type enumerations (see note below).

serviceType — Selects the level of service (e.g. forms-and-fees vs. full service), affecting how far Vitu carries the transaction on your behalf.

Participants — Structured party records on a transaction: owner and optional co-owner; lessor, lessee1/lessee2 for leases; lienholder for financed vehicles; and seller. Which participants are meaningful depends on the sale/lease structure of the deal.

Vehicle — The vehicle/vessel record (VIN/HIN, make/model/year, weights, odometer, fuel/body type, etc.).

Form / document — A document produced by a transaction, listed via the forms operation and retrievable as a PDF via the download operation. A form can be flagged required/selected/signed and may carry a signing flow (e.g. Vitu e-sign or notary).

Finalize (commit) inputs — At commit time the transaction requires shipping details and, depending on the deal, plate destination and signer contact information.

Callback — An asynchronous notification POSTed to your callbackUrl when a transaction's state changes. The callback body is polymorphic, discriminated by callbackType (success, failure, invoiced, and type-specific variants). See Asynchronous / webhook / callback patterns.

Status fields — Several distinct status concepts exist: a transaction status, a "universal status," and type-specific statuses (e.g. deal status, EVR status). These are separate fields with separate meanings; consult the spec for each and do not conflate them.

Lifecycle (conceptual): create → (update) → produce/inspect forms → commit/finalize → terminal outcome reported by callback. A transaction may also be saved for later (draft) rather than driven straight to commit.

Note — application-type divergence. The request body's applicationType and the success-callback's applicationType are defined as different enumerations in the spec. Do not assume a value accepted on input appears verbatim on output. Treat them as related but independent value sets.

Note — status enum completeness. Several status enumerations in the spec declare an _enumCount larger than the values shown (e.g. transaction status, universal status, deal status). The listed values are not exhaustive. Always read the enum from the current spec rather than this guide, and code defensively for unlisted values.


5. Common Use Cases & Integration Patterns

Each scenario references operations by name. Consult the spec for request/response detail.

5.1 Submit a new title & registration transaction (async, callback-driven)

  1. CreateTransaction — submit the transaction body; supply a callbackUrl to receive updates. Store the returned identifier and your refNumber.
  2. Await callback — a status-change callback reports success/failure and carries refNumber for correlation.
  3. On success, proceed to forms and/or commit as your workflow requires.

Pattern: prefer callbacks over polling. If you cannot receive callbacks, fall back to reading transaction-derived resources (forms) as a progress signal, but callbacks are the intended mechanism.

5.2 Revise a transaction before finalizing

  1. UpdateTransaction — replace/adjust the transaction using the same identifier or refNumber.
  2. Await callback — confirm the update was accepted and processed.

Use this to correct data flagged by a prior failure callback before committing. See the behavioral note on replace-vs-merge semantics.

5.3 Retrieve and download produced documents

  1. GetTransactionForms — list the documents a transaction has produced; inspect required/selected/signed flags and any signing flow.
  2. DownloadTransactionDocument — download a specific document as a PDF by its document id. Use the blank option when you need an unfilled template rather than the populated form.

Pattern: documents appear as processing advances; do not expect a complete form set immediately after creation. Drive document retrieval off a callback or a reasonable delay, not an immediate follow-up call.

5.4 Finalize (commit) a transaction

  1. Ensure the transaction is complete and its forms/signing are in the expected state.
  2. CommitTransaction — submit finalize inputs (shipping required; plate destination and signer details as applicable). Use submitAsIs per the spec when you intend to finalize without further edits.
  3. Await callback — the terminal outcome (and downstream events such as invoicing) arrive asynchronously.

Ordering & dependencies: create precedes update/commit/forms; a transaction must exist before any operation addressing it by id/refNumber can succeed; forms exist only after the transaction has produced them; commit is the finalizing step and should follow data validation and form readiness.


6. Behavioral & Operational Notes

  • Asynchronous acceptance. Create, update, and commit acknowledge acceptance for asynchronous processing — the acknowledgement is not a completion signal. Determine real outcomes from callbacks or subsequently readable resources, not from the acknowledgement alone.
  • Eventual consistency. Forms and status changes materialize after processing. A resource read immediately after a write may not yet reflect the change.
  • Dual identifiers. Operations accept either the numeric transaction id or the UUID refNumber in the path. Pick one consistently; refNumber is the most reliable correlation key across callbacks.
  • Update semantics (replace vs. merge). The update operation takes the full transaction representation. The spec does not state whether omitted fields are preserved or cleared. Flag: treat update as a full replacement and send a complete body until Vitu confirms merge behavior.
  • Multiple status dimensions. Transaction status, universal status, and type-specific statuses evolve independently. Base decisions on the specific field relevant to your workflow (see §4 note on statuses).
  • Blank vs. populated documents. The document-download blank flag changes the artifact returned (template vs. filled). Set it deliberately.
  • Signing flows. A form may require signing via an e-sign or notary flow; a form's signed flag reflects state. Account for signing before treating a document set as complete.

7. Asynchronous / Callback Patterns

Flow. When you pass a callbackUrl on create/update/commit, Vitu POSTs a callback to that URL on status change (the spec's onStatusChange callback). Your endpoint must be HTTPS and network-accessible from Vitu's servers, and should return a success status promptly to acknowledge receipt.

Payload shape. The callback body is polymorphic, discriminated by callbackType (e.g. success, failure, invoiced, and type-specific variants). Branch on the discriminator and read the variant defined in the spec — do not assume a single fixed shape.

Correlation. Every callback carries refNumber; use it to tie the event back to the originating request. Success/failure variants also carry identifiers such as transaction id and VIN.

Security. The spec indicates callbacks may be signed using HMAC-SHA256 (base64-encoded) when an HMAC key is configured.

Corresponding Title & Registration Notifications product: The Title & Registration Notifications product serves as a complementary offering to this Title & Registration service. Together, the transaction and notification capabilities provide a complete ecosystem for both initiating vehicle transaction requests and staying informed of relevant updates through secure, automated notifications. See that product in the Catalog for more details.


8. Environments & Sandbox Access

The API exposes production and two non-production environments through a single environment-parameterized base URL (see the spec's servers block for exact names and URLs). Do all integration and testing against a non-production environment first; promote to production only after verifying end-to-end behavior including callback delivery.


9. Rate Limiting & Quotas

Responses carry rate-limit headers (RateLimit-Limit, RateLimit-Reset) and, when a request is throttled, a Retry-After header on the too-many-requests response. Read these headers rather than hard-coding assumptions — the spec does not publish fixed numeric quotas, and any limits may change.

Strategy: track remaining budget from the limit headers; on a throttle response, wait at least the Retry-After interval before retrying, then apply exponential backoff with jitter for subsequent retries. Do not retry tighter than the server-signaled reset.


10. Error Handling & Troubleshooting

Handle errors by class, not by memorizing individual codes (codes and messages drift; the spec is authoritative). Error response bodies use the spec's Errors/Error schema on the primary failures; some responses (auth, throttle) use a code/message object — consult the spec per operation.

ClassMeaningRetryable?Action
Authentication (401)Missing/expired/invalid tokenOnce, after re-authenticatingObtain a fresh token, retry once; if it persists, check credentials/scope
Authorization (403)Authenticated but not permittedNoDo not retry; verify entitlements with Vitu
Validation / bad request (400)Malformed or invalid payloadNo (not without changes)Inspect the error body, correct the data, resubmit
Not found (404)Unknown transaction/document, or not yet consistentConditionallyFor a freshly created resource, allow for eventual consistency and retry with backoff; otherwise verify the identifier
Rate limit (429)ThrottledYesHonor Retry-After, then exponential backoff with jitter
Server (5xx)Server-side failureYesRetry with exponential backoff and a bounded attempt cap

Backoff convention: exponential backoff with jitter; respect Retry-After when present; cap total attempts and surface a durable failure rather than retrying indefinitely. Never retry a 400/403 unchanged. For non-idempotent operations, see the idempotency flag in §6 before retrying.


11. Data Sensitivity & Compliance Notes

Payloads carry regulated personal and vehicle data: names, driver license numbers, residence/mailing addresses, email/phone, VIN/HIN, and DMV transaction identifiers. Handle accordingly:

  • Transmit only over TLS (the API and callbacks are HTTPS).
  • Minimize retention; store only what your workflow requires, and protect stored copies and downloaded PDFs.
  • Restrict access to tokens, credentials, and payloads on a need-to-know basis.
  • Treat callback endpoints as ingress points for sensitive data and secure them as such.

This is handling guidance, not legal advice. Specific DMV/regulatory obligations for CA title and registration data are outside the spec; confirm compliance requirements with Vitu and your own counsel.


12. Support & Resources

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