Skip to content

Errors

Every error returns a JSON body with a stable machine code and a human message, plus an appropriate HTTP status:

{ "code": "quota_exceeded", "message": "concurrent sandbox limit reached" }

Branch on code — it is stable across releases — not on the message text or the raw HTTP status alone.

Returned by the API for auth, tenancy, and quota. All are fail-closed: a missing config or the auth store being unavailable denies rather than defaults open.

StatuscodeMeaning & what to do
400bad_requestMalformed JSON or invalid fields. Fix the body.
401unauthorizedMissing/malformed Authorization, unknown key id, wrong secret, or a revoked key. Check or recreate the key.
402insufficient_creditsYour prepaid balance is exhausted. Top up (or enable auto top-up) in Billing.
403forbiddenValid key, but the resource isn't yours — a template your tenant doesn't own, or another tenant's sandbox.
403demo_tier_limitA Demo key hit a demo boundary (concurrency, width, or a Pro-only capability like baking or connect-from-outside). The message says which; upgrading lifts it.
404not_foundUnknown or reaped sandbox id, or one not visible to your tenant. Create a new one.
409template_in_useThe template still backs live sandboxes — delete those first.
409port_not_exposedconnect-url (or connect) targeted a port the template doesn't expose. Bake the port into the template's ready-state ports; the SDK raises GatewayError with this code.
429rate_limitedPer-key request rate exceeded. Honor Retry-After and back off.
429quota_exceededAt your tier's concurrent-sandbox cap. Suspend/delete one, or upgrade.
502upstream_errorThe request reached the sandbox but the call failed upstream. Retry with backoff.

Returned by the sandbox for sandbox-scoped operations.

StatuscodeMeaning & what to do
409busyThe sandbox has an in-flight exec — you can't fork or re-exec until it finishes. Retry after it completes.
410session_goneThe sandbox was destroyed/reaped mid-request. Permanent — do not retry; create a new one.
413(payload)The request body or a file exceeded the size cap. Shrink it or stage via files.
503at_capacityThe platform shed the request before doing any work (no side effect). Safe to retry with backoff.
503drainingThe platform is briefly at capacity or cycling capacity; no work was admitted. Safe to retry.
503session_bringup_failedThe fork itself failed, leaving no live sandbox. Safe to retry.
  • Idempotent requests (GET, DELETE) are always safe to retry.
  • A non-idempotent request (a create/exec/fork POST) is only safe to retry when the platform proves no side effect committed — codes at_capacity, draining, session_bringup_failed, or a connection refused before the request was sent. Any other ambiguous 5xx should not be blindly re-sent, or you risk double-forking.
  • 429 responses carry Retry-After; use exponential backoff with jitter so a shed group doesn't re-arrive as a thundering herd.

The collimate-rl SDK implements all of this — bounded retries, full-jitter backoff, and side-effect-safe idempotency — so you rarely need to hand-roll it.