> For the complete documentation index, see [llms.txt](https://developer.abacum.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.abacum.ai/essentials/concepts/errors.md).

# Errors

The status codes the API returns, and what to do about each one.

| Status | Meaning                                                                                                                                                                         | What to do                                                                       |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `200`  | The request succeeded.                                                                                                                                                          | -                                                                                |
| `400`  | A parameter or a body field is not valid.                                                                                                                                       | Read the error message. Correct the request.                                     |
| `401`  | The client ID or the client secret is not valid, on the token request. Or the request to `GET /public-api/api-spec` carried an `Authorization` header. This endpoint is public. | Check the credentials. Call `api-spec` without an `Authorization` header.        |
| `403`  | The token is missing, malformed or expired. Or the user does not have permission for the resource.                                                                              | Request a new token. If the error continues, check the role of the user.         |
| `404`  | The resource does not exist, or the user cannot see it. IDs in the path must be UUIDs. Any other value returns `404`.                                                           | Check the ID in the path.                                                        |
| `422`  | A load for the same period range already runs. Import API only.                                                                                                                 | Wait for the load to finish. Then send the request again.                        |
| `429`  | You exceeded a rate limit.                                                                                                                                                      | Wait for the number of seconds in the `Retry-After` header.                      |
| `500`  | The server could not process the request.                                                                                                                                       | Send the request again one time. If the error continues, contact Abacum support. |

{% hint style="info" %}
On every endpoint except the token endpoint, a missing, malformed or expired token returns `403`. The response body is empty.
{% endhint %}

## Error body

Most errors return one message in an `error` field:

```json
{
  "error": "Both 'start_date' and 'end_date' are required when filtering by period."
}
```

A `400` from `POST /public-api/load-data` can also return the errors for each field, keyed by field name:

```json
{
  "months": ["At least one month must be provided."]
}
```

Some endpoints return a `detail` field instead. That is the case for the `403` of a user without the role, the `404` of the Spaces and search endpoints, and the `429` of every endpoint:

```json
{
  "detail": "Invalid page."
}
```

The `400` of the search and Space table data endpoints keys the messages by parameter name, like the field errors of a load. The token endpoint returns the OAuth fields `error` and `error_description`.

## Request ID

Every response from a `/public-api/` endpoint carries an `X-Request-ID` header, on success and on every error status. Give its value to support, so that we can find the exact request. A request that is rejected before it reaches the API, such as an unknown path or a CORS preflight, has none.

A server-side client can send its own `X-Request-ID` of 1 to 64 characters from `A-Za-z0-9_-`, and the API sends the same value back. Any other value is replaced by a generated one. A browser can read the header but cannot send its own.
