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

# Errors

> Error codes returned by the Custral API.

The Custral API returns a structured JSON body for every non-2xx response. Every error has a stable string `code` you can match against, plus a human-readable `message` and optional `details`, and the `reqId` of the failing request.

## Response shape

```json theme={null}
{
  "type": "error",
  "error": {
    "code": "authorization_invalid",
    "message": "The provided session token is not valid or has expired.",
    "data": {}
  }
}
```

## HTTP status convention

* `400`: request shape invalid (a field is missing or the wrong type).
* `401`: `authorization_missing` or `authorization_invalid`.
* `403`: authenticated, but not allowed: `organization_invalid`, scope violations, ACL denials.
* `404`: `*_not_found` codes.
* `409`: write conflicts (uniqueness violations, optimistic-lock failures).
* `422`: domain validation (e.g. `storage_limit_reached`, `domains_limit_reached`).
* `5xx`: internal errors. The body still carries a `code`; record the request id from the response headers when reporting.

## Common codes by group

### Auth

| Code                    | Meaning                                                                    | How to recover                                                                                                                                                                                                        |
| ----------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorization_missing` | No credential was sent with the request.                                   | Send your API key as a Bearer token. See [Authentication](/dev/auth/overview).                                                                                                                                        |
| `authorization_invalid` | The token does not match an active session.                                | Re-authenticate; tokens expire.                                                                                                                                                                                       |
| `organization_invalid`  | The caller is authenticated, but has no access to the requested workspace. | Check the key belongs to that workspace, `GET /v1/me` reports its org.                                                                                                                                                |
| `unauthorized`          | Bearer token did not match a known integration.                            | Generate a new API key from the workspace.                                                                                                                                                                            |
| `invalid_api_key`       | The API key supplied is not a recognized integration key.                  | Re-issue from the integrations page.                                                                                                                                                                                  |
| `insufficient_scope`    | The key is valid, but was not granted the scope this endpoint requires.    | Check the key's scopes with `GET /v1/me`, then mint one with the scope it needs. See [Applications & keys](/dev/api-reference/applications). A key minted with no scopes hits this on every endpoint except `/v1/me`. |

### Validation

| Code                 | Meaning                                                                              |
| -------------------- | ------------------------------------------------------------------------------------ |
| `request_invalid`    | The request body failed validation. The `data` field carries the field-level errors. |
| `invalid_payload`    | A specific endpoint rejected the body shape.                                         |
| `query_required`     | A required query param was missing.                                                  |
| `entity_id_required` | A path param was missing.                                                            |

### Limits

| Code                      | Meaning                                          |
| ------------------------- | ------------------------------------------------ |
| `storage_limit_reached`   | Workspace has hit its storage quota.             |
| `domains_limit_reached`   | Workspace cannot add more sending domains.       |
| `mailboxes_limit_reached` | Workspace cannot connect more mailboxes.         |
| `file_type_not_allowed`   | The uploaded file type is blocked by org policy. |

### Not found

| Code                 | Meaning                                                        |
| -------------------- | -------------------------------------------------------------- |
| `record_not_found`   | The record id does not exist or you do not have access to it.  |
| `object_not_found`   | The object id does not exist.                                  |
| `resource_not_found` | The uploaded resource id does not exist.                       |
| `action_not_found`   | A workflow action by id does not exist.                        |
| `not_found`          | A generic-fallback "not found" used by less-curated endpoints. |

### Workflow / blueprint

| Code                     | Meaning                                             |
| ------------------------ | --------------------------------------------------- |
| `workflow_invalid`       | The workflow definition is missing required fields. |
| `block_invalid`          | A workflow block id is not registered.              |
| `node_invalid`           | A workflow node references an unknown action key.   |
| `trigger_invalid`        | The trigger configuration is malformed.             |
| `edge_invalid`           | An edge points to an unknown source or target.      |
| `circular_link_detected` | Adding the edge would create a cycle.               |

### Conversation / action

| Code                  | Meaning                                                   |
| --------------------- | --------------------------------------------------------- |
| `action_not_approved` | A conversation action is referenced but not yet approved. |
| `setup_invalid`       | The trigger setup payload is malformed.                   |

## Long tail

The codes above cover the failures you'll meet in normal integration work, but the API can return others in narrower situations. Every one is a stable string, so it's safe to branch on a code you see in the wild even if it isn't listed here yet.

If you hit one you can't place, email [hello@custral.com](mailto:hello@custral.com) with the code and the `reqId` from the same response (the request id is what lets us find your exact call) and we'll explain it and add it to this page.


## Related topics

- [TypeScript SDK](/dev/sdks/typescript.md)
- [Browser SDK](/dev/sdks/browser.md)
- [Authentication](/dev/auth/overview.md)
- [Request logs](/dev/logs.md)
- [Delivery and retries](/dev/webhooks/delivery.md)
