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

# Erreurs

> L'enveloppe d'erreur de l'API Samsa, chaque code d'erreur et comment gérer chacun d'eux.

Chaque erreur que l'API Samsa renvoie — pour n'importe quel endpoint, à n'importe
quel statut — utilise une **enveloppe** JSON cohérente. Analyse le `code` lisible
par machine, pas le `message` humain (les messages peuvent changer ; les codes sont
stables).

## L'enveloppe d'erreur

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The provided API key is invalid, expired, or revoked.",
    "request_id": "req_8f14e45fceea167a"
  }
}
```

| Champ              | Description                                                                                                                              |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `error.type`       | Catégorie large, par ex. `authentication_error`, `credit_error`, `rate_limit_error`.                                                     |
| `error.code`       | Code stable et spécifique sur lequel tu branches (le tableau ci-dessous).                                                                |
| `error.message`    | Explication lisible par un humain. Pour l'affichage et les logs — ne l'analyse pas.                                                      |
| `error.request_id` | Id de corrélation pour cette requête, aussi renvoyé dans le header de réponse `X-Request-ID`. **Cite-le quand tu contactes le support.** |
| `error.param`      | Présent sur les erreurs de validation et de scope — nomme le champ fautif ou `"scope"`.                                                  |

<Note>
  Les réponses réussies ne contiennent jamais d'objet `error`. Branche d'abord sur
  le statut HTTP, puis sur `error.code`.
</Note>

## Codes d'erreur

| HTTP | `code`                             | `type`                  | Signification                                                                                                                           |
| ---- | ---------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 401  | `invalid_api_key`                  | `authentication_error`  | Clé manquante, malformée, inconnue, expirée ou révoquée.                                                                                |
| 403  | `missing_scope`                    | `permission_error`      | Clé valide sans le scope du endpoint.                                                                                                   |
| 402  | `insufficient_credits`             | `credit_error`          | Le pool de credits de l'organisation est en dessous du coût de l'action.                                                                |
| 402  | `subscription_inactive`            | `credit_error`          | Aucun abonnement d'organisation utilisable.                                                                                             |
| 402  | `insufficient_team_credits`        | `credit_error`          | Le budget mensuel restant de l'équipe de la clé API (plus les top-ups) est en dessous du coût de l'action.                              |
| 402  | `insufficient_unallocated_credits` | `credit_error`          | Le pool non alloué de l'organisation (plus les top-ups) est en dessous du coût de l'action — clé non assignée à une équipe avec budget. |
| 404  | `not_found`                        | `invalid_request_error` | Id inconnu, ou ressource appartenant à une autre organisation.                                                                          |
| 422  | `validation_error`                 | `invalid_request_error` | Le corps de la requête ou les paramètres ont échoué à la validation.                                                                    |
| 429  | `rate_limited`                     | `rate_limit_error`      | Fenêtre de rate de requêtes par clé dépassée.                                                                                           |
| 429  | `too_many_active_jobs`             | `rate_limit_error`      | Plafond de jobs concurrents de l'organisation atteint.                                                                                  |
| 500  | `internal_error`                   | `api_error`             | Erreur serveur inattendue.                                                                                                              |

***

### `invalid_api_key`

**HTTP 401.** Le header `Authorization` est manquant ou malformé, ou la clé est
inconnue, expirée ou révoquée — ou le créateur de la clé n'est plus membre de
l'organisation. Les clés expirées et inconnues sont intentionnellement
indistinguables.

```json theme={null}
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "The provided API key is invalid, expired, or revoked.",
    "request_id": "req_8f14e45fceea167a"
  }
}
```

**Comment gérer.** Vérifie le header `Authorization: Bearer samsa_sk_…`. Si la clé
a été révoquée ou a expiré, [crées-en une nouvelle](/fr/guides/authentication#faire-tourner-une-clé).
Ne réessaie pas — le résultat ne changera pas.

### `missing_scope`

**HTTP 403.** La clé est valide mais n'a pas le [scope](/fr/guides/authentication#scopes)
que le endpoint requiert. `param` vaut `"scope"` et le message nomme le scope
manquant.

```json theme={null}
{
  "error": {
    "type": "permission_error",
    "code": "missing_scope",
    "message": "The API key is missing the required scope: images.generate.",
    "request_id": "req_1c9a3b7d2e5f4a80",
    "param": "scope"
  }
}
```

**Comment gérer.** Un admin modifie les scopes de la clé (ou émet une nouvelle clé)
pour accorder le scope nommé. Ne réessaie pas sans changer la clé.

### `insufficient_credits`

**HTTP 402.** Le pool de credits dépensable de l'organisation (abonnement plus
top-ups valides) est en dessous du coût de l'action. Voir [Tarification](/fr/guides/pricing).
Si l'organisation a au moins une équipe active, l'API renvoie à la place les codes
liés aux équipes [`insufficient_team_credits`](#insufficient_team_credits) ou
[`insufficient_unallocated_credits`](#insufficient_unallocated_credits).

```json theme={null}
{
  "error": {
    "type": "credit_error",
    "code": "insufficient_credits",
    "message": "Insufficient credits available.",
    "request_id": "req_2d5f4a801c9a3b7d"
  }
}
```

**Comment gérer.** Recharge ou fais évoluer le plan de l'organisation dans l'app,
puis réessaie. Rien n'a été facturé et aucun job n'a été créé.

### `subscription_inactive`

**HTTP 402.** L'organisation n'a aucun abonnement utilisable (aucun actif, en
période de grâce, ou détenant des top-ups dépensables). Distinct de
`insufficient_credits`, où un abonnement existe mais le pool est trop bas.

```json theme={null}
{
  "error": {
    "type": "credit_error",
    "code": "subscription_inactive",
    "message": "No active subscription for this organization.",
    "request_id": "req_4a801c9a3b7d2d5f"
  }
}
```

**Comment gérer.** Réactive la facturation de l'organisation dans l'app, puis
réessaie.

### `insufficient_team_credits`

**HTTP 402.** Les organisations peuvent répartir leurs credits d'abonnement mensuels
en **budgets** par équipe, et chaque clé API peut être assignée à une équipe. Une clé
assignée à une équipe avec budget dépense depuis le bucket mensuel de cette équipe ;
tout ce qui n'est alloué à aucun budget d'équipe forme le **pool non alloué** de
l'organisation. Les top-ups achetés sont exemptés des budgets et restent
disponibles pour couvrir le reste. Ce code survient quand le budget restant de l'équipe pour la
période de facturation en cours, plus les top-ups, est en dessous du coût de
l'action.

```json theme={null}
{
  "error": {
    "type": "credit_error",
    "code": "insufficient_team_credits",
    "message": "Insufficient team credits for team Marketing",
    "request_id": "req_6b7d2d5f4a801c9a"
  }
}
```

**Comment gérer.** Un admin de l'organisation peut augmenter le budget mensuel de
l'équipe, assigner la clé à une autre équipe, ou acheter des top-ups (les top-ups ne
sont pas limités par les budgets d'équipe). L'utilisation du budget se réinitialise
aussi à la prochaine période de facturation. Rien n'a été facturé et aucun job n'a été créé.

### `insufficient_unallocated_credits`

**HTTP 402.** La clé n'est pas assignée à une équipe avec budget (non assignée, ou
son équipe n'a pas de budget), elle dépense donc depuis le pool non alloué de
l'organisation — les credits d'abonnement mensuels restants après soustraction des
budgets de toutes les équipes actives. Ce code survient quand ce pool, plus les top-ups exemptés
des budgets, est en dessous du coût de l'action. Les organisations sans équipe
active ne voient jamais les deux codes liés aux équipes — elles reçoivent le simple
[`insufficient_credits`](#insufficient_credits) à la place.

```json theme={null}
{
  "error": {
    "type": "credit_error",
    "code": "insufficient_unallocated_credits",
    "message": "Insufficient unallocated organization credits",
    "request_id": "req_0a3b7d2d5f4a801c"
  }
}
```

**Comment gérer.** Un admin de l'organisation peut libérer des credits non alloués
en baissant les budgets d'équipe, assigner la clé à une équipe avec du budget
disponible, faire évoluer le plan, ou acheter des top-ups. Rien n'a été facturé et
aucun job n'a été créé.

### `not_found`

**HTTP 404.** L'id est inconnu, ou il appartient à une autre organisation. Les deux
cas sont indistinguables par conception, donc l'existence n'est jamais divulguée
entre organisations.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "not_found",
    "message": "The requested resource was not found.",
    "request_id": "req_7d2d5f4a801c9a3b"
  }
}
```

