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

# Rate limits

> How boot and chat throttle requests, the 429 response you get, and how to back off cleanly.

The worker enforces rate limits on `POST /boot` and `POST /chat` to keep one visitor or one workspace from overwhelming the service. Limits apply at two levels: per visitor and per workspace. When a request crosses a limit, the worker rejects it with `429` and tells you when to retry.

## The 429 response

A throttled request returns status `429` with a JSON body and a `Retry-After` header (in seconds):

```json theme={null}
{
  "bucket": "chat/visitor-burst",
  "error": "rate_limit/exceeded"
}
```

<ResponseField name="bucket" type="string">
  Which limit you hit, so you can tell visitor throttling apart from workspace throttling.
</ResponseField>

<ResponseField name="error" type="string">
  Always `rate_limit/exceeded` for throttled requests.
</ResponseField>

Always read the `Retry-After` header and wait at least that long before retrying. Some responses also carry the same value as a `retryAfterSec` field.

<Note>
  Burst windows report a fixed 60-second `Retry-After`. Sustained per-visitor windows report the seconds remaining in the current window.
</Note>

## Limits

| Endpoint     | Scope                        | Limit               | Bucket                 |
| ------------ | ---------------------------- | ------------------- | ---------------------- |
| `POST /boot` | Per IP                       | 120 requests / 60s  | `boot/rate-limited`    |
| `POST /chat` | Per visitor (burst)          | 30 requests / 60s   | `chat/visitor-burst`   |
| `POST /chat` | Per workspace (burst)        | 1000 requests / 60s | `chat/tenant-burst`    |
| `POST /chat` | Per visitor (sustained)      | 100 requests / hour | `chat/visitor-hour`    |
| `POST /chat` | Per IP (no or invalid token) | 120 requests / 60s  | `chat/ip-rate-limited` |

A chat request can be checked against the visitor burst, workspace burst, and sustained per-visitor windows in turn. Requests that arrive without a valid visitor token fall back to the per-IP limit.

## Back off cleanly

<Steps>
  <Step title="Honor Retry-After">
    On a `429`, wait for the `Retry-After` interval before the next attempt. Do not retry immediately.
  </Step>

  <Step title="Add exponential backoff with jitter">
    If retries keep failing, grow the delay on each attempt (for example 1s, 2s, 4s) and add a small random offset so concurrent clients do not retry in lockstep.
  </Step>

  <Step title="Cap retries and surface the limit">
    Stop after a few attempts rather than looping. The embed runtime already paces its own requests, so persistent `429`s usually mean traffic is genuinely above the limit.
  </Step>
</Steps>

<Tip>
  The visitor JWT minted at `/boot` lives about 15 minutes. Reuse it across chat turns instead of calling `/boot` on every message, which keeps you well under the boot limit.
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="Errors" icon="triangle-alert" href="/errors">
    Every error namespace and status code, including the rate-limit envelope.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    How visitor sessions are minted and how programmatic API keys are scoped.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference">
    Request shapes and responses for the worker endpoints.
  </Card>
</CardGroup>
