# Gestion des erreurs
Source: https://docs.lomi.africa/api/errors

Comprendre et traiter les erreurs renvoyées par l’API.

***

title: 'Gestion des erreurs'
description: 'Comprendre et traiter les erreurs renvoyées par l’API.'
---------------------------------------------------------------------

Nous utilisons les codes HTTP usuels pour signaler le succès ou l’échec d’une requête :

* Plage `2xx` : succès.
* Plage `4xx` : erreur côté client (paramètre manquant, données invalides, etc.).
* Plage `5xx` : erreur côté nos serveurs (rare). En cas de doute, voir notre [page de statut](https://status.lomi.africa).

En cas d’échec (`4xx` ou `5xx`), le corps de la réponse contient un objet JSON décrivant l’erreur.

Pour parser ces erreurs dans votre application avec le SDK TypeScript, voir [Gestion des erreurs](/build/reliability/error-handling).

## Structure de la réponse d’erreur

Format JSON cohérent :

```json filename="Exemple de réponse d’erreur"
{
  "error": {
    "code": "unauthorized",
    "message": "Description lisible de l'erreur.",
    "details": "Optionnel : détails ou informations structurées sur l'erreur."
  },
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

| Champ           | Type                 | Description                                                                                           |
| --------------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
| `error`         | `object`             | Conteneur d’informations d’erreur.                                                                    |
| `error.code`    | `string`             | Code machine (voir le tableau des codes stables ci-dessous).                                          |
| `error.message` | `string`             | Résumé bref lisible par un humain.                                                                    |
| `error.details` | `string` ou `object` | Optionnel. Contexte plus précis (échecs de validation, `retry_after_seconds`, ressources en conflit). |
| `request_id`    | `string` (UUID)      | Corrélation avec les journaux serveur. Aussi renvoyé dans l’en-tête `X-Request-Id`.                   |

## Codes HTTP courants

| Code  | Statut                | Signification                                                                                                                            |
| ----- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `200` | OK                    | Requête réussie.                                                                                                                         |
| `201` | Created               | Ressource créée (par exemple un webhook).                                                                                                |
| `204` | No Content            | Succès sans corps utile (par exemple une suppression).                                                                                   |
| `400` | Bad Request           | Requête incorrecte ou paramètres invalides / manquants.                                                                                  |
| `401` | Unauthorized          | Pas de clé API valide.                                                                                                                   |
| `403` | Forbidden             | La clé n’a pas les droits pour cette opération.                                                                                          |
| `404` | Not Found             | La ressource demandée est introuvable.                                                                                                   |
| `409` | Conflict              | Conflit avec l’état actuel (par exemple une clé d’idempotence réutilisée avec un autre corps).                                           |
| `429` | Too Many Requests     | Plafonds de débit dépassés.                                                                                                              |
| `500` | Internal Server Error | Erreur côté lomi. (exceptionnelle).                                                                                                      |
| `503` | Service Unavailable   | Indisponibilité temporaire, y compris les rails mutés comme `POST /charge/switch`. Réessayez plus tard, ou utilisez le checkout hébergé. |

## Codes d’erreur stables

| Code                       | Statut HTTP typique |
| -------------------------- | ------------------- |
| `bad_request`              | 400                 |
| `validation_failed`        | 400                 |
| `amount_invalid`           | 400                 |
| `invalid_cursor`           | 400                 |
| `unauthorized`             | 401                 |
| `forbidden`                | 403                 |
| `not_found`                | 404                 |
| `conflict`                 | 409                 |
| `idempotency_key_required` | 400                 |
| `idempotency_key_reused`   | 409                 |
| `idempotency_in_progress`  | 409                 |
| `rate_limit_exceeded`      | 429                 |
| `api_access_suspended`     | 403                 |
| `service_unavailable`      | 503                 |
| `internal_error`           | 500                 |

## Limites de débit

La même politique s’applique à la sandbox et au live. Voir [Authentification](/api/authentication#rate-limits).

| Périmètre                                                                                                           | Limite                       |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| Défaut                                                                                                              | 5000 requêtes par 15 minutes |
| Écritures (`POST /checkout-sessions`, `POST /payment-requests`, `POST /refunds`, `POST /payouts`, `POST /charge/*`) | 120 requêtes par minute      |

Un `429` inclut :

* `Retry-After` (secondes)
* `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Window-Seconds`
* IETF `RateLimit` / `RateLimit-Policy`
* `error.details.retry_after_seconds` et `error.details.limit`

## Requête

### Paramètres d’URL

*Pas d’autre paramètre dans l’URL.*

### Paramètres de requête

*Aucun paramètre de requête.*

### En-têtes

| Nom            | Emplacement | Obligatoire | Schéma | Description                                                                                          |
| -------------- | ----------- | ----------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `Lomi-Version` | header      | Non         | -      | Optional schema version pin. Echoes OpenAPI info.version (currently 1.2.0). Routes stay unversioned. |

## Réponses

| Statut | Description |
| ------ | ----------- |
| `200`  | -           |

## Erreurs

Les erreurs suivent un format JSON standard. **401** : clé manquante ou invalide. **404** : ressource introuvable. **429** : trop de requêtes. Pour les créations, envoyez une clé d’idempotence si votre flux le permet.

## Exemples de messages courants

Les champs `message` et `details` varient. Motifs typiques :

**`400` Bad Request :**

* `"code": "validation_failed"` avec `details` par champ
* `"code": "amount_invalid"`
* `"code": "idempotency_key_required"`
* `"code": "invalid_cursor"`

**`401` Unauthorized :**

* `"code": "unauthorized"`, `"message": "Invalid API key"`
* `"code": "unauthorized"`, `"message": "Missing API key"`

**`404` Not Found :**

* `"code": "not_found"`

**`409` Conflict :**

* `"code": "idempotency_key_reused"`
* `"code": "idempotency_in_progress"`

**`429` Too Many Requests :**

* `"code": "rate_limit_exceeded"`, `"message": "Too many requests"`

**`500` Internal Server Error :**

* `"code": "internal_error"`, `"message": "Internal server error"`

**`503` Service Unavailable :**

* `"code": "service_unavailable"` (maintenance, ou un rail d’encaissement direct muté)

## Traiter les erreurs

1. Lire le code HTTP.
2. Analyser le corps JSON pour les erreurs `4xx` ou `5xx`.
3. Utiliser `error.code`, `error.message` et `error.details`.
4. Réessayer `429` et `5xx` avec un backoff. Ne pas réessayer les autres `4xx` tant que la requête n’est pas corrigée.
5. Journaliser `request_id` (corps et en-tête `X-Request-Id`) pour le support.
