Error envelope
Every non-2xx response has the same shape:error string is a
human-readable hint. Don’t pattern-match on the message text — it’s free-form and may
change. Branch on the status code instead.
Status code reference
| Status | Meaning | What to do |
|---|---|---|
400 Bad Request | Malformed request — invalid UUID, missing required field, oversized file. | Fix the request; do not retry as-is. |
401 Unauthorized | API key missing, malformed, or revoked. | Mint a new key (see Authentication). |
403 Forbidden | Key is valid but the agent/task lives in another workspace. | Use a key scoped to the right workspace. |
404 Not Found | Agent or task UUID doesn’t exist. | Check the ID. Note: this is also returned for resources in other workspaces, so a stolen ID can’t be probed. |
409 Conflict | State-conflict (e.g. publishing an agent that has no draft changes). | Inspect the message; the operation isn’t valid right now. |
429 Too Many Requests | Rate limit hit. | Back off — see below. |
500 Internal Server Error | Unexpected server-side error. | Safe to retry with exponential backoff. |
503 Service Unavailable | Temporary outage / deploy. | Retry with backoff. |
When to retry
| Class | Retry? |
|---|---|
4xx except 429 | No — the request itself is wrong. Fix and re-send. |
429 | Yes, after a back-off. Respect any Retry-After header if present. |
5xx | Yes — these are transient. Use exponential backoff (1s → 2s → 5s → 10s, cap at ~30s) with full jitter, and give up after 4–5 attempts. |
Python
Pagination
List endpoints (GET /v1/tasks, GET /v1/agents, GET /v1/agents/{id}/versions) are
cursor-paginated, newest-first. The response looks like:
cursor query parameter.
When you reach the end, next_cursor is omitted (or empty).
Python
Cursor opacity
next_cursor is opaque — don’t try to parse it. If you decode it today and rely on the
shape, your code will break the next time the server changes its pagination key.
limit
Default is 20, max is 100. Larger pages mean fewer round-trips but a larger response
body; for bulk export, 100 is usually the right choice.
Rate limits
Rate limits are enforced per-workspace, not per-key. If you’re running tight loops or fanning out many concurrent agents, watch for429 and back off. We do not currently
publish per-tier numbers — if you’re hitting limits in production, reach out.