***

title: Errors
subtitle: Error types, response format, and handling guidance
slug: api-guides/errors
---------------------

For clean Markdown of any page, append .md to the page URL. For a complete documentation index, see https://docs.prolifi.io/api-guides/llms.txt. For full documentation content, see https://docs.prolifi.io/api-guides/llms-full.txt.

## Error response format

All API errors follow a consistent structure:

```json
{
  "error": {
    "type": "validation_error",
    "message": "The request data is invalid.",
    "errors": [
      {
        "field": "email",
        "message": "The email field is required."
      }
    ]
  }
}
```

The `error.type` field is a machine-readable string you can use in your code. The `error.message` field is a human-readable description. The `error.errors` array is only present for validation errors and contains field-level details.

## Error types

| Type                   | Status    | Description                                                                            |
| ---------------------- | --------- | -------------------------------------------------------------------------------------- |
| `authentication_error` | 401       | Missing, invalid, or unrecognised API key                                              |
| `permission_error`     | 403       | Insufficient permissions (e.g., public key on a write endpoint, live mode not enabled) |
| `validation_error`     | 422       | Request body failed validation                                                         |
| `not_found`            | 404       | The requested resource does not exist                                                  |
| `invalid_request`      | 400       | Malformed request (e.g., idempotency key too long)                                     |
| `rate_limit_error`     | 429       | Too many requests — see [Rate Limiting](/api-guides/rate-limiting)                     |
| `ip_restricted`        | 403       | Request IP address not in the allowlist                                                |
| `conflict`             | 409       | Resource state conflict                                                                |
| `api_error`            | 500 / 501 | Internal server error or feature not yet available                                     |

## Validation errors

When a request fails validation, the response includes a `422` status and field-level error details:

```json
{
  "error": {
    "type": "validation_error",
    "message": "The request data is invalid.",
    "errors": [
      {
        "field": "customer_id",
        "message": "The customer id field is required."
      },
      {
        "field": "plan_id",
        "message": "The plan id field is required."
      }
    ]
  }
}
```

Each entry in the `errors` array includes the `field` name and a descriptive `message`.

## Handling errors

Best practices for error handling in your integration:

* **Check `error.type`** rather than parsing the message string. Types are stable; messages may change.
* **Retry on `429`** after the duration specified in the `Retry-After` response header.
* **Retry on `500`** with exponential backoff. If errors persist, contact support.
* **Do not retry `401`, `403`, `404`, or `422`** — these indicate issues with your request that require code changes.
* **Log the full error response** for debugging. Include the request method, path, and any request body (redacting sensitive fields).