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

# Rate limits & retries

<div style={{position:'absolute',width:'1px',height:'1px',padding:0,margin:'-1px',overflow:'hidden',clipPath:'inset(50%)',whiteSpace:'nowrap',border:0}}>
  > **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
</div>

Blitz enforces a **per-endpoint** request-per-second limit (5 req/s per endpoint by default). The limit applies independently to each endpoint, so 5 req/s on `/enrichment/email` and 5 req/s on `/enrichment/phone` run at the same time without competing for the same budget. Both SDKs handle this for you: a client-side limiter keeps your outgoing requests under the cap, and any `429` that still slips through is retried automatically. In most cases you don't need to write any rate-limit handling yourself.

## Find your limit

Your per-endpoint limit is on `key_info()`. Trial and paid plans may differ — read it rather than hard-coding `5`.

<CodeGroup>
  ```python Python theme={null} theme={null}
  info = client.account.key_info()
  print(info.max_requests_per_seconds)   # your per-endpoint req/s limit
  ```

  ```ts TypeScript theme={null} theme={null}
  const info = await client.account.key_info();
  console.log(info.max_requests_per_seconds);  // your per-endpoint req/s limit
  ```
</CodeGroup>

See [Authentication](/guide/getting-started/authentication) for the full `key_info` response.

## Client-side rate limiting

Each client throttles its outgoing requests to `rate_limit_rps` (default `5`) **per endpoint** — every endpoint path gets its own limiter, mirroring the API's per-endpoint budget. In Python it's a **sliding window** (at most N requests to a given endpoint in any rolling second); in TypeScript it's a **token bucket** (admits at most N per second, per endpoint). A single client instance therefore stays under the API limit on every endpoint on its own. Set it to `None` / `null` to disable.

<CodeGroup>
  ```python Python theme={null} theme={null}
  client = BlitzAPI(rate_limit_rps=5.0)   # default; None to disable
  ```

  ```ts TypeScript theme={null} theme={null}
  const client = new BlitzAPI({ rate_limit_rps: 5 }); // default; null to disable
  ```
</CodeGroup>

<Tip>
  **Reuse one client per process.** The limiter lives on the client instance, so a single shared `client` keeps every endpoint's calls under its limit. Set `rate_limit_rps` to match `max_requests_per_seconds` from your key.
</Tip>

## Automatic retries

`429` (rate limited) and `5xx` (server errors) are retried automatically with exponential backoff — TypeScript adds jitter — up to `max_retries` (default `3`). `401` / `402` / `404` are **not** retried; they raise immediately. If the retries are exhausted, the error surfaces as `RateLimitError` (`429`) or `ServerError` / `APIStatusError` (`5xx`).

<CodeGroup>
  ```python Python theme={null} theme={null}
  from blitz_api import BlitzAPI, RateLimitError

  client = BlitzAPI(max_retries=5)   # default 3

  try:
      client.search.people(people={"job_level": ["VP"]})
  except RateLimitError:
      ...   # still 429 after retries — back off and try again later
  ```

  ```ts TypeScript theme={null} theme={null}
  import { BlitzAPI, RateLimitError } from "blitz-api-js";

  const client = new BlitzAPI({ max_retries: 5 }); // default 3

  try {
    await client.search.people({ people: { job_level: ["VP"] } });
  } catch (err) {
    if (err instanceof RateLimitError) {
      // still 429 after retries — back off and try again later
    }
  }
  ```
</CodeGroup>

## Timeouts are not retried

Each method takes a per-call `timeout` (Python keyword arg; TypeScript options object as the last argument). Unlike `429`/`5xx`, a **read timeout is not retried** — the server may already have processed (and billed) the request, so the SDK surfaces `APITimeoutError` immediately rather than risk a double charge. Raise the per-call timeout for genuinely slow endpoints instead of relying on retries.

<CodeGroup>
  ```python Python theme={null} theme={null}
  client.enrichment.email(person_linkedin_url="...", timeout=10.0)
  ```

  ```ts TypeScript theme={null} theme={null}
  await client.enrichment.email({ person_linkedin_url: "..." }, { timeout: 10 });
  ```
</CodeGroup>

## Running many workers

The limiter is **per client instance** (per process), and the API limit is **per endpoint**. If you fan the SDK out across multiple processes or workers that hit the **same endpoint**, their combined rate can exceed that endpoint's limit and you'll see `429`s — the retry path absorbs occasional ones, but for steady throughput divide `rate_limit_rps` across the workers sharing an endpoint (e.g. 5 workers all calling `/enrichment/email` on a 5 req/s key → `rate_limit_rps = 1` each). Workers calling **different** endpoints don't compete — each endpoint has its own budget.

## Next steps

<CardGroup cols={2}>
  <Card title="Pagination" icon="layer-group" href="/sdks/pagination">
    Stream results across pages and cap spend with `max_items`.
  </Card>

  <Card title="Python error handling" icon="python" href="/sdks/python#error-handling">
    The full exception hierarchy for `blitz-api-py`.
  </Card>

  <Card title="TypeScript error handling" icon="node-js" href="/sdks/typescript#error-handling">
    The full exception hierarchy for `blitz-api-js`.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/account/get-api-key-details">
    Request/response schemas and a try-it console.
  </Card>
</CardGroup>
