# Errors and limits

> When a request fails, the API answers with an HTTP status and a JSON error body. This page lists the error codes, the rate limits and when to retry a request.

Canonical HTML page: https://conclude.io/doc/api/errors/
Last updated: 2026-10-27

---

**The API is in beta.** API keys are available to organizations in the beta program. Requests and responses may still change, and we tell beta customers before they do. [Contact us](https://conclude.io/contact/) to get access.

When a request fails, the API answers with an HTTP status and a JSON error body. This page lists the error codes, the rate limits and when to retry a request.

## The error body

```json
{
  "error": {
    "code": "channel_access_denied",
    "message": "You do not have access to one of the channels",
    "requestID": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}
```

| Field | Description |
|---|---|
| `code` | What went wrong. Codes are stable, so your code can rely on them. |
| `message` | An English description for people. It can change, so don't parse it. |
| `param` | The request parameter or body field at fault, when there is one. A field inside the body is named with dots, as in `endpoints.1.channelID`. |
| `requestID` | Our ID for the request. Quote it when you contact support. |

The token endpoint uses the OAuth error body instead. See [Token errors](https://conclude.io/doc/api/authentication/#token-errors).

A path that the API doesn't serve returns `404` with a different body. Check the method and the path.

## Error codes

These codes can come from any endpoint.

| Status | Code | Meaning |
|---|---|---|
| 400 | `invalid_request` | The request is malformed. A parameter or field is missing or has the wrong value. `param` names it when it can. |
| 401 | `invalid_token` | The token is missing, malformed or expired. The key may be revoked or expired. The token may have been sent to a host other than `api.conclude.io`. Get a new token. If that fails, check the key. |
| 403 | `insufficient_scope` | The key doesn't have a scope this endpoint needs. The message names the scopes that work. |
| 403 | `forbidden` | The person the token acts for doesn't have the access or permission this request needs. |
| 404 | `not_found` | The resource doesn't exist, or the person the token acts for can't see it. |
| 409 | `conflict` | The request conflicts with the current state. |
| 410 | `gone` | The resource has been deleted, for example your organization. |
| 429 | `rate_limited` | The key made too many requests. See [Rate limits](#rate-limits). |
| 500 | `internal_error` | Something went wrong on our end. The message doesn't say what. Quote the `requestID` if you contact support. |
| 503 | `unavailable` | Conclude couldn't finish the request. Try again. |

These codes come from the requests on the [Connections](https://conclude.io/doc/api/connections/) page.

| Status | Code | Meaning |
|---|---|---|
| 400 | `channel_not_connectable` | The channel can't be connected. It is archived or deleted, or it is not a regular channel. |
| 403 | `subject_required` | A key that acts as Conclude tried to change a connection without a subject. Ask for a token with a [subject](https://conclude.io/doc/api/authentication/#acts-as). |
| 403 | `conclude_not_in_channel` | A key that acts as Conclude named a channel that Conclude doesn't reach. Add Conclude to the channel first. |
| 403 | `channel_access_denied` | The person the token acts for can't access the channel. |
| 403 | `connections_disabled` | Channel connections are turned off for your organization. |
| 409 | `already_connected` | The channel is already in a connection. A channel can be in only one. |

## Rate limits

- Each key can make at least 25 requests a second, with bursts of up to 50.
- The token endpoint accepts 60 requests a minute from one IP address.

Above the limit, Conclude answers `429` with a `Retry-After` header. It gives the number of seconds to wait before you try again.

## Retries

Retry a request after these errors:

- `429`: wait for the seconds in `Retry-After`.
- `503`: try again after a short wait.
- `500` on a `GET`: try again after a short wait. If it keeps failing, contact support with the `requestID`.

A write that failed with a network error or a `500` may still have taken effect. Check before you send it again. For example, look the channel up with [`GET /v1/findChannel`](https://conclude.io/doc/api/organization/#find-channels) and read `connected`. A repeated create answers `already_connected` when the first one succeeded.

Don't retry other `4xx` errors unchanged. Fix the request first.

