Errors

How the API reports failures — status codes and the error body shape.

View as Markdown

Errors come back as JSON with a snake_case code and a matching HTTP status:

1{ "error": "invalid_status" }

Some errors carry extra detail alongside the code (for example a list of offending field keys). Always branch on the HTTP status first, then on the error code.

Status codes

StatusMeaning
401Unauthenticated — missing, malformed, or invalid token
403Authenticated but lacks a write permission, or not an admin
404Not found — also used as a leak-guard for a missing space:read grant (hides existence rather than returning 403)
409State conflict (for example, reprocessing a non-failed file, or deleting a definition that still has objects)
410Expired but still within a grace window (see the Process API)
413Payload too large (relayed from file storage)
422Invalid body — an unknown or archived field, or a $-injection attempt
429Too many requests — the organization’s rate limit is exhausted; wait for Retry-After
503A downstream dependency is unavailable, or auth validation hit a transient auth-service outage

The 404-as-leak-guard convention matters: a 404 on a space-scoped resource can mean “doesn’t exist” or “you can’t see it.” The API deliberately doesn’t distinguish the two, so you can’t probe for the existence of resources you lack access to.

Common error codes

CodeTypical statusMeaning
unauthorized401Missing or malformed Authorization header
invalid_token401Token failed validation
auth_unavailable503Transient auth-service outage during key validation — retry; not a revoked key
org not found404Token has no associated organization
invalid_request400Malformed request (for example, combining view with filter/sort)
invalid_status400Unknown status value in a query filter
view_not_found404Unknown or wrong-scope saved view
objects_exist409Deleting an object definition that still has live objects
payload_too_large413Body exceeded the size limit
not_found404Unknown id (or hard-wiped resource)
expired410Purged resource, still in its grace window
upstream_error5xxA downstream worker returned an error

Errors on capability endpoints

The capability endpoints (/v1/…) use a richer envelope. The legacy { "error": … } shape above is unchanged on every other route.

1{
2 "code": "invalid_request",
3 "message": "file: provide exactly one of `file` or `files`",
4 "retryable": false,
5 "requestId": "req_01KYCZWG1M7V8HM95NBV63PET2",
6 "docUrl": "https://docs.cloudraker.com/developers/errors#invalid_request"
7}
FieldWhat it is
codeStable machine-readable code — branch on this.
messageHuman-readable, and where a field is at fault it is prefixed with that field’s path. Never parse it.
retryableWhether repeating the identical request could succeed.
requestIdAlso returned as the x-request-id response header. Quote it in support requests.
docUrlPresent when a specific rule was broken — links to the rule.

invalid_request

400. The body or query is malformed: a missing field, a bad type, or a mutually exclusive pair sent together (file and files, schema and action, spaceId and space on keep). It also covers a parameter that doesn’t apply to the input — style on a PDF, mode on audio — and a saved sign action passed as another verb’s action. message names the offending field. Fix the call; retrying identically will fail identically.

A slow run is never an error. When the synchronous cap is reached the call returns 202 with the run handle, and a run waiting on a human returns 202 with needs_input — both are successes with a body to poll.

invalid_schema

400. The schema you sent to extract breaks the extraction schema dialect. docUrl points at the exact rule and message at the exact node.

not_found

404. No such run, file, template, action, webhook endpoint, or produced output. Also returned when a sub-route addresses a step the run doesn’t have — GET /v1/runs/plr_…/envelope on a pipeline with no sign step. Right after a synchronous run returns, GET /v1/runs/:id/output/:name can 404 for a moment while the produced file is registered; re-fetch the run and use output.file.url.

Other capability codes

CodeStatusMeaning
unauthorized / invalid_token401Missing, malformed, or invalid bearer token.
rate_limited429The organization’s rate limit is exhausted. Nothing was started; wait for the Retry-After seconds and retry.
run_expired410The run passed its ttl and was purged. Terminal; the result is gone. After the grace window this becomes 404.
upstream_error4xxFallback code when a downstream stage rejects the request and has no more specific code. Fix the call; retryable is false.
action_unknown4xxThe action you referenced doesn’t exist in your organization, by id or by slug.
file_ineligible4xxThe document couldn’t be used as an input — wrong type, or it never finished parsing.
file_not_ready409The file exists but hasn’t finished uploading or parsing yet. Poll GET /v1/files/:id until ready.
output_not_ready409A run’s output file is registered but its bytes are still settling. Retryable — wait a moment and re-request output.file.url or /v1/runs/:id/output/:name. It is never a 404.
file_fetch_failed422The url you sent couldn’t be fetched at registration time — unreachable host, non-2xx response, or an empty body.
file_unreadable502The source was reached but its bytes couldn’t be read.
file_upload_failed502The fetched bytes couldn’t be stored. Most often the source served no Content-Length — see Files.
already_kept409The run was already kept into a different space. A run belongs to one space.
pipeline_running409You tried to keep a run that hasn’t finished. Wait for a terminal status.
webhook_endpoint_not_found422webhook: {id} references an endpoint that doesn’t exist.
webhook_endpoint_disabled422The referenced endpoint is paused. Re-enable it with PATCH /v1/webhooks/:id, or send webhook: {url}.
ambiguous_capability4xxA saved redact action didn’t say whether it targets documents or audio. Send mimeType when creating it.
run_too_large4xxThe request exceeds the dispatch size budget. Send fewer files, or a smaller schema.
schema_too_large4xxThe inline schema is over the 64 KB limit. See size limit.
internal_error5xxSomething failed on our side. retryable is true — back off and retry.

New codes can be added over time; branch on the ones you handle and treat anything unknown as a plain failure of its HTTP status class.

Retrying

  • 503 auth_unavailable and 503 downstream errors are transient — retry with exponential backoff.
  • 410 expired is terminal for that resource; don’t retry.
  • 429 rate_limited is transient too, but retry on the terms the response gives you: sleep for the Retry-After seconds, then back off exponentially. The budget and the tactics are on Rate limits.
  • 4xx other than 429 means a bad request — fix the call rather than retrying.

Where to go next