# Erreurs

> Chaque erreur est un objet Problem Details (RFC 9457) dont seul le code est un contrat machine. Le format, le catalogue complet des codes par statut, et la conduite à tenir pour chacun.

Toute erreur de Noryo Merchant API est un document **Problem Details** (RFC 9457), servi en `application/problem+json`.

```json
{
  "type": "https://developer.noryo.app/errors/idempotency_key_reuse",
  "title": "Idempotency key reused",
  "status": 409,
  "code": "idempotency_key_reuse",
  "detail": "this Idempotency-Key is bound to a different request for the remainder of its TTL",
  "request_id": "req_01a07784-d343-75f8-b0ae-b0629b305cd4"
}
```

## Les champs

| Champ | Contenu | Stable ? |
|---|---|---|
| `type` | L'adresse de la page du code dans le [catalogue des erreurs](https://developer.noryo.app/fr-FR/errors) | Le lien peut changer de domaine ; le code, non |
| `title` | Un titre court, en anglais, pour un humain | Non : peut être reformulé |
| `status` | Le statut HTTP de la réponse, pour tous les codes | |
| `code` | Le code machine, en `snake_case` | **Oui : c'est le contrat** |
| `detail` | Une phrase en anglais, parfois plus précise que le titre | Non : peut être reformulée |
| `request_id` | L'identifiant de la tentative, identique à l'en-tête `Noryo-Request-Id` | |

Une `410` ajoute `enrichment_id`, et une `503 engine_error` aussi : il y désigne la tentative échouée, pas un résultat. Aucun autre membre n'est ajouté.

> **Important** Bâtissez votre logique sur `code`, et sur le statut HTTP. `title` et `detail` sont écrits pour des humains et peuvent être reformulés à tout moment sans changement de version : un client qui les analyse cassera à la première relecture.

Les corps d'erreur ne portent jamais de SQLSTATE, de nom de table, de trace d'appels, de nom d'hôte interne, ni la valeur de votre clé ou de votre `Idempotency-Key`. Un `500` ne porte que `code` et `request_id` comme informations utiles.

## Le catalogue

