# Errors

The Understory API can return errors in several cases.
These can be the result of an incorrect action from the client or a server-side incident.

In general whenever the API returns status codes between `400 - 599` a JSON body payload will be in the response containing details about the error.
The exception is `429 Too Many Requests`, whose body may differ; see [Rate limits](/docs/usage/rate-limits).

```json Error response example
{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error occurred while handling the request"
}
```

The `code` field will contain a unique code that identifies the issue.
This is intended for machine-reading and is considered an enum value.

The `message` field will contain a human readable description of the issue and possibly guidelines for resolving it.

## Error codes

Here is a list of error codes that you can encounter when interacting with the API.
Each code always comes with the same HTTP status.
New codes may be added, so handle an unknown `code` by its HTTP status.

| Code | Status | Description |
|  --- | --- | --- |
| `BAD_REQUEST` | `400` | The request is invalid, for example a missing or malformed parameter or body field. `message` says what to fix. |
| `UNAUTHORIZED` | `401` | The access token is missing, expired or revoked. Get a new token and retry once. |
| `FORBIDDEN` | `403` | The token is valid but lacks the scope the endpoint requires, or cannot access the resource. |
| `NOT_FOUND` | `404` | The resource does not exist, or is not visible to your credentials. |
| `CONFLICT` | `409` | The request conflicts with the current state of the resource, for example because it already exists. |
| `PRECONDITION_FAILED` | `412` | The resource is not in a state that allows the operation. |
| `TOO_MANY_REQUESTS` | `429` | You have reached a rate limit. See [Rate limits](/docs/usage/rate-limits). |
| `INTERNAL_SERVER_ERROR` | `500` | An internal server error occurred while handling the request. |
| `NOT_IMPLEMENTED` | `501` | The operation is not available yet. |
| `SERVICE_UNAVAILABLE` | `503` | A service needed to handle the request is temporarily unavailable. Retry with backoff. |
| `GATEWAY_TIMEOUT` | `504` | A service needed to handle the request did not respond in time. Retry with backoff. |


## Retrying

Retry `5XX` errors and `429` with backoff.
Do not retry other `4XX` errors unchanged: the same request will fail again.
Retrying a `POST` can create a duplicate unless the endpoint documents otherwise.