> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ada.cx/reference/introduction/limits/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server. # Limits Ada's API enforces rate and data limits to ensure stability and prevent abuse. These limits are applied per Ada instance. ## Rate limits ### Default rate limits Unless otherwise specified, the following default rate limits apply across all Platform API endpoints: * Requests per day: 10,000 * Requests per minute: 100 * Requests per second: 10 Exceeding these limits will result in a `429 Too Many Requests` error. Implement retry logic with exponential backoff and jitter to handle these responses and minimize disruptions. ### API-specific rate limits Some APIs have their own specific rate limits that differ from the defaults: | API | Per-Second Limit | Per-Minute Limit | Per-Day Limit | | ----------------------------------------------------- | --------------------------------- | ------------------- | ------------------- | | Data Export API (v2) | 10 requests/second (per endpoint) | 100 requests/minute | 15,000 requests/day | | Data Export API (v1.4) | 10 requests/second (per endpoint) | No per-minute limit | No daily limit | | MCP server (per AI Agent; per user for OAuth sign-in) | 50 requests/second | 200 requests/minute | 30,000 requests/day | The Data Export API (v1.4) endpoints return no rate limit headers. See [rate limit headers](#rate-limit-headers). The MCP server also refuses every request from an IP address for the rest of the minute, after 300 requests from that address fail authentication or exceed the budget in one minute. > **Note** > > Refer to the documentation for each API endpoint for complete details on rate limits and any additional restrictions. ### Rate limit headers Every `/v2/` Platform API endpoint and the MCP server return these headers on every successful authenticated response. The legacy Data Export v1.4 endpoints (`/data_api/v1.x/`) return no rate limit headers. * `X-RateLimit-Limit`: the request cap for the current window. * `X-RateLimit-Remaining`: the requests left in the current window. * `X-RateLimit-Reset`: the Unix timestamp when the window resets. On a successful response, these headers describe the longest window that applies to the endpoint. That is the per-day limit where one exists, or the per-minute limit otherwise. A Platform API `429` from the rate limiter carries only `Retry-After`. An MCP `429` from the rate limiter also carries the three headers, and they describe the window that was exceeded. A `429` response caused by rate limiting includes a `Retry-After` header. It gives the number of seconds to wait before you retry. Other `429` responses, for example an application cooldown, do not carry `Retry-After`. Use `Retry-After` to pace retries. Use `X-RateLimit-Remaining` and `X-RateLimit-Reset` to avoid hitting the limit. `X-RateLimit-Remaining` tracks the longest window only. Pace per-second and per-minute traffic from the documented limits, not from this header. Responses to requests that fail authentication, such as a request with an invalid token, carry no `X-RateLimit-*` headers. A `429` from the rate limiter still carries `Retry-After`. ### Working with rate limits Read the rate limit headers on every response, not only on a `429` response. When `X-RateLimit-Remaining` is low, slow down. Spread the remaining requests over the time left until `X-RateLimit-Reset`. Do not sleep until the reset time on an endpoint with a daily limit. That wait can be hours. On a `429` response with `Retry-After`, wait the number of seconds it gives. Then retry once. Treat `Retry-After` as a minimum wait, not an exact one. Do not retry in a tight loop. Do not use a fixed short delay instead of the header value. Do not blind-retry a request that timed out with no response. On a write such as `POST /v2/conversations/`, the server may have accepted the request before the connection dropped. Spread a bulk job across the window. Do not send it in one burst. For example, a job of 10,000 calls against a 300-per-minute limit sends about 5 requests per second when spread evenly. It finishes in about 33 minutes. A job that sends as fast as possible spends most of its run being rejected with `429` responses. A `200` response can carry `X-RateLimit-Limit: 300`, `X-RateLimit-Remaining: 12`, and `X-RateLimit-Reset: 1758112860`. A later `429` response can carry `Retry-After: 17`. Retry only when `Retry-After` is present. A `429` without it from a `/v2/` endpoint is an application limit. Handle it as an error. A `429` from a legacy `/data_api/v1.x/` endpoint carries no headers. Back off exponentially there, starting at one second. Use this pattern to pace your requests: ```python response = send_request() if response.status_code == 429: retry_after = response.headers.get("Retry-After") if retry_after is None: raise ApplicationLimitError(response) time.sleep(int(retry_after)) response = send_request() elif response.ok: remaining = response.headers.get("X-RateLimit-Remaining") reset_at = response.headers.get("X-RateLimit-Reset") if remaining is not None and reset_at is not None: seconds_left = max(1, int(reset_at) - time.time()) if int(remaining) < THRESHOLD: time.sleep(min(seconds_left / max(1, int(remaining)), 60)) ``` ## Data limits * Max request body size: 10MB Exceeding this size will result in a `413 Content Too Large` error. > **Note** > > Some endpoints may also enforce **local data limits**. Refer to the documentation for each API endpoint for details on additional restrictions.