> ## 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": { "code": "rate_limited", "message": "Rate limit exceeded. Retry after the indicated delay." } }
```

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 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).

This is a **separate budget**: batch requests are counted on their own, so
ordinary traffic on your key never consumes your batch allowance and vice
versa. `X-RateLimit-Limit` reflects the ceiling of whichever budget handled
the request — `1000` on standard endpoints, `20` on `/batch` ones.

## 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`; the `message` gives the parse error and, when known, its character position in the body), 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`, `initiative_name_taken`) or a wrong lifecycle state — including an action that would be a no-op, e.g. `initiative_already_archived` / `initiative_not_archived` |
| `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>


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