Errors & status codes
The error envelope, every error code, and retry guidance.
Every error response uses one envelope:
{
"error": {
"code": "study_not_found",
"message": "No study 'a1b2c3d4' for this organization"
}
}
Some errors include extra context fields next to code and message (for example detected_series on series-selection failures). A validation_error carries details, a list of { "field": "patient.dob", "message": "..." }.
Unknown routes answer 404 not_found and unsupported methods 405 method_not_allowed, in the same envelope. Anything unexpected on our side is 500 internal_error with no further detail; retry with backoff.
Error codes
| HTTP | Code | When | What to do |
|---|---|---|---|
| 401 | invalid_api_key | Missing or unknown X-API-Key | Check the header and key value |
| 403 | key_revoked | Key was revoked | Use your replacement key |
| 400 | unsupported_file_type | File is not .dcm or .zip | Repackage the study |
| 400 | no_files | No file part in the submit | Send the study as multipart form data with the file in file |
| 400 | unsupported_scan_type | scan_type is not a known body region | Use one of the values listed in the message |
| 404 | study_not_found | Unknown study id for your org | Check the study_id from the submit response |
| 404 | results_not_ready | report.html requested before the read completes | Poll GET /studies/{id} until complete |
| 422 | no_processable_series | No usable DICOM series found; the study was not kept | Inspect detected_series reasons; resubmit with a different series |
| 422 | series_not_found | series_uid not in the upload; the study was not kept | Check the UID against detected_series and resubmit |
| 422 | body_part_mismatch | scan_type disagrees with the DICOM BodyPartExamined; the study was not kept | Resubmit with the right scan_type |
| 422 | validation_error | Malformed request | See details for field errors |
| 422 | scan_type_undetected | The DICOM header does not say what was scanned; the study was not kept | Resubmit with scan_type |
| 429 | rate_limited | Too many write requests this hour | Wait for Retry-After |
| 502 | upload_failed / processing_failed | The study could not be stored or dispatched; nothing was kept | Retry the submit |
| 500 | internal_error | Unexpected failure on our side | Retry with backoff; contact support if it persists |
| 503 | storage_unavailable / auth_unavailable | Upstream dependency issue | Retry with backoff |
Retry guidance
- 5xx responses: retry with exponential backoff (for example 1s, 4s, 16s, then alert).
- First request after idle can take several seconds while capacity warms up. Set client timeouts to at least 90 seconds and treat a timeout as retryable.
- 4xx responses: do not retry unchanged; fix the request.
- Submit is safe to retry with an
Idempotency-Keyheader: a repeat returns the study the first request created and never reads it twice. A failed submit keeps nothing, so a plain resubmit is also safe.
Study status values
| Status | Meaning |
|---|---|
uploaded | Stored, not yet dispatched |
queued | Waiting for a worker |
processing | The read is running; step says where it is |
complete | Results available |
error | Failed; error field has the reason |
These five are the only values any route returns.
Next: Changelog