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

# Rate limits

> How Lusor limits request rates, and how to handle a 429.

Lusor limits how many requests your account can make in a short time. The limit applies to every authenticated `/v1` request and is counted per account, across all its workspaces and API keys. `GET /v1/health` is not limited.

## Read the headers

Every limited response carries two headers:

| Header | Meaning |
| - | - |
| `X-RateLimit-Limit` | The most requests you can send in a burst. |
| `X-RateLimit-Remaining` | How many you can still send right now. It refills steadily over time. |

## When you hit the limit

The API returns `429`:

```json theme={null}
{ "error": "rate_limit_exceeded", "message": "Too many requests. Retry in 2s." }
```

The `Retry-After` header says how many seconds to wait. Wait that long, then retry.

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

def get(url, headers):
    while True:
        r = requests.get(url, headers=headers)
        if r.status_code != 429 or r.json().get("error") != "rate_limit_exceeded":
            return r
        time.sleep(int(r.headers.get("Retry-After", "1")))
```

```javascript Node.js theme={null}
async function get(url, headers) {
  while (true) {
    const res = await fetch(url, { headers });
    if (res.status !== 429) return res;
    const body = await res.clone().json();
    if (body.error !== "rate_limit_exceeded") return res;
    const wait = Number(res.headers.get("Retry-After") ?? "1");
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
}
```

## Other 429 responses

Not every `429` is a rate limit. Check `error`:

| `error` | Meaning | What to do |
| - | - | - |
| `rate_limit_exceeded` | Too many requests. | Wait `Retry-After` seconds. |
| `device_busy` | The phone is working on another session, named in `currentSessionId`. | Wait for that session to finish, or [stop it](https://docs.lusor.ai/agents/stop-a-session.md). Retrying sooner does not help. |

## Keep your request rate low

* Poll `GET /v1/sessions/{id}/status` every few seconds, not in a tight loop. It is the cheapest way to watch a session.
* When reading events, pass `since` so each call returns only new events.
* Send several actions to a phone as one chain instead of one request each. See [Direct phone control](https://docs.lusor.ai/phones/direct-control.md).


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