> ## Documentation Index
> Fetch the complete documentation index at: https://docs.piriod.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error handling

> Status codes and response shapes when something goes wrong.

## Status codes

| Code  | Meaning                                                                               |
| ----- | ------------------------------------------------------------------------------------- |
| `200` | OK. Returned on `GET`, `PATCH`, `PUT` and most action endpoints.                      |
| `201` | Created. Returned on `POST` for new resources.                                        |
| `204` | No Content. Returned on `DELETE`.                                                     |
| `400` | Bad Request. Validation error (see body).                                             |
| `401` | Unauthorized. Missing or invalid `Authorization` header.                              |
| `403` | Forbidden. Authenticated but not allowed (e.g. wrong workspace).                      |
| `404` | Not Found. Either the resource does not exist or it does not belong to the workspace. |
| `405` | Method Not Allowed. The HTTP verb is not supported by the endpoint.                   |
| `500` | Internal Server Error. Open a support ticket if it persists.                          |

## Response shapes

### Generic errors

For `401`, `403`, `404` and most `500` cases:

```json theme={null}
{
  "detail": "Authentication credentials were not provided."
}
```

### Validation errors

For `400`, errors are returned as a field-keyed map. Errors not bound to a
single field are grouped under `non_field_errors`:

```json theme={null}
{
  "name": ["This field is required."],
  "tax_id": ["Invalid format."],
  "non_field_errors": ["x-simple-workspace header is required."]
}
```

## Common pitfalls

* **`x-simple-workspace` missing** → `400` with `non_field_errors: ["x-simple-workspace header is required."]`.
* **Wrong workspace ID** → `403` (the user is not a member of that workspace).
* **Tax-regulated country, missing `tax_id` or `tax_settings`** → `400` with field-specific errors.
* **Trying to delete a customer with active subscriptions** → `400`. Cancel the
  subscriptions first or the customer is archived instead.

## Retries

The API does not currently support an idempotency header. Treat write requests
as non-idempotent and avoid blind retries on `5xx` for endpoints that create
financial records.
