# Errors (/docs/api-reference/errors)



The careCycle API uses standard HTTP status codes. A `2xx` status means the
request succeeded. Errors return a JSON body with a human-readable `message` and
a machine-readable `code`.

Error format [#error-format]

```json
{
  "message": "A customer with this MBI already exists",
  "code": "CUSTOMER_ALREADY_EXISTS"
}
```

Branch on `code` (or on the HTTP status when no code you recognize is present).
Do not parse `message`: it is written for people and can change.

Some errors carry extra fields:

| Status       | Extra field     | Contents                                                                                        |
| ------------ | --------------- | ----------------------------------------------------------------------------------------------- |
| `400`, `409` | `details`       | An object with more context about the problem, when available                                   |
| `422`        | `errors`        | One entry per invalid field: `path`, `message`, `code`, and sometimes `expected` and `received` |
| `422`        | `failedRecords` | Sync endpoints only: identifiers of the records that failed validation                          |
| `429`        | `retryAfter`    | Seconds to wait before retrying. See [Rate limits](/docs/api-reference/rate-limits)             |

A validation error looks like this:

```json
{
  "message": "Validation failed",
  "code": "VALIDATION_ERROR",
  "errors": [
    {
      "path": ["email"],
      "message": "Invalid email address",
      "code": "invalid_format"
    }
  ]
}
```

Error codes [#error-codes]

| Status | Code                    | Meaning                                                               | How to recover                                                                                       |
| ------ | ----------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `400`  | `BAD_REQUEST`           | The request is well formed but not valid for this operation           | Read `message` and `details`, fix the request, and retry. Retrying unchanged fails again             |
| `401`  | `UNAUTHORIZED`          | The API key is missing or invalid                                     | Send a valid key in the `x-api-key` header. See [Authentication](/docs/api-reference/authentication) |
| `403`  | `FORBIDDEN`             | The key is valid but lacks the capability this endpoint needs         | Create a key with the required capability. Retrying with the same key fails again                    |
| `404`  | `NOT_FOUND`             | The resource does not exist, or your key can't access it              | Check the ID. Do not retry                                                                           |
| `409`  | `CONFLICT`              | The request conflicts with the current state, for example a duplicate | Fetch the current state, then decide whether to update the existing resource or change the request   |
| `422`  | `VALIDATION_ERROR`      | The request failed schema validation                                  | Fix each field listed in `errors`, then retry                                                        |
| `429`  | `RATE_LIMIT_EXCEEDED`   | The key exceeded its rate limit                                       | Wait `retryAfter` seconds, then retry. See [Rate limits](/docs/api-reference/rate-limits)            |
| `500`  | `INTERNAL_SERVER_ERROR` | Something went wrong on careCycle's side                              | Retry with exponential backoff. If it persists, contact support                                      |
| `503`  | `SERVICE_UNAVAILABLE`   | The service is temporarily unavailable                                | Retry with exponential backoff                                                                       |

Endpoint-specific codes [#endpoint-specific-codes]

Some endpoints return a more specific `code` with one of the statuses above.
For example, creating a customer whose MBI is already on file returns `409`
with `CUSTOMER_ALREADY_EXISTS`, and booking an appointment slot that was just
taken returns `409` with `SLOT_NO_LONGER_AVAILABLE`. Each endpoint page lists
the statuses it can return. Treat any code you don't recognize according to its
HTTP status.

Server errors [#server-errors]

`5xx` responses always use a generic `message`, so the body does not explain the
failure. Before retrying a `POST` that creates something, check whether the
first attempt succeeded, to avoid creating a duplicate.

Errors outside the standard format [#errors-outside-the-standard-format]

A few errors are returned before a request reaches an endpoint and use an
`error` field instead of `code`:

* **Malformed JSON** returns `400` with `"error": "Invalid JSON"`.
* **Request bodies over 2 MB** return `413`.

Fix the request body before retrying.

Request IDs [#request-ids]

Every response includes an `X-Request-Id` header. Include it when you contact
careCycle support about a specific request.
