TitleRead

API

One endpoint to send a file, one to get the result. Everything is JSON. Base URL: https://titleread.com

Authentication

Every request carries your API key: Authorization: Bearer ts_live_…. Keys are created in the dashboard and can be revoked there.

Send a document

curl -X POST https://titleread.com/v1/documents \
  -H "Authorization: Bearer $TITLE_API_KEY" \
  -F "file=@packet.pdf" \
  -F 'options={"context":{"lot_number":"45123456"},"metadata":{"order":"A-1001"},"webhook_url":"https://your-app/hooks"}'

Or send the bytes directly with Content-Type: application/pdf and an X-File-Name header. PDF, JPEG, PNG, WebP; up to 50 MB; any number of pages and documents in one file.

Response 202: {"id":"…","status":"queued"}. One credit is charged per vehicle — a group of pages sharing a VIN that has a title or a bill of sale — when the read completes. Pages without a title or bill of sale are free.

options, all optional: context.lot_number (an auction lot number printed on a sticker is then never mistaken for the title number), context.vin, context.state; metadata (anything, returned with the result and in webhooks); webhook_url (overrides the account setting for this document).

Get the result

curl https://titleread.com/v1/documents/ID -H "Authorization: Bearer $TITLE_API_KEY"

status moves queued → processing → completed or failed. A completed result has:

A document that could not be read has failure.reason: CORRUPTED_DOCUMENT (rescan it), NO_PAGES_DETECTED, PROVIDER_ERROR. A page the model answered badly has extraction.failure.reason such as TRUNCATED or BLOCKED, and rawText to inspect.

Webhooks

Set a URL in the dashboard (or per document). We POST {"id":"evt_…","event":"document.completed","data":{"id":"…","status":"completed","documents":2,"metadata":{…}}} and retry with backoff for up to eighteen hours. The URL must be public and use HTTPS. The X-Title-Signature header is t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, t + "." + body); reject anything older than five minutes.

Other calls

GET /v1/documents?limit=50&before=…your documents, newest first, without results
GET /v1/documents/ID/pages/N.pnga rendered page, for your own review screens
POST /v1/documents/ID/corrections{"documentIndex":0,"fieldPath":"titleNumber","oldValue":"…","newValue":"…"} — what a person changed; it improves the service
POST /v1/documents/ID/reprocessread it again (charged again)
DELETE /v1/documents/IDremove the result and the file now, ahead of retention
GET /v1/usage, GET /v1/meuploads, vehicles read, credits

Limits and errors

120 requests per minute per key (429). 401 bad key, 402 no credits, 413 too large, 415 wrong type, 404 not yours or gone. Errors are {"error":"code","message":"…"}.