Overview
Cardinal Gray dispatches webhook notifications to your endpoint whenever a title entry undergoes a state change that matches your subscribed events. Webhooks are sent asPOST requests with the full title entry as the JSON body.
To configure a webhook endpoint, contact the Cardinal Gray team. You’ll need to provide your endpoint URL and choose an authentication scheme.
Authentication
Cardinal Gray supports two outbound authentication schemes for webhook delivery:Basic Auth
Authorization header contains a Base64-encoded username:password pair. This is the recommended scheme for new integrations.
Bearer Token (Legacy)
Authorization header and/or an x-partner-key header. New integrations should use Basic Auth.
Subscribable Events
| Event | Fires When |
|---|---|
title.job_status.complete | Entry processing finishes successfully (job_status transitions to complete) |
title.job_status.error | Entry processing fails terminally (job_status transitions to error) |
title.data.found | New enrichment data is discovered (NMVTIS, public portal, or private state pull transitions from not_found → found) |
title.data.not_found | Reserved for future use |
title.account_status.* | Any account_status field change (wildcard — fires for all transitions) |
Account Status Lifecycle
Thetitle.account_status.* event fires with the specific new status appended. Possible values:
Payload Shape
The webhook payload is aPOST request with Content-Type: application/json. The body is the full title entry (identical to GET /title/{id} response) plus a webhook_events array indicating which subscribed events triggered this dispatch.
Example Webhook Payload
Key Fields
| Field | Type | Description |
|---|---|---|
entryId | string | Unique identifier for the title entry |
website | string | Organization identifier |
VIN | string | Vehicle Identification Number |
state | string | Target state for title processing |
job_status | enum | Processing status: pending, input_parsing, enriching, generating_forms, complete, error |
account_status | enum | Lifecycle status (see Account Status Lifecycle above) |
account_data | object | Structured vehicle, loan/sale, and owner data (see Core Ontology) |
nmvtis_found_status | enum | NMVTIS enrichment result: pending, found, not_found, error, unavailable, skipped |
state_found_status | enum | State/private enrichment result (same enum as above) |
signature_requests | array | Signing ceremony status (DocuSign, Notarize, etc.) |
fee_estimate | object | Calculated DMV fees (tax, registration, title) |
webhook_events | string[] | Which subscribed events triggered this webhook delivery |
S3 document paths (
nmvtis_pull, state_pull, form_* fields) are delivered as presigned URLs valid for 1 hour. Download or process them promptly.Delivery Semantics
- Method:
POST - Content-Type:
application/json - Retry: Exponential backoff on 5xx responses (up to 3 retries)
- Timeout: 10 second response timeout per attempt
- Idempotency: The same event may be delivered more than once. Use
entryId+webhook_eventsto deduplicate.
Success / Failure
| Your Response | Our Behavior |
|---|---|
2xx | Delivery confirmed, no retry |
4xx | Client error logged, no retry (fix your endpoint) |
5xx | Retried with exponential backoff |
| Timeout | Treated as 5xx, retried |
Testing
To trigger a test webhook:- Create a title entry via
POST /titlewith enrichment enabled (sync_nmvtis: true) - Wait for
job_statusto reachcomplete— this firestitle.job_status.completeand potentiallytitle.data.found - Update
account_statusvia the dashboard or signing flow to triggertitle.account_status.*events
2xx. Contact the Cardinal Gray team if you need help debugging delivery issues.