## L'envelope

Ogni errore di `/public/v1/*` risponde con lo stesso corpo, qualunque sia il codice HTTP:

```json
{
  "error": "PERMISSION_DENIED",
  "message": "You do not have the required permission for this action",
  "request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "details": {}
}
```

- **`error`** — il codice della tabella sotto; l'unico campo su cui la tua integrazione dovrebbe decidere
  cosa fare. Non cambia mai forma all'interno di `/public/v1` (vedi [Versioning](/it/api/versioning/)).
- **`message`** — testo per umani, in inglese, orientato al debug — non mostrarlo così com'è al tuo utente
  finale né usarlo per decidere la logica di business, la sua formulazione può cambiare senza preavviso.
- **`request_id`** — includilo se scrivi al supporto per un errore specifico; ci aiuta a trovare la
  richiesta esatta nei nostri log.
- **`details`** — contesto aggiuntivo (per es. quali campi hanno fallito una validazione); non è mai la
  parte stabile del contratto, trattalo come informativo.

## Catalogo dei codici

| HTTP | `error` | Quando compare |
| --- | --- | --- |
| 401 | `INVALID_CREDENTIALS` | La chiave non esiste, è stata copiata male o è revocata. |
| 401 | `TOKEN_EXPIRED` | La chiave ha superato la sua data di scadenza. |
| 403 | `PERMISSION_DENIED` | La chiave non ha lo scope esatto richiesto dall'endpoint — vedi [Autenticazione](/it/api/authentication/). |
| 403 | `PLAN_NOT_ELIGIBLE` | Il tenant proprietario della chiave non è su un piano Pro o Enterprise — vedi [Piani e limiti](/it/api/plans-and-limits/). |
| 404 | `NOT_FOUND` | La risorsa non esiste, oppure appartiene a un altro tenant — stessa risposta in entrambi i casi, per non confermare mai l'esistenza di dati altrui. |
| 409 | `WHATSAPP_SESSION_WINDOW_CLOSED` | `POST /conversations/{id}/messages` verso un contatto WhatsApp con la finestra di 24h chiusa — usa `POST /conversations/start` con un template approvato al suo posto. L'invio reale non viene mai tentato. |
| 422 | `VALIDATION_ERROR` | Il corpo o i parametri della richiesta non rispettano lo schema dell'endpoint — controlla `details`. |
| 422 | `IDEMPOTENCY_KEY_REUSE_MISMATCH` | Solo se invii l'header opzionale `Idempotency-Key`: lo stesso valore è già stato usato con un corpo DIVERSO in una richiesta precedente. Genera una chiave nuova per una richiesta realmente diversa. |
| 429 | `RATE_LIMIT_EXCEEDED` | Hai superato la tua quota di richieste — vedi [Piani e limiti](/it/api/plans-and-limits/) per gli header `X-RateLimit-*`. |

Un `422` di validazione di FastAPI (corpo malformato, tipo errato) usa lo stesso envelope, con `details` che
elenca ogni campo che ha fallito.