Chaque code a sa page dans le [catalogue des erreurs](https://developer.noryo.app/fr-FR/errors).

| Statut | Code | Quand | Conduite |
|---|---|---|---|
| 400 | [`invalid_request`](https://developer.noryo.app/fr-FR/errors/invalid_request) | Corps hors schéma, champ inconnu, `external_transaction_id` sur un rafraîchissement, hôte inconnu | Corriger la requête |
| 400 | [`invalid_json`](https://developer.noryo.app/fr-FR/errors/invalid_json) | Corps qui n'est pas du JSON valide | Corriger la requête |
| 400 | [`identifier_required`](https://developer.noryo.app/fr-FR/errors/identifier_required) | Création sans `Idempotency-Key` ni `external_transaction_id` ; rafraîchissement sans `Idempotency-Key` | Ajouter l'identifiant |
| 400 | [`invalid_idempotency_key`](https://developer.noryo.app/fr-FR/errors/invalid_idempotency_key) | En-tête `Idempotency-Key` vide, trop long, répété ou hors ASCII visible | Corriger la clé |
| 400 | [`invalid_input`](https://developer.noryo.app/fr-FR/errors/invalid_input) | Non rendu par les routes actuelles | Aucune |
| 400 | [`refresh_requires_transaction_id`](https://developer.noryo.app/fr-FR/errors/refresh_requires_transaction_id) | Non rendu par les routes actuelles : le rafraîchissement d'un enrichissement sans `external_transaction_id` rend `409 refresh_not_available` | Voir [Rafraîchir](https://developer.noryo.app/fr-FR/merchant/refresh) |
| 400 | [`target_enrichment_required`](https://developer.noryo.app/fr-FR/errors/target_enrichment_required) | Non rendu par les routes actuelles : le chemin nomme toujours la cible | Aucune |
| 400 | [`unsupported_canonicalization`](https://developer.noryo.app/fr-FR/errors/unsupported_canonicalization) | Non rendu par les routes actuelles | Contacter le support avec le `request_id` |
| 401 | [`invalid_api_key`](https://developer.noryo.app/fr-FR/errors/invalid_api_key) | Clé absente, mal formée, inconnue, révoquée ou de mauvais préfixe | Corriger la clé |
| 402 | [`sandbox_quota_exhausted`](https://developer.noryo.app/fr-FR/errors/sandbox_quota_exhausted) | Dotation Sandbox épuisée | Passer en Production |
| 402 | [`no_active_subscription`](https://developer.noryo.app/fr-FR/errors/no_active_subscription) | Aucun abonnement actif ne couvre l'opération | Régulariser le compte |
| 403 | [`insufficient_scope`](https://developer.noryo.app/fr-FR/errors/insufficient_scope) | La clé n'a pas le scope de la route | Utiliser une clé avec le bon scope |
| 403 | [`account_inactive`](https://developer.noryo.app/fr-FR/errors/account_inactive) | Organisation ou workspace inactif | Contacter Noryo |
| 403 | [`production_not_enabled`](https://developer.noryo.app/fr-FR/errors/production_not_enabled) | La clé n'est pas autorisée en Production | Voir [Passage en production](https://developer.noryo.app/fr-FR/merchant/going-live) |
| 404 | [`enrichment_not_found`](https://developer.noryo.app/fr-FR/errors/enrichment_not_found) | `enrichment_id` inconnu, mal formé, d'un autre workspace ou environnement | Vérifier l'identifiant, la clé, l'environnement |
| 404 | [`transaction_not_found`](https://developer.noryo.app/fr-FR/errors/transaction_not_found) | Rafraîchissement d'une transaction sans résultat enregistré | Créer un enrichissement d'abord |
| 409 | [`idempotency_key_reuse`](https://developer.noryo.app/fr-FR/errors/idempotency_key_reuse) | Même `Idempotency-Key`, autre requête, dans les 24 heures | Nouvelle clé pour une nouvelle requête |
| 409 | [`transaction_id_conflict`](https://developer.noryo.app/fr-FR/errors/transaction_id_conflict) | Même `external_transaction_id`, autre entrée économique | Corriger l'entrée ou l'identifiant |
| 409 | [`input_mismatch`](https://developer.noryo.app/fr-FR/errors/input_mismatch) | Rafraîchissement dont l'entrée diffère de celle de la transaction | Renvoyer l'entrée d'origine |
| 409 | [`refresh_not_available`](https://developer.noryo.app/fr-FR/errors/refresh_not_available) | Enrichissement d'origine sans `external_transaction_id` | Relire en `GET`, ou créer avec un identifiant |
| 410 | [`result_content_expired`](https://developer.noryo.app/fr-FR/errors/result_content_expired) | Contenu purgé après 90 jours | Voir [Rétention et 410](https://developer.noryo.app/fr-FR/merchant/retention) |
| 413 | [`request_entity_too_large`](https://developer.noryo.app/fr-FR/errors/request_entity_too_large) | Corps de plus de 16 Kio | Réduire le corps |
| 415 | [`unsupported_media_type`](https://developer.noryo.app/fr-FR/errors/unsupported_media_type) | `Content-Type` autre que `application/json` | Envoyer du JSON |
| 429 | [`rate_limited`](https://developer.noryo.app/fr-FR/errors/rate_limited) | Seau de débit vide | Reprendre après `Retry-After` |
| 500 | [`internal_error`](https://developer.noryo.app/fr-FR/errors/internal_error) | Erreur inattendue | Reprendre avec la même clé ; citer le `request_id` |
| 503 | [`engine_error`](https://developer.noryo.app/fr-FR/errors/engine_error) | Le moteur de résolution n'a pas répondu ; rien n'est facturé ni mémorisé | Reprendre avec la même clé |
| 503 | [`busy`](https://developer.noryo.app/fr-FR/errors/busy) | Contention passagère, ou requête identique en cours | Reprendre après `Retry-After` |
| 503 | [`pricing_not_activated`](https://developer.noryo.app/fr-FR/errors/pricing_not_activated) | Facturation pas encore activée pour l'opération | Reprendre après `Retry-After` |

## Politique de reprise

| Statut | Reprendre ? |
|---|---|
| `429` | Oui, après `Retry-After` |
| `503` | Oui, **avec la même `Idempotency-Key`** : rien n'a été facturé ni mémorisé |
| `500` | Oui, avec la même `Idempotency-Key` |
| `409` | Non : corrigez la charge utile ou la clé |
| Autres `4xx` | Non |

Le détail est dans [Reprises](https://developer.noryo.app/fr-FR/merchant/operations/retries).

## L'identifiant de tentative

**Chaque réponse porte `Noryo-Request-Id`**, et chaque corps d'erreur le répète dans `request_id`. Une tentative a exactement un identifiant : le même dans l'en-tête, dans le corps et dans les journaux de Noryo, y compris sur un `500`. Citez-le au support et nous retrouvons la tentative exacte. Voir [Identifiants de requête](https://developer.noryo.app/fr-FR/merchant/operations/request-ids).

---

Page canonique : https://developer.noryo.app/fr-FR/merchant/error-handling
