# Erreurs de l'API

Une erreur a toujours la même forme. Le statut HTTP dit la catégorie, `name` dit le cas précis, et `message` dit quoi corriger, en français.

```json
{
  "statusCode": 422,
  "name": "validation_error",
  "message": "template.variables : valeur manquante pour prenom"
}
```

Dans `message`, le nom du champ vient en premier, suivi de `:` quand l’erreur vient d’un champ. Une erreur de corps ne signale que la première faute trouvée.

## Codes

| Statut | `name`                  | Cause                                                                                                                                                                                                                                                        | Que faire                                                                                                                                      |
| ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| 401    | `missing_api_key`       | L’en-tête `Authorization` manque, ou ne commence pas par `Bearer `.                                                                                                                                                                                          | Ajoute `Authorization: Bearer am_…`.                                                                                                           |
| 401    | `restricted_api_key`    | La clé est « envoi seulement » et la route n’est ni un envoi ni la lecture de ses propres e-mails (`GET /emails/:id`).                                                                                                                                       | Utilise une clé à accès complet pour cette route, créée dans **Clés d’API**.                                                                   |
| 403    | `invalid_api_key`       | La clé est inconnue ou a été révoquée.                                                                                                                                                                                                                       | Vérifie la clé. Si elle a été révoquée, crée-en une dans **Clés d’API**. Ne réessaie pas tel quel.                                             |
| 403    | `account_suspended`     | Les envois de ton espace sont suspendus. Rien n’est parti.                                                                                                                                                                                                   | Ne réessaie pas. Écris à <support@hgdc.ch> pour rétablir les envois. Les campagnes et les workflows en cours attendent.                        |
| 403    | `sending_paused`        | Les envois sont en pause après trop de messages non remis ou signalés. Rien n’est parti.                                                                                                                                                                     | Ne réessaie pas. HGDC te contacte pour vérifier ta liste, puis reprend les envois. Voir [Limites](/docs/reference/limites/#pause-automatique). |
| 403    | `account_under_review`  | Ton espace attend sa validation par HGDC : il ne peut écrire qu’à ses propres membres pour l’instant. Rien n’est parti.                                                                                                                                      | Attends l’e-mail de validation, en général dans la journée. Voir [Limites](/docs/reference/limites/#avant-tes-premiers-envois).                |
| 404    | `not_found`             | L’élément n’existe pas dans ton espace, ou le chemin est mal formé.                                                                                                                                                                                          | Vérifie l’identifiant.                                                                                                                         |
| 422    | `validation_error`      | Le corps est invalide : champ manquant, trop long, mauvais type, champ non pris en charge (`attachments`, `scheduled_at`, `react`, `topic_id`), domaine d’expédition non vérifié, variable de modèle sans valeur, modèle sans contenu, campagne déjà partie. | Corrige la requête. La rejouer à l’identique donne la même erreur.                                                                             |
| 413    | `payload_too_large`     | Le corps dépasse le plafond : 2,5 Mo pour un e-mail ou une autre route, 10 Mo pour `POST /emails/batch`. Un formulaire, lui, s’arrête à 64 Ko.                                                                                                               | Allège le contenu (images hébergées plutôt qu’intégrées) ou découpe le lot.                                                                    |
| 429    | `rate_limit_exceeded`   | Trop de requêtes en peu de temps : plus de 600 requêtes par minute, ou écritures trop rapprochées.                                                                                                                                                           | Attends quelques secondes, puis réessaie.                                                                                                      |
| 429    | `daily_quota_exceeded`  | La limite de destinataires du jour de ton espace est atteinte.                                                                                                                                                                                               | Ne réessaie pas avant le lendemain. Besoin de plus ? Demande une hausse dans **Réglages**.                                                     |
| 500    | `internal_server_error` | Erreur de notre côté. Le message dit « Erreur interne, réessaie. ».                                                                                                                                                                                          | Réessaie avec la même `Idempotency-Key`.                                                                                                       |

Un `422` peut aussi venir d’une règle métier, comme `Cette adresse n'a pas l'air valide.` ou `Liste introuvable : …`. Le texte de `message` dit alors quelle donnée changer.

## Réessayer sans doublon

Un nouvel essai ne crée pas de doublon quand la requête a une `Idempotency-Key`, ou quand l’action est sans effet de bord.

| Requête                                     | Réessayer ?                                  | Comment                                                                                       |
| ------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `POST /emails`, `POST /emails/batch`        | Oui, sur `429 rate_limit_exceeded` et `500`. | Garde la même `Idempotency-Key`. Sans clé, un nouvel appel peut envoyer deux fois.            |
| `POST /contacts`, `PATCH /contacts/…`       | Oui.                                         | Sans risque : une même adresse est mise à jour, jamais dupliquée.                             |
| `GET`, `DELETE`                             | Oui.                                         | Sans effet de bord répété.                                                                    |
| `POST /lists`, `POST /broadcasts`           | Non, à l’aveugle.                            | Un second appel crée un second objet. Vérifie d’abord avec `GET /lists` ou `GET /broadcasts`. |
| `POST /broadcasts/:id/send`                 | Non, à l’aveugle.                            | Une campagne déjà partie répond `422`, mais vérifie d’abord avec `GET /broadcasts/:id`.       |
| Toute requête en `401`, `403`, `404`, `422` | Non.                                         | La requête ne changera pas.                                                                   |
| `429 daily_quota_exceeded`                  | Non avant le lendemain.                      | Le quota ne se libère pas en quelques secondes.                                               |

Pour un lot, la clé se décline par position : `<clé>:0`, `<clé>:1`, etc. Si le lot s’arrête à mi-chemin, relance-le avec la même clé : les e-mails déjà créés renvoient leur `id`, et seuls les autres partent.

## Délai entre deux essais

En cas de `429 rate_limit_exceeded`, attends quelques secondes avant de réessayer. Le [SDK TypeScript](/docs/reference/sdk/) attend 0,5 s, puis 1 s, et respecte l’en-tête `Retry-After` quand la réponse le contient.

Une erreur réseau, sans réponse du tout, se réessaie comme un `500`, avec la même clé. Le SDK fait ces réessais seul, sur `429`, `500` et erreur réseau.

## Si ça ne marche pas

- **Tu reçois `401 missing_api_key` alors que la clé est définie** : ta variable d’environnement n’arrive pas à ton processus, ou l’en-tête ne commence pas par `Bearer `(un espace est obligatoire).
- **Tu reçois `403 invalid_api_key` après une mise en production** : la clé de test ou une clé révoquée est encore dans la configuration. Remplace-la par une clé active.
