> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.chaser.sh/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.chaser.sh/_mcp/server.

# Limits and Errors

Rate limits, concurrency caps, and error reference.

## Session limits

| Limit | Value |
|---|---|
| Max concurrent sessions per workspace | 10 |
| Max TTL | 3600 seconds (1 hour) |
| Default TTL | 1800 seconds (30 minutes) |
| Min TTL | 60 seconds |
| Max session creations per minute | 20 |

## Rate limits

| Endpoint | Limit |
|---|---|
| `POST /v1/sessions` | 20 per minute per workspace |
| `POST /v1/sessions/:id/screenshot` | 60 per minute per session |
| `POST /v1/sessions/:id/preview-token` | 10 per minute per session |

Rate limit responses include a `Retry-After` header with the number of seconds to wait.

## Error format

All errors follow a consistent shape:

```json
{
  "error": {
    "code": "error_code",
    "message": "Human-readable description."
  }
}
```

## Error reference

### Session errors

| Status | Code | Message | Meaning |
|---|---|---|---|
| 404 | `session_not_found` | Session not found. | The session doesn't exist or belongs to a different workspace. |
| 409 | `session_not_open` | Session is already in a terminal state. | The session is closed or expired. Already stopped — safe to ignore on cleanup. |
| 409 | `session_not_ready` | Session is not ready yet. | Still provisioning. Wait and retry. |

### Rate limit errors

| Status | Code | Message | Meaning |
|---|---|---|---|
| 429 | `rate_limited` | Too many requests. | You've hit a rate limit. Check `Retry-After` header. |
| 429 | `concurrency_limit` | Concurrency limit reached. | Too many active sessions. Delete some before creating more. |

### Billing errors

| Status | Code | Message | Meaning |
|---|---|---|---|
| 402 | `payment_required` | Insufficient balance. | Workspace balance is zero. Top up to create new sessions. |

### Authentication errors

| Status | Code | Message | Meaning |
|---|---|---|---|
| 401 | `unauthorized` | Missing or invalid API key. | Check the `Authorization: Bearer` header. |
| 403 | `forbidden` | Access denied. | The key is valid but doesn't have access to the requested resource. |

### Input errors

| Status | Code | Message | Meaning |
|---|---|---|---|
| 400 | `invalid_request` | Request body is malformed. | Check the request body against the API reference. |
| 400 | `invalid_field` | Invalid value for field: `field_name`. | A field value is out of range or wrong type. |

## Retry guidance

- **`429 rate_limited`** — wait the number of seconds in `Retry-After`, then retry.
- **`409 session_not_ready`** — wait 2 seconds and poll again.
- **`500` or `503`** — transient server error. Retry with exponential backoff.
- **`409 session_not_open`** — the session is already dead. No retry needed.