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

# Erreurs

> Codes d'erreur, format de réponse et stratégie de retry

Toutes les erreurs SandPay suivent un format unique et stable. Pas de surprise, pas de format ad hoc selon l'endpoint.

## Format de réponse

```json theme={null}
{
  "error": "invalid_body",
  "message": "amount must be greater than 0",
  "detail": {
    "fieldErrors": {
      "amount": ["Number must be greater than 0"]
    }
  }
}
```

* `error` — code machine, stable, à utiliser dans votre logique (`switch`, `if`).
* `message` — texte humain, en anglais, susceptible d'évoluer.
* `detail` — payload structuré optionnel (erreurs Zod par champ, contexte additionnel).

L'en-tête `X-Request-Id` accompagne chaque réponse (succès comme erreur). Conservez-le si vous ouvrez un ticket support.

## Codes par statut HTTP

| Status | `error`           | Quand                                                                               |
| ------ | ----------------- | ----------------------------------------------------------------------------------- |
| 400    | `invalid_body`    | Le corps JSON ne valide pas le schéma (Zod). `detail` contient les champs en faute. |
| 400    | `invalid_params`  | Paramètres de query invalides (par ex. `limit=999`).                                |
| 401    | `unauthorized`    | En-tête `Authorization` absent.                                                     |
| 401    | `invalid_api_key` | Clé inconnue, révoquée ou mal formée.                                               |
| 402    | `quota_exceeded`  | Quota mensuel atteint sur le plan courant. Mettez à niveau.                         |
| 404    | `not_found`       | Ressource introuvable (transaction, application, client…).                          |
| 404    | `env_not_found`   | Le couple `country`/`operator` n'a pas d'environnement configuré.                   |
| 429    | `rate_limited`    | Trop de requêtes — retry après l'en-tête `Retry-After`.                             |
| 5xx    | `internal`        | Erreur côté SandPay. Tracée dans Sentry, retry recommandé.                          |

## Stratégie de retry

| Status         | Retriable ? | Comment                                                  |
| -------------- | ----------- | -------------------------------------------------------- |
| 4xx (sauf 429) | Non         | Corrigez la requête. Réessayer ne changera rien.         |
| 429            | Oui         | Respectez `Retry-After`, puis backoff exponentiel.       |
| 5xx            | Oui         | Backoff exponentiel : 1s, 2s, 4s, 8s, 16s. Max 5 essais. |

<Tip>
  Le SDK Node lève une `SandPayApiError` qui expose `status`, `code`, `message`, `detail` et `requestId` — utilisez-la pour brancher votre logique de retry.
</Tip>

## Exemple — gérer un quota dépassé

```ts theme={null}
import { SandPay, SandPayApiError } from "@drwintech/sandpay";

const sp = new SandPay({ apiKey: process.env.SANDPAY_API_KEY! });

try {
  await sp.payments.create({ /* ... */ });
} catch (err) {
  if (err instanceof SandPayApiError && err.code === "quota_exceeded") {
    // Notifier l'équipe, déclencher l'upgrade, etc.
    notifyOps("SandPay quota dépassé, requestId=" + err.requestId);
    return;
  }
  throw err;
}
```
