---
title: Errors & Edge Cases
description: Complete error catalog and async failure modes for production integrations.
source: https://www.edgaze.ai/docs/api/errors
section: api
---
# 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

```doccallout
{"variant":"warning","text":"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.