**Comment gérer.** Vérifie l'id, et que l'organisation de la clé possède bien la
ressource. Ne réessaie pas.

### `validation_error`

**HTTP 422.** Le corps de la requête ou un paramètre a échoué à la validation.
`param` nomme le champ fautif ; `message` explique la contrainte.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "message": "aspect_ratio must be one of: 1:1, 1:4, 1:8, 16:9, 2:3, 21:9, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 9:16.",
    "request_id": "req_3b7d2d5f4a801c9a",
    "param": "aspect_ratio"
  }
}
```

**Comment gérer.** Corrige la requête selon `message` et `param`, puis renvoie-la.
C'est une erreur client — réessayer la même requête échouera de façon identique.

### `rate_limited`

**HTTP 429.** La clé a dépassé sa fenêtre de rate de requêtes par clé. La réponse
porte les headers `Retry-After` et `X-RateLimit-*`. Voir [Rate limits](/fr/guides/rate-limits).

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "API rate limit exceeded. Slow down and retry after the rate-limit window resets.",
    "request_id": "req_5f4a801c9a3b7d2d"
  }
}
```

**Comment gérer.** Ralentis et réessaie après l'intervalle `Retry-After`. Utilise un
backoff exponentiel pour des 429 répétés.

### `too_many_active_jobs`

