Every error is a problem detail (RFC 7807), sent as application/problem+json:
{
"type": "/api/v1/problems/insufficient-scope",
"title": "Insufficient Scope",
"status": 403,
"detail": "API key is missing required scope: write",
"instance": "/api/v1/jobs/submit",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"retryability": "auth"
}| Field | Meaning |
|---|---|
type | The kind of problem. Specific problems have their own name (below); others are …/problems/http-<status>. Branch on this, not on detail. |
title, status | A short name for the problem, and the HTTP status. |
detail | A human-readable explanation. Its wording can change. |
instance | The path that failed. |
request_id | Quote it when you contact support. Every response also carries it in the X-Request-ID header; send your own X-Request-ID to set it. |
errors | On most 422 responses, the list of problems found (below). |
retryability | Whether to retry (below). |
Should I retry?
retryability | Statuses | What to do |
|---|---|---|
upstream | 5xx | Retry with exponential backoff. |
timeout | 408, 504 | Retry with backoff. |
quota | 429, plan limits, spend ceilings | Wait (for 429, a minute; for monthly limits, next month) or raise the limit. |
conflict | 409 | Re-read the current state, then decide. |
validation | 400, 413, 422 | Fix the request. Retrying unchanged fails again. |
auth | 401, 403 | Fix the credential or its scopes. |
terminal | others, such as 404 and 410 | Don't retry. |
Retry writes with the same Idempotency-Key, so a request that actually succeeded isn't done twice. See Idempotency and Handling errors.
Validation errors
A 422 lists each problem in errors. Request-shape problems look like:
{"type": "missing", "loc": ["body", "job_type"], "msg": "Field required", "input": {}}Workflow problems (from validate, estimate, saving a definition, or starting a run) are diagnostics instead, with a code, a message, and where they apply (step_id, port, or a JSON path):
{"code": "edge_incompatible", "message": "cannot resolve source port embed3d.poses", "step_id": "dock", "port": "ligands"}Branch on code, and treat codes you don't recognize as general validation failures: new ones can appear.
Named problems
type ends with | Status | Meaning |
|---|---|---|
missing-idempotency-key | 400 | An API-key write was sent without an Idempotency-Key. |
insufficient-scope | 403 | The API key lacks read or write for this call. |
api-key-management-forbidden | 403 | API keys can't manage API keys; use an access token. |
api-key-limit-exceeded | 403 | Your plan's API key limit is reached. |
spend-ceiling-exceeded | 403 | The key's monthly spend ceiling would be passed. |
insufficient-wallet | 402 | The wallet can't cover an Assistant turn or a plan-card approval. |
session-spend-cap | 409 | The Assistant conversation reached its spend cap. |
estimate-changed | 409 | A plan card's price went up; approve the new price. |
proposal-expired | 410 | A plan card expired. |
invalid-event-cursor | 422 | An events after cursor is malformed. |
A job or workflow run that your wallet can't cover returns 400 with a detail explaining it.