Guides
Errors & Edge Cases
Complete error catalog and async failure modes for production integrations.
Complete error catalog and async failure modes for production integrations. Branch on `error.code`: messages are stable but intended for humans, not programmatic matching.
All errors use the envelope `{ "error": { "code": "…", "message": "…" } }`.
Error catalog#
| Code | HTTP | When |
|---|---|---|
| `unauthorized` | 401 | Invalid, missing, revoked, or expired API key |
| `insufficient_scope` | 403 | Key lacks required scope |
| `forbidden` | 403 | Not entitled to workflow or run (non-leaky) |
| `not_found` | 404 | Unknown workflow or run, or cross-tenant run |
| `spend_cap_reached` | 402 | API key spend cap exceeded (sync, before run created) |
| `rate_limited` | 429 | 60 POST /runs requests per minute per key |
| `invalid_json` | 400 | Request body is not valid JSON |
| `missing_workflow` | 400 | POST /runs without workflow or workflowId |
| `internal_error` | 500 | Unexpected server error (no internals leaked) |
Async failures after 202#
POST /runs returns 202 before wallet or bundle funding is finalized. If the account lacks funds, the run row is created then fails during preparation. Poll GET /runs/{id} and handle status: failed: there is no synchronous 402 for insufficient wallet balance. Spend cap breaches are the opposite: they return 402 synchronously and no run id is created.
Run model edge cases#
- free: runnable via wallet path when entitled.
- per_run: wallet or bundle charged at trigger.
- legacy_unlock: requires one-time purchase before API runs succeed. Check `purchaseRequired` on the workflow detail response.