Les erreurs avec problem+json Le code de statut dit qu'il y a une erreur. Le body doit dire laquelle , et comment la corriger. Plutôt que d'inventer un format par API, il existe un standard : application/problem+json . Le format HTTP/1.1 409 Conflict Content-Type: application/problem+json { "type": "https://api-ritif.example/problems/order-not-cancellable", "title": "La commande ne peut plus être annulée", "status": 409, "detail": "La commande 42 est en préparation. Le shaker tourne déjà.", "instance": "/v1/orders/42" } Champ Rôle type Une URI qui identifie le type d'erreur. Idéalement, une page de documentation qui l'explique. Par défaut : about:blank . title Un résumé court, le même pour toutes les erreurs de ce type. status Le code de statut HTTP, répété pour faciliter la lecture. detail L'explication propre à cette occurrence, lisible par un humain. instance Une URI qui identifie cette occurrence précise (la ressource concernée, ou un identifiant de log). Tous les champs sont facultatifs, mais type , title et status sont un minimum raisonnable. Les extensions On peut ajouter ses propres champs. Le cas le plus courant : les erreurs de validation, avec la liste des champs en faute. HTTP/1.1 422 Unprocessable Content Content-Type: application/problem+json { "type": "https://api-ritif.example/problems/validation-error", "title": "Données invalides", "status": 422, "detail": "La requête contient 2 erreurs.", "errors": [ {"field": "rating", "message": "doit être compris entre 1 et 5"}, {"field": "comment", "message": "ne doit pas dépasser 500 caractères"} ] } Le client peut afficher chaque message sous le bon champ du formulaire, sans parser une phrase. Les bonnes pratiques Le même format pour toutes les erreurs de l'API, y compris les 404 et les 500 . Un detail qui dit quoi corriger : « la note doit être comprise entre 1 et 5 », pas « erreur de validation ». Jamais d'informations internes dans une erreur. Ceci n'est pas un message d'erreur, c'est une fuite d'informations : {"error": "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'prix' in /var/www/api/models/Cocktail.php line 42"} Un attaquant y apprend votre base de données, votre langage, votre arborescence et le nom de vos colonnes. Loggez le détail côté serveur, renvoyez un message neutre au client.