How errors are reported
The API signals failures with standard HTTP status codes. Most errors carry a JSON body. Simple errors use the conventional{"detail": "..."} shape; two cases —
frozen Tasks and request validation — return a structured, typed body documented
below.
Always branch on the status code first, then read the body for detail.
Status codes at a glance
400 — Bad request
A400 means the request was understood but is not acceptable as sent. The
specific causes differ by endpoint (see the table above). The body is the
conventional detail shape:
400 example bodies
400 example bodies
Unknown Neither/both identifiers on The
task_type on POST /task/create:GET /task/get:uuid query parameter is what this message calls task_id — pass exactly one of uuid or external_id.Requesting a link for a non-file Data Item on get_link:task_type values are provisioned for your organization during onboarding —
there is no discovery endpoint. If you get “Task type not in list of allowed
tasks,” confirm the exact value with your Synthpop contact.403 — Forbidden
Returned byPOST /auth/get_token when the api_secret is well-formed but
invalid or obsolete — for example after it has been rotated or revoked. Mint a
fresh secret from the Synthpop UI and exchange it again.
403 example body
403 example body
404 — Not found
The identifier is well-formed but nothing matches it. OnGET /task/get this
means no Task with that uuid/external_id exists for your org; on get_link it
means the Task has no Data Item with that ID.
404 example body
404 example body
409 — Conflict (frozen Task, or Task not accepting uploads)
POST /task/{uuid}/upload returns 409 in two distinct cases, each with a
different body shape:
- The Task has been frozen by a newer, patient-matched Task. The body is
a
TaskFrozenErrornaming the Task to use instead. - The Task is not accepting uploads (it is not in
waiting), or every file in the upload request is a duplicate of an existing Data Item. The body is the conventional{"detail": "..."}shape — for example"All uploaded files are duplicates of existing data items."— not aTaskFrozenError.
409 TaskFrozenError body
409 TaskFrozenError body
409 example body (not accepting uploads / all duplicates)
409 example body (not accepting uploads / all duplicates)
422 — Validation error
FastAPI returns422 when a request fails schema validation — a missing required
field, a wrong type, or an out-of-range value (for example length=500 on
GET /task/list, which caps at 200). The body is an HTTPValidationError: a
detail array where each entry pinpoints one problem.
422 HTTPValidationError body
422 HTTPValidationError body
429 — Too many requests
Two distinct endpoints return429:
POST /task/createreturns429when too much deferrable work is already parked server-side awaiting capacity (it reports aspending, not as a separate observable status). Back off and retry the create later; in-flight Tasks are unaffected. See load backpressure.POST /auth/get_tokenreturns429when there have been too many token-exchange attempts. This response carries aRetry-Afterheader telling you how many seconds to wait before trying again. A token is valid for 365 days, so exchange once and reuse it rather than minting a fresh token per request.
The
429 on POST /task/create is part of the API contract but is not yet
present in the committed OpenAPI snapshot that powers the
API reference. Handle it anyway; the committed
reference will include it once the schema-regeneration job lands.Related
Responding to waiting Tasks
Recover from a
409 and resume a paused Task.Working with async results
Polling, callbacks, and load backpressure (the
429 queue cap).
