Skip to main content
POST
Document Reader

Authorizations

Authorization
string
header
required

Organisation API key, sent as Authorization: Bearer chk_live_….

  • chk_live_… — real inference, real credits, livemode: true.
  • chk_test_… — identical pipeline against the fixture backend, test credits, livemode: false.

Keys are stored hashed; only the prefix (chk_live_a1b2…) is ever displayed again. A key may be scoped to a subset of endpoint families — calling outside its scopes is a 403.

Headers

Idempotency-Key
string

Client-generated key (a UUID is ideal) making this POST safe to retry. The first request is executed and its response stored for 24 h; any replay with the same key returns that stored response with Idempotent-Replayed: true and bills nothing. Reusing a key with a different payload is a 409 idempotency_key_reuse.

Required string length: 8 - 255
X-Carhub-Test-Scenario
string

Steers the fixture backend. Ignored by live keys, 400 test_scenario_not_supported if the scenario is unknown to the endpoint. Common catalogue:

Some endpoints add their own scenarios; unsupported common scenarios (for example empty_result on a generation endpoint) are rejected rather than silently ignored.

Examples:

"empty_result"

"low_confidence"

"model_error"

"slow"

"insufficient_credits"

Query Parameters

wait
boolean
default:false

Hold the connection until the job settles and answer 200 with the completed job instead of 202 with a queued one. Available on fast endpoints only; the ceiling is 30 s, after which the job keeps running and the call answers 202 as usual.

Body

image
file
required

JPEG, PNG or WebP, 10 MB maximum. Larger files must go through /v1/uploads.

document_type_hint
enum<string>
Available options:
registration_certificate,
invoice,
service_record,
insurance_certificate
country_hint
string
Pattern: ^[A-Z]{2}$
return_boxes
boolean
default:true

Return the position of each field, for a review UI that highlights them.

Response

Job completed synchronously (wait=true).

The unit of work of the API. Every inference call creates one, and every result is read back from one — synchronously through wait=true, or later through GET /v1/jobs/{id} or a webhook.

result is populated only in succeeded, error only in failed / expired. stages is present on inspection jobs only.

id
string
required

Job identifier — job_ followed by a base58 string.

Pattern: ^job_[1-9A-HJ-NP-Za-km-z]{8,32}$
Example:

"job_3ZxK9pQr7TnW"

object
string
required
Allowed value: "job"
endpoint
enum<string>
required

Dotted slug of a CarHub endpoint, the identifier used for jobs and usage.

Available options:
vehicle.analyse,
vehicle.segment,
vehicle.identify,
vin.read,
plate.read,
document.read,
dashboard.read,
engine.detect,
video.onboard,
damage.detect,
damage.severity,
tire.read,
tire.detect,
parts.recognize,
parts.segment,
parts.decompose,
pricing.vehicle,
pricing.repair,
render.background,
render.enhance,
render.plate,
render.360,
render.video,
viewer.hotspots,
inspections
status
enum<string>
required

Lifecycle of a job. queuedprocessing → one of succeeded | failed; expired when it was never picked up in time, canceled when it was cancelled before starting. The three settled states are terminal.

Available options:
queued,
processing,
succeeded,
failed,
expired,
canceled
livemode
boolean
required

false when the job was created with a chk_test_ key: fixture result, test credits.

created
integer<int64>
required

Epoch seconds, UTC.

Example:

1755300000

started_at
integer<int64> | null
required

When the job left the queue. Null while queued.

Example:

1755300000

completed_at
integer<int64> | null
required

When the job settled. Null until then.

Example:

1755300000

model_version
string | null
required

Exact model build that produced the result, as <model>@<release date>. Null until the job starts. Pin your regression tests to it.

Example:

"plate-reader@2026-08-01"

credits
object
required

Credit accounting for the job. One credit equals one USD cent. reserved is held at admission and charged is the real cost after settlement; unused credits are released.

result
document.read result · object | null
required

The document's type and its extracted fields. Fields are returned as a flat, named list rather than a per-document-type object, so one shape covers a registration certificate, an invoice and a service record alike — and so a new document type never breaks a client.

Field names are stable per document type:

  • registration_certificateholder_name, holder_address, plate, vin, first_registration_date, make, model, fuel, power_kw, document_number.
  • invoiceinvoice_number, issue_date, seller_name, total_amount, currency.
  • service_recordservice_date, mileage_km, garage_name, operations.
  • insurance_certificateinsurer_name, policy_number, valid_from, valid_until, plate.

Values are returned as read, unparsed and unvalidated: dates keep the document's own formatting only when they cannot be normalised to ISO 8601.

error
object | null
required

Populated when status is failed or expired, null otherwise.

stages
Inspection stage · object[]

Per-stage progress. Present on inspections jobs only, absent everywhere else.

test_scenario
string

The X-Carhub-Test-Scenario that produced this job. Present on test-mode jobs that were steered by one, absent otherwise — a live job never carries it.

Example:

"low_confidence"