arbitr API
Programmatic access to arbitr.
Use this API to create translation projects, upload documents, poll progress,
fetch deliverables, and manage credits from your own tools. Authenticate with
an API key generated in the arbitr UI under Settings → API Keys. All
routes are served under the /v1 prefix, which is itself the API version
marker.
Required header on every call:
| Header | Value |
|---|---|
X-API-Key |
abr_live_... — from Settings → API Keys |
X-API-Version: 1 may optionally be sent for belt-and-suspenders
validation; it is not required.
Scopes: each key is limited to the scopes granted when it was created
(e.g. verify:submit, verify:read). A call to a route the key isn't scoped
for returns 403 insufficient_scope. Check a key's scopes with GET /v1/me.
Rate limits: per API key. Live keys (abr_live_* / py_live_*): 100
requests/minute. Test/sandbox keys (abr_test_* / py_test_*): 30
requests/minute. Both share a 20 requests/second burst cap. Every
response includes X-RateLimit-Limit, X-RateLimit-Remaining, and
X-RateLimit-Reset. Exceeding the limit returns 429 with Retry-After
(seconds) and error.code = rate_limited.
Idempotency: optional Idempotency-Key is accepted only on
POST /v1/projects (create). Other POST routes do not honour it — sending
the header there has no effect.
Language codes: every language and locale value on this API — in
target_language_codes, source_language_code, and every response — is a
lowercase BCP-47 tag (en-us, fr-fr, pt-br, es-419). Use the exact
bcp47 values returned by GET /v1/languages; other forms (bare fr,
mixed-case fr-FR, language names) are not accepted.
Submit a project: POST /v1/projects takes a source file, a
source_language_code (required), a target_language_codes array, plus a
workflow — an ordered list of stages. AI_TRANSLATION is the required base
(machine translation and automatic verification); layering on TRANSLATION
(requires AI_TRANSLATION) and EDIT (requires TRANSLATION) routes the
project through the corresponding human stages after the AI stage completes —
arbitr assigns and sequences everything downstream of workflow automatically.
["AI_TRANSLATION"] alone is a valid AI-only project. An optional due_date
(YYYY-MM-DD) is informational only — it never blocks or parks the project;
feasibility is reported back on the status endpoint.
Poll a project: GET /v1/projects/{id} is the single status endpoint.
Alongside status, it returns an assessment block (billable words,
due_date_feasible, and per-wallet credit sufficiency —
credits.intelligence always, plus credits.trust when the workflow
includes a human stage) and a review block describing where the project
sits in its human-stage lifecycle.
Credit shortfall: if a project's credits run out mid-flight — intelligence
credits for the AI stage, or trust credits for a human stage — its status
becomes awaiting_payment. Top up the org's balance and call
POST /v1/projects/{id}/resumptions (or
POST /v1/projects/{id}/review/resumptions when the hold is on the human
stage) to continue (409 if the project isn't awaiting payment, 402 if
the balance is still short). The older …/resume and
…/human-review/resume paths still work but are deprecated until
2026-11-05; move callers to the two routes above.
Deliverables: list a completed project's files with
GET /v1/projects/{id}/deliverables; add ?format=zip to get all of them
bundled as one ZIP instead of the JSON list. Fetch one deliverable with
GET /v1/projects/{id}/deliverables/{deliverable_id} — omit Accept (or
send application/json / */*) for its metadata, or send Accept: application/octet-stream to stream the file bytes directly instead.
The older …/deliverables/zip and …/deliverables/{deliverable_id}/download
paths still work but are deprecated until 2026-11-05; move callers to
the two routes above.
Losing a key: rotate it from the Settings page. The plaintext is shown only once.
Deprecations: a route being retired stays callable until its sunset date
and is marked deprecated below. While deprecated, every response carries
Deprecation and Sunset headers (RFC 9745 / RFC 8594) so client tooling
can warn before anything breaks. The minimum notice from announcement to
removal is 90 days. After sunset the route answers 410 Gone with a pointer
to its replacement.