# Rate limits

Rate limits protect service availability and latency. Requests that exceed a
limit return `429 Too Many Requests` with a `Retry-After` header.

## What's limited

Requests can be limited for two reasons:

| Condition | Response |
| --- | --- |
| Workspace request rate exceeded | [`429 rate_limit_exceeded`](/errors#429) |
| Service temporarily at capacity | [`429 service_busy`](/errors#429) |

Your workspace has a sustained request-rate limit. If you need a committed
rate or a higher limit, [contact us](mailto:support@celeris.ai).

All inference usage draws from prepaid workspace credit.

Other constraints to design for:

- **Rate limits are workspace-wide.** All API keys in a workspace share the
  same request-rate limit and credit balance.
- **Short bursts may still be limited.** Design clients to handle `429`
  responses even when average traffic is below the stated sustained rate.
- **Token limits are model-specific.** For `celeris-1`, prompt tokens plus
  `max_tokens` must be at most 131,072. `max_tokens` can be any positive integer
  that fits the context window. Requests over the [model limit](/models) return
  [`400 Bad Request`](/errors#400).

## When you hit a limit

Over-limit requests fail fast with **`429`**, code `rate_limit_exceeded`, and a
`Retry-After` header (in seconds):

```http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 1

{"error": {"message": "You have exceeded your workspace's request rate. Slow down and retry, or contact support for a higher sustained limit.", "type": "rate_limit_exceeded", "code": "rate_limit_exceeded"}}
```

A `429 service_busy` response means the service is temporarily at capacity.
Handle it in the same way: honor `Retry-After` and retry with backoff. See
[Errors](/errors#429) for details.

An out-of-credit workspace returns **`402 insufficient_quota`**. Add credit
before retrying. See [Errors](/errors#402).

## Backing off well

Wait at least as long as `Retry-After`, use exponential backoff with jitter for
subsequent attempts, and cap the number of retries:

```python

from openai import APIStatusError

def with_backoff(call, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return call()
        except APIStatusError as err:
            if err.status_code not in (429, 502, 503) or attempt == max_attempts - 1:
                raise
            retry_after = float(err.response.headers.get("retry-after", 1))
            # Full jitter: sleep somewhere in [retry_after, retry_after + 2^attempt)
            time.sleep(retry_after + random.uniform(0, 2 ** attempt))
```

For applications with multiple workers, enforce a shared client-side
concurrency limit. This is more predictable than independent retry loops in
each worker.

## Watching your usage

The [Console's usage page](/console#usage) shows completed requests and token
volumes. It does not include throttled requests, so monitor `429` responses in
your application logs and metrics.
