> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/operations/reference/rate-limits.md).

# Rate Limits

Every Amigo API endpoint enforces a rate limit, tracked per authenticated identity per endpoint. When you exceed the limit, the API returns HTTP **429 Too Many Requests** with a `Retry-After` header indicating how many seconds to wait before retrying.

{% hint style="info" %}
**Classic API tables.** The endpoint tables on this page cover Classic API endpoints (`api.amigo.ai`). Platform API endpoints enforce rate limits too - their per-endpoint limits are documented in the Platform API OpenAPI spec and the API reference documentation. See the [Platform API guide](/developer-guide/platform-api/platform-api.md) for that surface.
{% endhint %}

## Overview

The two API surfaces expose different rate-limit headers. Classic API responses expose only `Retry-After`, and only on 429 responses. Platform API responses include the `X-RateLimit-*` headers on every response.

| Header                  | API                  | Description                                                |
| ----------------------- | -------------------- | ---------------------------------------------------------- |
| `Retry-After`           | Classic and Platform | Seconds to wait before retrying (present on 429 responses) |
| `X-RateLimit-Limit`     | Platform only        | Maximum requests allowed in the current window             |
| `X-RateLimit-Remaining` | Platform only        | Requests remaining in the current window                   |
| `X-RateLimit-Reset`     | Platform only        | UTC epoch seconds when the window resets                   |

{% hint style="warning" %}
**Rate limits are tracked per authenticated identity per endpoint**, not pooled across the organization. On the Classic API, each request counts against the budget of the user the token was issued for - API keys are exchanged for user-scoped tokens, so keys that sign in as different users have independent budgets, while multiple keys signing in as the same user share that user's budget. On the Platform API, each API key has its own per-endpoint budget.
{% endhint %}

## Find the Current Endpoint Limit

Use the OpenAPI embed on the endpoint's reference page as the source of truth. Its `429` response documents the current numeric limit for that operation when the contract publishes one. This avoids a second method/path matrix that can drift when limits or routes change.

If an embedded operation does not publish a numeric limit, handle `429` and `Retry-After` without assuming a fixed budget. Platform limits can also depend on the authenticated credential and deployment.

## Handling Rate Limits

When your application receives a 429 response, use the `Retry-After` header to determine how long to wait. Combine this with exponential backoff for resilience.

### Manual Implementation

{% tabs %}
{% tab title="Python" %}

```python
import requests, time

def request_with_backoff(method, url, headers, json=None, max_retries=5):
    delay = 1
    for attempt in range(1, max_retries + 1):
        resp = requests.request(method, url, headers=headers, json=json)
        if resp.status_code != 429:
            resp.raise_for_status()
            return resp
        # Respect Retry-After when present; otherwise fall back to exponential backoff
        retry_after = int(resp.headers.get("Retry-After", delay))
        print(f"Rate limited. Retrying in {retry_after}s (attempt {attempt}/{max_retries})")
        time.sleep(retry_after)
        delay = min(delay * 2, 60)
    raise RuntimeError("Exceeded maximum retry attempts due to rate limiting")
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
async function requestWithBackoff(
  fn: () => Promise<Response>,
  maxRetries = 5
): Promise<Response> {
  let delay = 1000
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const response = await fn()
    if (response.status !== 429) return response

    const retryAfter = parseInt(response.headers.get('Retry-After') ?? String(delay / 1000))
    console.log(`Rate limited. Retrying in ${retryAfter}s (attempt ${attempt}/${maxRetries})`)
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000))
    delay = Math.min(delay * 2, 60000)
  }
  throw new Error('Exceeded maximum retry attempts due to rate limiting')
}
```

{% endtab %}
{% endtabs %}

### SDK Automatic Retry Behavior

Both the Python SDK (`amigo-sdk`) and TypeScript SDK (`@amigo-ai/sdk`) handle 429 responses automatically:

* The SDKs read the `Retry-After` header and wait the specified duration before retrying.
* Retries use exponential backoff for consecutive 429 responses.
* Network errors and 5xx server errors are also retried automatically.

{% hint style="success" %}
**No manual retry code needed when using the SDKs.** The built-in retry logic handles rate limiting transparently. See [Error Handling](/developer-guide/classic-api/sdks/sdk-error-handling.md) for details on configuring retry behavior.
{% endhint %}

## Best Practices

1. **Respect `Retry-After` headers.** Always use the server-provided delay rather than a fixed wait time.
2. **Use exponential backoff.** If the `Retry-After` header is absent, double the delay on each consecutive 429 (capped at 60 seconds).
3. **Monitor `X-RateLimit-Remaining` on the Platform API.** Proactively slow down requests as you approach the limit rather than waiting for a 429. Classic API responses do not expose a remaining-request header, so rely on backoff there.
4. **Batch where possible.** Some endpoints (such as tool invocation) accept multiple items in a single request, reducing the number of calls.
5. **Spread requests over time.** Avoid bursting all requests at the start of a rate-limit window.
6. **Use the SDKs.** The official Python and TypeScript SDKs handle 429 retries automatically with proper backoff.
7. **Design for the tightest limit.** Conversation creation and interaction are limited to 5 and 10 requests/min respectively. Architect your application to stay comfortably within these bounds.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/operations/reference/rate-limits.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
