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

# Limits

The beta's default limits per organization, how to read your current usage against them, and what the API returns when you hit one.

Limits keep one organization from crowding out the others on a shared node. Each limit has an ID, and the same ID appears wherever that limit shows up: in `GET /v1/limits`, in the `limit` member of an error and in the `RateLimit-Policy` header.

## Beta defaults

These apply per organization unless your account says otherwise:

| Limit ID | Product | Kind | Beta default | Unit | Window |
|---|---|---|---|---|---|
| `sandboxes.concurrent` | sandboxes | concurrency | 10 | sandboxes |  |
| `sandboxes.vcpu_max` | sandboxes | size | 2 | vcpu |  |
| `sandboxes.memory_max` | sandboxes | size | 2048 | MiB |  |
| `sandboxes.disk_max` | sandboxes | size | 16 | GiB |  |
| `sandboxes.timeout_max` | sandboxes | duration | 3600 | seconds |  |
| `vision.sessions.concurrent` | vision | concurrency | 5 | sessions |  |
| `vision.session.timeout_max` | vision | duration | 1800 | seconds |  |
| `vision.scrape.rpm` | vision | rate | 60 | requests | 60 s |
| `vision.scrape.concurrent` | vision | concurrency | 5 | requests |  |
| `vision.crawl.pages_max` | vision | size | 500 | pages |  |
| `vision.crawl.concurrent` | vision | concurrency | 1 | crawls |  |
| `render.concurrent` | render | concurrency | 2 | renders |  |
| `routines.steps.daily` | routines | quota | 50000 | steps | 86400 s |
| `actions.rpm` | actions | rate | 300 | requests | 60 s |
| `infer.tpm.<model>` | infer | rate | per model | tokens | 60 s |
| `egress.bytes.daily` | platform | quota | per model | bytes | 86400 s |

Model limits differ per model; `GET /v1/infer/models` lists each model's tokens per minute and requests per minute for you. Each product's limits page lists the size limits of single requests, such as the most URLs in one batch.

## Read your limits

Any valid credential can read the limits that apply to it, with current usage:

```bash
curl -s https://beta-api.b3os.org/v1/limits -H "Authorization: Bearer $B3OS_API_KEY"
```

```json
{
  "object": "limits",
  "spend": { "cap_usd": 50, "used_usd": 1.42, "period_start": "2026-10-01T00:00:00.000Z", "period_end": "2026-11-01T00:00:00.000Z" },
  "items": [
    { "id": "sandboxes.concurrent", "product": "sandboxes", "kind": "concurrency", "limit": 10, "unit": "sandboxes", "current": 2 },
    { "id": "vision.scrape.rpm", "product": "vision", "kind": "rate", "limit": 60, "unit": "requests", "window_s": 60, "current": 14, "reset_s": 38 }
  ]
}
```

This example is abridged. `spend` shows the calling key's spend cap and what it has used this period.

## When you hit a limit

| Status and code | When | What to do |
|---|---|---|
| `429` [`rate_limited`](/errors#rate_limited) | Too many requests in the current window | Wait `Retry-After` seconds |
| `429` [`concurrency_limited`](/errors#concurrency_limited) | Too many operations of one kind running at once | Wait for one to finish, or stop one |
| `429` [`quota_exceeded`](/errors#quota_exceeded) | A daily or monthly quota is used up | Wait for the window to reset |
| `422` [`limit_exceeded`](/errors#limit_exceeded) | One request asks for more than a limit allows, such as `vcpu: 4` | Ask for less |
| `402` [`spend_cap_exceeded`](/errors#spend_cap_exceeded) | The key reached its spend cap | Raise the cap or use another key |
| `402` [`credits_exhausted`](/errors#credits_exhausted) | The organization has no credits left | Add credits in the dashboard |

`429` responses carry `Retry-After` and the `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` and `RateLimit-Policy` headers. The problem body repeats the wait as `retry_after_s` and names the limit in `limit`:

```json
{
  "type": "https://docs.beta.b3os.org/errors#rate_limited",
  "title": "Rate limited",
  "status": 429,
  "code": "rate_limited",
  "detail": "60 scrapes per minute allowed; retry in 12 seconds",
  "instance": "req_01m5t4yg394wegr3j4y01qb363",
  "retry_after_s": 12,
  "limit": { "id": "vision.scrape.rpm", "limit": 60, "unit": "requests", "window_s": 60, "current": 60 }
}
```

The SDKs retry `429` and `5xx` responses of idempotent calls with jittered backoff. Your own clients should wait at least `Retry-After` seconds before trying again.

## Limits on the node

The node enforces the limits on sandboxes, inference tokens and egress itself, with counters it refreshes from the edge every few seconds. Calls from inside a sandbox never pass through the edge and are capped all the same.