# Rate limits

> 600 requests per minute per key, the RateLimit headers on every response, and how to back off on 429.

Source: https://dev.ody.co/api/rate-limits

Every API key gets **600 requests per minute**, shared across `/v1/api/*` and the MCP endpoint. Requests without a valid key are limited per IP address instead.

## Headers

Every response, success or error, carries:

| Header | Meaning |
|---|---|
| `RateLimit-Limit` | Your budget for the window (600) |
| `RateLimit-Remaining` | Requests left in the current window |
| `RateLimit-Reset` | Seconds until the window resets |

When you exceed the limit you get `429` with code `resource_exhausted` and a `Retry-After` header:

```http
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 600
RateLimit-Remaining: 0
RateLimit-Reset: 23
Retry-After: 23
Content-Type: application/json

{"error":{"code":"resource_exhausted","message":"Rate limit exceeded (600 requests/minute). Retry after 23s.","requestId":"req_…"}}
```

The window is a fixed 60 seconds.

## Staying under the limit

- **Watch `RateLimit-Remaining`** and slow down as it approaches zero, rather than reacting to `429`s.
- **Use webhooks instead of polling.** Subscribe to `message.received` and Ody pushes new messages to you. If you must poll a shared inbox, every 10–30 seconds is plenty.
- **Request bigger pages** (`limit` up to each endpoint's maximum) when syncing.
- **Back off with jitter** on `429` and `5xx`; honour `Retry-After`; cap your retries.

```ts
async function withBackoff<T>(fn: () => Promise<T>, attempts = 5): Promise<T> {
  for (let i = 0; ; i++) {
    try {
      return await fn();
    } catch (err: any) {
      const retriable = err?.status === 429 || err?.status >= 500;
      if (!retriable || i >= attempts - 1) throw err;
      const wait = err.retryAfter ? err.retryAfter * 1000 : Math.min(30_000, 2 ** i * 500) * (0.5 + Math.random());
      await new Promise((r) => setTimeout(r, wait));
    }
  }
}
```

Need a higher limit for a specific integration? Email [support@ody.co](mailto:support@ody.co) with your use case.
