curl --request GET \
--url https://api.trycarhub.com/mgmt/v1/jobs/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.trycarhub.com/mgmt/v1/jobs/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.trycarhub.com/mgmt/v1/jobs/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trycarhub.com/mgmt/v1/jobs/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.trycarhub.com/mgmt/v1/jobs/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.trycarhub.com/mgmt/v1/jobs/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trycarhub.com/mgmt/v1/jobs/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"is_staging": false,
"id": "job_3ZxK9pQr7TnW",
"object": "job",
"endpoint": "vehicle.pose",
"status": "queued",
"livemode": true,
"created": 1755300000,
"started_at": 1755300000,
"completed_at": 1755300000,
"model_version": "plate-reader@2026-08-27",
"credits": {
"reserved": 20,
"charged": 20
},
"result": {},
"error": {
"type": "processing_error",
"code": "model_inference_failed",
"message": "<string>"
},
"test_scenario": "low_confidence",
"api_key_id": "key_9TbR3xLm",
"api_key_prefix": "chk_live_a1b2",
"charged": 123
}Retrieve a job (dashboard)
Identical payload to GET /v1/jobs/{id}, reachable with a dashboard JWT and with the
api key that produced it exposed for audit. Minimum role: member.
curl --request GET \
--url https://api.trycarhub.com/mgmt/v1/jobs/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.trycarhub.com/mgmt/v1/jobs/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.trycarhub.com/mgmt/v1/jobs/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trycarhub.com/mgmt/v1/jobs/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.trycarhub.com/mgmt/v1/jobs/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.trycarhub.com/mgmt/v1/jobs/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trycarhub.com/mgmt/v1/jobs/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"is_staging": false,
"id": "job_3ZxK9pQr7TnW",
"object": "job",
"endpoint": "vehicle.pose",
"status": "queued",
"livemode": true,
"created": 1755300000,
"started_at": 1755300000,
"completed_at": 1755300000,
"model_version": "plate-reader@2026-08-27",
"credits": {
"reserved": 20,
"charged": 20
},
"result": {},
"error": {
"type": "processing_error",
"code": "model_inference_failed",
"message": "<string>"
},
"test_scenario": "low_confidence",
"api_key_id": "key_9TbR3xLm",
"api_key_prefix": "chk_live_a1b2",
"charged": 123
}Authorizations
Short-lived JWT issued by the CarHub auth service (Better Auth), verified against its
JWKS. Claims: sub (user), org_id (active organisation) and role
(owner | admin | member | billing_manager). Used by the dashboard for /mgmt/v1/… only — it is never
accepted on /v1/….
Path Parameters
Job identifier.
Job identifier — job_ followed by a base58 string.
^job_[1-9A-HJ-NP-Za-km-z]{8,32}$"job_3ZxK9pQr7TnW"
Response
The job.
A job as seen from the dashboard, with the audit fields the API key never sees.
Staging classification. Requires live mode and uses the organisation's shared live credits.
Job identifier — job_ followed by a base58 string.
^job_[1-9A-HJ-NP-Za-km-z]{8,32}$"job_3ZxK9pQr7TnW"
"job"Dotted slug of a CarHub endpoint, the identifier used for jobs and usage.
vehicle.pose, vehicle.segment, vehicle.identify, vin.read, driver_license.read, plate.read, document.read, dashboard.read, engine.detect, 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, render.hotspots Lifecycle of a job. queued → processing → one of succeeded | partial | failed; expired
when it was never picked up in time, canceled when it was cancelled before starting.
Every state after processing is terminal.
queued, processing, succeeded, partial, failed, expired, canceled false when the job was created with a chk_test_ key: fixture result, test credits.
Epoch seconds, UTC.
1755300000
When the job left the queue. Null while queued.
1755300000
When the job settled. Null until then.
1755300000
Exact model build that produced the result, as <model>@<release date>. Null until the job starts. Pin your regression tests to it.
"plate-reader@2026-08-27"
Credit accounting for the job. One thousand credits equal one USD. reserved is held at
admission and charged is the real cost after settlement; unused credits are released.
Show child attributes
Show child attributes
Endpoint-specific payload, null until the job succeeds. See each endpoint's 200 / 202 schema for its exact shape.
Populated when status is failed or expired, null otherwise.
Show child attributes
Show child attributes
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.
"low_confidence"
Key that created the job.
"key_9TbR3xLm"
"chk_live_a1b2"
Money charged to the credit balance for this job, in minor currency units.