**HTTP 429.** L'organisation a atteint son plafond de jobs concurrents en cours. Le
message inclut le compte actuel et la limite, et un header `Retry-After` est défini.

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "too_many_active_jobs",
    "message": "Too many active jobs for this organization (5/5). Wait for in-flight jobs to finish before submitting more.",
    "request_id": "req_801c9a3b7d2d5f4a"
  }
}
```

**Comment gérer.** Attends que les jobs en cours atteignent un statut terminal
(interroge leur endpoint `GET` ou utilise un [webhook](/fr/guides/webhooks)) avant
d'en soumettre d'autres, puis réessaie après `Retry-After`.

### `internal_error`

**HTTP 500.** Une erreur inattendue du côté de Samsa. La réponse ne divulgue jamais
de détails internes — le `request_id` est ton point d'entrée pour le support.

```json theme={null}
{
  "error": {
    "type": "api_error",
    "code": "internal_error",
    "message": "An internal error occurred. Contact support with the request_id.",
    "request_id": "req_9a3b7d2d5f4a801c"
  }
}
```

**Comment gérer.** Réessaie avec un backoff — les 500 sont souvent transitoires. Si
cela persiste, contacte [support@samsa.ai](mailto:support@samsa.ai) avec le
`request_id`.

## Utiliser `request_id` pour le support

Chaque erreur (et chaque succès) porte un `request_id`, aussi renvoyé dans le
header de réponse `X-Request-ID`. Il relie ton erreur côté client, le header de
réponse et les logs serveur de Samsa à une même requête. Log-le, et cite-le quand
tu contactes [support@samsa.ai](mailto:support@samsa.ai) — c'est le moyen le plus
rapide pour nous de retrouver exactement ce qui s'est passé.

<Tip>
  De nouveaux codes d'erreur peuvent être ajoutés au fil du temps (par exemple des
  codes additifs par endpoint). Traite un `code` non reconnu comme sa classe de
  statut HTTP, et branche toujours sur `code` plutôt que sur une correspondance de
  texte de `message`.
</Tip>
