# Errors and rate limits

Error format, status codes and rate-limit headers of the zn Cloud API.

Source: https://usezn.com/docs/api/errors/

Errors return JSON with an `error` message. Quota errors add a machine-readable `code`.

```json
{"error": "Invalid API key"}
```

```json
{"error": "Monthly call limit reached", "code": "MONTHLY_LIMIT_REACHED"}
```

## Status codes

| Status | Meaning | What to do |
| - | - | - |
| 400 | The body is missing `input`, or `input` is longer than 20,000 characters | Send `{"input": "..."}`, split long inputs |
| 401 | Missing or invalid API key | Check the `Authorization` header and the key in the dashboard |
| 429 | Monthly limit reached (`MONTHLY_LIMIT_REACHED`) | Wait for `Retry-After`, add credits or upgrade |
| 500 | Unexpected analysis failure | Retry once with backoff (each request counts against quota) |

Branch on the HTTP status and on `code`, not on the text of `error`, which may change.

## Rate-limit headers

`RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` come back on successful responses and on 401 and 429, so you can slow down before hitting a 429. A 429 also includes `Retry-After`.

## Fail open or fail closed?

Decide what your agent does when zn is unreachable. For high-impact tools (shell, payments, data deletion), fail closed: do not run the tool. For low-impact reads, you may fail open and keep the local [zn-gate](https://usezn.com/docs/zn-gate/) rules as a fallback.
