# Error handling

Understand HTTP status codes and error responses from the FiscalRail API.

FiscalRail uses standard HTTP response codes. `2xx` responses indicate success, `4xx` responses indicate a problem with the request or account, and `5xx` responses indicate an error on our side.

A `5xx` response does not necessarily mean that the operation had no effect. Record the response's `Request-Id` header before retrying or contacting support so we can trace the request.

## Error responses

API errors are returned as JSON under a top-level `error` property:

```json
{
  "error": {
    "code": "invalid_request",
    "message": "limit must be between 1 and 100"
  }
}
```

Every error includes a stable machine-readable `code` and a human-readable `message`. Validation errors may also include a `details` array identifying individual fields and violations. Integrations should branch on the HTTP status and `code`, not the text of `message`.

Validation details use dotted field paths where necessary:

```json
{
  "error": {
    "code": "invalid_customer",
    "message": "The customer is invalid",
    "details": [
      {
        "code": "required_value",
        "field": "tax_id.country",
        "message": "can't be blank",
        "metadata": {}
      }
    ]
  }
}
```

## Common errors

| HTTP status | Code | Meaning |
| --- | --- | --- |
| `400` | `invalid_request` | The request could not be parsed or contains an invalid parameter. |
| `401` | `authentication_required` | The API key is missing, malformed or unknown. |
| `402` | `balance_exhausted` | The live account does not have enough balance for a billable operation. |
| `404` | `resource_not_found` | The resource does not exist or belongs to another account. |
| `409` | `idempotency_key_in_use` | Another request is currently using the same idempotency key. |
| `409` | `idempotency_key_mismatch` | The idempotency key was reused for another operation or different parameters. |

## Resource and operation errors

These codes apply only when the corresponding resource or operation is involved:

| HTTP status | Code | Meaning |
| --- | --- | --- |
| `404` | `customer_not_found` | The customer supplied when issuing an invoice does not exist in the account. |
| `409` | `pdf_render_in_progress` | Another request is already rendering the invoice PDF. Retry after a short delay. |
| `422` | `invalid_customer` | Customer data is invalid, or the requested customer operation is not allowed. Check `details`. |
| `422` | `invalid_invoice` | Invoice data is invalid. Check `details`. |
| `422` | `account_not_configured` | The account is missing configuration required by the operation. |
| `503` | `pdf_rendering_unavailable` | PDF rendering is temporarily unavailable. Retry later. |

## Safe retries

Retry transient `5xx` responses with exponential backoff and jitter. Do not retry `4xx` responses without changing the request or account state.

For operations that support idempotency, reuse the same `Idempotency-Key` when retrying an inconclusive request. See [Idempotency](/en/docs/api/idempotency).
