> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ada.cx/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.