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

# Rate limits & errors

> Limits, headers, and the error shape used across all endpoints.

## Rate limits

Requests are limited to **1000 per minute per API key** (sliding window).
Every response carries the current state:

| Header                  | Meaning                             |
| ----------------------- | ----------------------------------- |
| `X-RateLimit-Limit`     | Max requests in the window          |
| `X-RateLimit-Remaining` | Requests left in the current window |
| `X-RateLimit-Reset`     | When the window resets (epoch ms)   |
| `Retry-After`           | Seconds to wait (only on `429`)     |

When exceeded you get `429`:

```json theme={null}
{ "error": "Rate limit exceeded" }
```

Wait for `Retry-After` seconds (or until `X-RateLimit-Reset`) and retry.
Rate-limited requests are rejected before any work happens, so they are
always safe to resend.

### Batch endpoints

The `/batch` endpoints share your key but use a **lower limit of 20 requests
per minute**. A single batch performs up to 1000 operations, so the
per-operation ceiling stays comparable. A batch body is capped at
**1000 items** (`400` over that).

## Error shape

Every error response is JSON with an `error` object carrying a stable,
machine-readable `code` (snake\_case) and a human `message`:

```json theme={null}
{ "error": { "code": "initiative_not_found", "message": "No initiative with that id exists in your organization." } }
```

Some errors carry extra fields alongside `code` and `message`:

* **`issues`**: per-field breakdown on validation failures
  (`code: "validation_failed"`).
* **`suggestions`**: "did you mean" candidates on unknown-type `404`s:

```json theme={null}
{ "error": { "code": "unknown_object_type", "message": "Unknown custom object type: ordr", "suggestions": ["order"] } }
```

Every response uses this shape, including authentication failures
(`unauthorized`) and rate limits (`rate_limited`).

## Status codes

| Status        | When                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` / `201` | Success                                                                                                                                                                                                                                                                                                                                                                                   |
| `400`         | Wrong `Content-Type` (`unsupported_content_type`), malformed JSON (`invalid_json`), schema validation failure (`validation_failed`, including an empty batch or one over the 1000-item cap), a bad pagination token (`invalid_cursor`), or a relationships list without an anchor (`unanchored_query`)                                                                                    |
| `401`         | Missing or invalid API key                                                                                                                                                                                                                                                                                                                                                                |
| `404`         | The resource (or one it references) doesn't exist in your organization. Codes follow the `*_not_found` pattern: `person_not_found`, `custom_object_not_found`, `event_not_found`, `segment_not_found`, `initiative_not_found`, `participant_not_found`, `journey_not_found`, `template_not_found`, and so on. Unknown custom object types return `unknown_object_type` with `suggestions` |
| `409`         | Conflicts with current state: duplicates (`duplicate_type_name`, `segment_slug_taken`, `template_name_taken`) or a wrong lifecycle state                                                                                                                                                                                                                                                  |
| `422`         | Syntactically valid but rejected semantically, e.g. launching an initiative that isn't ready (`initiative_not_ready`)                                                                                                                                                                                                                                                                     |
| `429`         | Rate limit exceeded                                                                                                                                                                                                                                                                                                                                                                       |
| `500`         | Unexpected server error (`internal_error`, internals are never leaked)                                                                                                                                                                                                                                                                                                                    |
| `503`         | A list query timed out (`query_timeout`). Narrow the filters or `limit`, then retry                                                                                                                                                                                                                                                                                                       |

<Note>
  Batch and participant endpoints report **per-item errors** inside a `2xx`
  response body (e.g. `contact_suppressed` when someone on your Do Not
  Contact list is skipped). The request succeeds while individual items
  fail. Always check the per-item `errors` array.
</Note>

<Note>
  Server errors return a generic message by design: they never echo stack
  traces or payload contents. Every response includes an `X-Request-Id`
  header; include it when contacting support about a failed request.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    How API keys and the `401` responses work.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/quickstart">
    See the request and response shapes in action.
  </Card>
</CardGroup>
