---
title: "Bisque Errors"
description: "The error envelope, the common codes, and the rate limits."
canonical: https://bisque.cloud/docs/api/errors
---

# Errors

The error envelope, the common codes, and the rate limits.

Page: https://bisque.cloud/docs/api/errors

Every error is JSON with a stable code, a message for people, and a `requestId` to quote.

## The error envelope

```json
{
  "requestId": "…",
  "error": {
    "code": "INVALID_PRESENTATION_ID",
    "message": "presentationId query parameter is required.",
    "hint": "…"
  }
}
```

- `error.code` is upper snake case and stable; match on it.
- `error.message` is for people and can change.
- `error.hint`, when there is one, says where to look next.
- `requestId` is what to quote in a bug report.

Only `error`, with its `code` and `message`, is on every error; `requestId`
and `hint` are present when the endpoint has them. The OAuth endpoints answer
with RFC 6749 bodies instead, `{"error": "…", "error_description": "…"}`.

## Common codes

| Status | Code                                   | Meaning                                                                                                                              |
| ------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `401`  | `UNAUTHORIZED`, `INVALID_ACCESS_TOKEN` | The credential is missing, expired, or revoked. See [Authentication](/docs/api/authentication).                                           |
| `404`  | `NOT_FOUND`                            | No endpoint at that `/api` path. The body's `hint` names the OpenAPI document and the MCP server, and `docs` names the API overview. |
| `404`  | `PRESENTATION_NOT_FOUND`               | No presentation at that address, or one you cannot read.                                                                             |
| `405`  | `METHOD_NOT_ALLOWED`                   | The endpoint exists, but not for that HTTP method.                                                                                   |
| `422`  | `IDEMPOTENCY_KEY_REUSED`               | The same `Idempotency-Key` with a different body.                                                                                    |
| `429`  | `CONTEXT_RATE_LIMITED`                 | The per-IP window on `/api/presentations/context`. Wait `Retry-After` seconds.                                                       |

The live creation endpoints under `/v1/presentations` add their own. In every
case nothing was written.

| Status | Code                      | Meaning                                                                                                                                                |
| ------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400`  | `LIVE_APPEND_ONLY`        | An append removed, reordered, or inserted a slide before one already sent. The message names the first slide that moved.                               |
| `404`  | `NO_OPEN_CREATION`        | Nothing is open under that id. A finalized presentation answers this.                                                                                  |
| `409`  | `LIVE_TARGET_CHANGED`     | An append sent a `slug`, `handle`, `org`, or `visibility` different from the one the creation started with. Leave them out and the originals are used. |
| `409`  | `LIVE_REVISION_CONFLICT`  | The `baseRevision` you sent is behind the current `live.revision`. Read the presentation, then append after what is there.                             |
| `409`  | `LIVE_APPEND_IN_PROGRESS` | Another append or narration upload was still being written after 20 seconds. Try again.                                                                |
| `409`  | `CREATION_SUPERSEDED`     | Another publish of the same presentation replaced the open creation.                                                                                   |

## Rate limits

`GET` and `POST /api/presentations/context` are limited per IP: 60 requests
per 10 minutes without a credential, 300 with one. Every response from the
endpoint carries `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`
(seconds) and `RateLimit-Policy` (`60;w=600` without a credential,
`300;w=600` with one). A `429` adds `Retry-After`. In the batch form each item
costs one slot, and items past the window come back as `CONTEXT_RATE_LIMITED`
rows rather than failing the request.

The documentation MCP server, `POST /docs/mcp`, allows 120 requests per 10
minutes per IP.

Publishing endpoints have no request window.

Back to the [API overview](/docs/api). For the tool-level view of the same
API, see the [MCP servers](/docs/mcp).
