Developer APIErrors, limits and compute

Errors, limits and compute

Error format

Every API error uses the same envelope:

{
  "error": {
    "type": "validation_error",
    "code": "unknown_inputs",
    "message": "One or more inputs are not declared by this capability",
    "param": "inputs",
    "details": {"unknown": ["foo"]},
    "request_id": "..."
  }
}

Every response includes a request ID. Include it when you contact support.

Errors from the managed-lab routes add a resolution, whether the call is retryable, and a gateway_request_id under details. Their codes match the MCP tools:

StatusCodesMeaning
403insufficient_scopeThe key lacks the route’s scope.
403gateway_not_enabledThe call starts compute, publishes, changes a lab or reaches external sources, and managed operations are not enabled for the account. Reads still work.
404run_not_found, workspace_not_found, lab_not_found, file_not_found, experiment_not_foundNot found. Records owned by another account get exactly this answer, so an ID never reveals whether someone else’s work exists.
409plan_digest_mismatch, plan_expired, plan_blocked, plan_unavailable, idempotency_conflictPrepare the plan again, or use the exact digest it returned.
429rate_limitedThe daily fair-use limit for this key. Wait Retry-After seconds.

In Python, failed requests raise ApiError, AuthenticationError, ValidationError, RateLimitError or InsufficientCreditsError. A run that ends badly raises RunFailed, and a caller timeout raises RunTimeout with the live run handle.

Idempotency

POST /runs needs an Idempotency-Key header. The SDK creates one for you, or you can pass idempotency_key=.

What happensResponse
Same key, same requestThe original run
No key400 idempotency_key_required
Same key, different request409 idempotency_conflict
Same key while the first request is still processing409 idempotency_in_progress, retry after Retry-After

Retries and rate limits

The SDK retries transport failures and HTTP 408, 425, 429, 500, 502, 503 and 504 with bounded exponential backoff and jitter, and it respects Retry-After. Don’t retry validation, authentication or idempotency-conflict errors without changing the request.

Rate limits apply per API key. Creating runs has a tighter limit than reads, and compute concurrency is limited per account. Check these headers:

RateLimit-Limit
RateLimit-Remaining
RateLimit-Reset
Retry-After

Compute

Managed runs of a private Lab revision (kind: managed) consume compute. Their published price is shown before execution.

Scientific runs consume compute from your personal allowance or the owning team’s pool. Add compute in Billing; purchased funds are available only after Stripe confirms payment.

Before a run is queued, the service reserves enough compute for its compute profile. When the run ends it charges what was used and gives back the rest. The run response shows both amounts in US dollars (the field names keep their original credits_ prefix):

{
  "credits_reserved": 10,
  "credits_settled": 3
}

If your available compute can’t cover the reservation, the request fails with 402 and Python raises InsufficientCreditsError.