# Errors

Failures return an RFC-9457 problem document with `Content-Type: application/problem+json`. Branch on the stable `code` in your own code; show `detail` to a human.

```json
{
  "type": "https://ziffi.dev/problems/product_not_found",
  "title": "Product Not Found",
  "status": 404,
  "detail": "No product for id 'sha:zzz'.",
  "code": "product_not_found"
}
```

## Codes

| `code` | HTTP | When it happens | What to do |
|---|---|---|---|
| `invalid_argument` | 400 | A parameter is missing or malformed | Fix the request; read `detail`. |
| `auth_required` | 401 | An endpoint needs a key | Send `X-Ziffi-Key`. |
| `forbidden` | 403 | The key may not do that | Use a permitted key. |
| `product_not_found` | 404 | No product matches the identifier | Check the id or `product_uid`. |
| `brand_not_found` | 404 | No brand matches the slug | Check the slug. |
| `not_found` | 404 | The resource does not exist | Verify the path. |
| `rate_limit` | 429 | You exceeded the rate limit | Back off using `Retry-After`. |
| `quota_exceeded` | 429 | A daily cap was reached | Retry after the window. |
| `upstream_unavailable` | 503 | A brand store is temporarily unreachable | Retry with backoff. |
| `internal` | 500 | An unexpected error | Retry; if it persists, report it. |

Retryable errors (`429`, `503`) carry a `Retry-After` header in seconds.

## Handling a 429

```python
import time, httpx

def get(url, tries=5):
    for _ in range(tries):
        r = httpx.get(url)
        if r.status_code != 429:
            return r
        time.sleep(int(r.headers.get("Retry-After", "1")))
    r.raise_for_status()
```

```javascript
async function get(url, tries = 5) {
  for (let i = 0; i < tries; i++) {
    const r = await fetch(url);
    if (r.status !== 429) return r;
    const wait = Number(r.headers.get("Retry-After") || 1);
    await new Promise(res => setTimeout(res, wait * 1000));
  }
  throw new Error("rate limited");
}
```

## Next steps

- [Rate limits](#/rate-limits): the one open limit.
- [The response envelope](#/envelope): the success shape.
