> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sixtyfour.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limits

> Every Sixtyfour API rate and concurrency limit, the headers a 429 carries, and how to retry.

Limits apply per organization. Every API key and OAuth token in an organization, including keys used through the [MCP server](https://docs.sixtyfour.ai/developer-tools/mcp-setup.md), draws on the same budgets. A request over a rate limit returns `429` with a `Retry-After` header, and nothing runs.

## How limits are counted

| Kind | How it counts | A `429` carries |
| - | - | - |
| Per-minute limit | Requests in any 60-second window | `Retry-After` |
| Burst budget | Up to the burst at once, then a steady refill. 300 per minute with a burst of 15 admits 15 requests at once, then 5 a second | `Retry-After` and the `X-RateLimit-*` headers |

A request counts once it is admitted, even if it fails afterwards. Each endpoint has its own budget unless a table below says it shares one.

Requests from a signed-in session in the Sixtyfour web app skip the burst budgets: status polling, result downloads, and history exports. They count toward per-minute limits like any other request. API keys and OAuth tokens never skip a limit.

## Status polling

| Endpoint | Limit |
| - | - |
| [`GET /job-status/{job_id}`](https://docs.sixtyfour.ai/api-reference/enrichment/job-status) and `GET /workflows/runs/{run_id}/live_status` | 300 per minute, burst 15, one budget shared by both |

`GET /job-status` answers are cached for up to 10 seconds, so polling a job more often returns the same answer. At one poll every 10 seconds, the budget covers about 50 jobs or runs in flight. Spread the polls out instead of polling every job at the same moment.

For more work than that, pass `webhook_url` and poll only as a fallback. See [Outgoing Webhooks](https://docs.sixtyfour.ai/api-reference/webhooks/outgoing.md).

A `429` on a status read does not affect the job. Wait for `Retry-After` and read again; do not restart the job. [Async jobs](https://docs.sixtyfour.ai/api-reference/async-jobs.md#polling) has a polling helper that does this.

## Limits by endpoint

### Intelligence and contact

| Endpoint | Limit | Notes |
| - | - | - |
| `POST /bulk-intelligence/people`, `POST /bulk-intelligence/company` | 10 per minute each | A replay with the same `Idempotency-Key` does not count |
| `POST /verify-email` | 120 per minute | |
| `GET /check-balance` | 60 per minute | |

### Workflows

| Endpoint | Limit | Notes |
| - | - | - |
| `POST /workflows/run` | 120 per minute | A retry with the same `Idempotency-Key` that returns the run it already started does not count. This limit is being turned on one organization at a time; until it is on for yours, starts above it are accepted |
| `GET /workflows/runs/{run_id}/results/download-links` | 5 per second, burst 15 | Burst budget. See [Workflow result download retries](https://docs.sixtyfour.ai/api-reference/errors.md#workflow-result-download-retries) |
| Downloading a file from a `download_url` | 60 per minute, burst 5 | Burst budget, shared by workflow result links, webhook result links, and `GET /search/download` links |
| `GET /templates`, `GET /templates/{template_key}` | 120 per minute | One budget for both. Requests without credentials count per IP address |
| `GET /templates/available` | 120 per minute | |

### Search

| Endpoint | Limit | Notes |
| - | - | - |
| `POST /search/start-deep-search` | 200 per minute | Also 5 running at a time. See [Concurrency limits](#concurrency-limits) |
| `POST /search/query` | 200 per minute | |
| `POST /search/start-filter-search` | 200 per minute | Deprecated; use `POST /search/query` |
| `POST /search/filter-field-values` | 200 per minute | |
| `GET /search/filter-capabilities` | 300 per minute | |
| `POST /search/lookalike` | 200 per minute | `GET /search/lookalike/{task_id}` is not limited |
| `POST /search/export` | 10 per minute | |

### Monitors

| Endpoint | Limit | Notes |
| - | - | - |
| `POST /monitors/upload` | 10 per minute | Replays count |
| `POST /monitors/{monitor_id}/history-export` | 300 per minute, burst 15 | Burst budget. Also 5 builds at a time. See [Concurrency limits](#concurrency-limits) |

### Atlas

| Endpoint | Limit | Notes |
| - | - | - |
| `/v1/atlas/*` | 120 per minute | One budget across every Atlas endpoint. Each connection and reconnection to the event stream counts |

### Webhooks

| Endpoint | Limit | Notes |
| - | - | - |
| `POST /webhooks/test-events` | 10 per minute | |

### Media

| Endpoint | Limit | Notes |
| - | - | - |
| `GET /v1/media/{token}` | 600 per minute per IP address | |
| `GET /v1/media/profiles/{key}` | 600 per minute per IP address | Separate budget |

### OAuth tokens

`POST /oauth/token` issues up to 60 tokens per minute per client. Requests that fail client authentication, or are still being checked, also count toward 25 per minute per client and toward 120 per minute shared with other callers. A request that authenticates does not count toward those two. Reuse each token until shortly before its `expires_in` instead of requesting one per call. See [Using OAuth Clients](https://docs.sixtyfour.ai/guides/oauth-clients.md).

## Concurrency limits

### Deep search

Each organization runs up to 5 deep searches at a time, people and company combined. A start above that is never refused with `429`. It returns `200` with `status: "running"`, and the search then ends `failed` with this `error`:

```text theme={null}
Concurrency limit reached: max 5 concurrent deep_search requests. Please wait for an existing request to complete.
```

On some accounts, lookalike searches also take one of the five slots. Start a new deep search only after one of yours reaches a final status.

### History exports

All callers, web app sessions included, share 5 history-export builds at a time per organization. A sixth returns `429` with `Retry-After: 5`:

```json theme={null}
{
  "detail": "Five history exports are already building for this organization. Retry later."
}
```

## Response headers

| Header | Sent on | Meaning |
| - | - | - |
| `Retry-After` | Every `429`, and `503` responses you can retry | Seconds to wait before retrying |
| `X-RateLimit-Requests` | `429` from a burst budget | Requests added per period |
| `X-RateLimit-Period` | `429` from a burst budget | The period, in seconds |
| `X-RateLimit-Burst` | `429` from a burst budget | Requests available at once after idling |

Successful responses carry no `X-RateLimit-*` headers.

A `429` from the status polling budget:

```http theme={null}
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Requests: 300
X-RateLimit-Period: 60
X-RateLimit-Burst: 15
Content-Type: application/json

{"detail": "Rate limit exceeded: 300 requests per 60 second(s) per organization, with a burst of 15, shared across API servers. Retry after Retry-After; do not restart the job."}
```

A `429` from a per-minute limit:

```json theme={null}
{
  "detail": "Rate limit exceeded: 120 requests per 1 minutes. Please retry after 12 seconds."
}
```

When Sixtyfour cannot count requests against a burst budget, the endpoint returns `503` with `Retry-After: 15` and a `detail` that starts with `Request capacity is temporarily unavailable.`

## Retry after a 429

* Wait at least `Retry-After` seconds, then send the same request again.
* Workers that share an organization share its budgets. Coordinate them, and add a small random delay after the server's minimum.
* Stop after a bounded number of attempts.
* For many records, use async endpoints, [Bulk Intelligence](https://docs.sixtyfour.ai/api-reference/endpoint/bulk-intelligence.md), or the [Workflows API](https://docs.sixtyfour.ai/api-reference/workflows/workflows-overview.md) instead of many synchronous calls.

This helper retries `429` and `503` responses after `Retry-After`:

```python theme={null}
import time
import requests

def post_with_retry(url, headers, data, max_retries=5):
    for attempt in range(max_retries):
        response = requests.post(url, headers=headers, json=data)
        if response.status_code in (429, 503):
            time.sleep(int(response.headers.get("Retry-After", 2 ** attempt)))
            continue
        response.raise_for_status()
        return response.json()
    raise Exception("Max retries exceeded")
```

Contact [support@sixtyfour.ai](mailto:support@sixtyfour.ai) if a limit blocks your integration. For other status codes, see [Handling Errors](https://docs.sixtyfour.ai/api-reference/errors.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.