Guide complet des codes de statut HTTP : 1xx, 2xx, 3xx, 4xx, 5xx. Tableaux détaillés, exemples pratiques et bonnes pratiques pour vos APIs REST.
Qu'est-ce qu'un code de statut HTTP ?
Un code de statut HTTP est un nombre à trois chiffres renvoyé par un serveur web en réponse à une requête HTTP. Défini dans la RFC 7231 (et ses successeurs de la famille RFC 9110), ce code indique au client si sa requête a été traitée avec succès, si une redirection est nécessaire, ou si une erreur s'est produite.
Chaque réponse HTTP est composée d'une ligne de statut, d'en-têtes (headers) et d'un corps optionnel. La ligne de statut suit toujours ce format :
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 42
{"id": 1, "name": "Article créé avec succès"}
Comment lire un code HTTP
Le premier chiffre définit la catégorie de réponse. Les deux suivants précisent le cas particulier. Il existe cinq familles :
| Famille | Plage | Signification | Exemple clé |
|---|---|---|---|
| 1xx | 100 – 199 | Informationnel — requête reçue, traitement en cours | 100 Continue |
| 2xx | 200 – 299 | Succès — requête reçue, comprise et traitée | 200 OK, 201 Created |
| 3xx | 300 – 399 | Redirection — action supplémentaire nécessaire | 301 Moved Permanently |
| 4xx | 400 – 499 | Erreur client — requête mal formée ou non autorisée | 404 Not Found, 401 Unauthorized |
| 5xx | 500 – 599 | Erreur serveur — le serveur n'a pas pu traiter la requête | 500 Internal Server Error |
Codes 1xx — Informationnel
Les codes 1xx sont des réponses provisoires. Elles indiquent que le serveur a bien reçu la requête et que le traitement se poursuit. Le client doit attendre la réponse définitive. Ces codes sont rarement visibles en production mais jouent un rôle crucial dans certains protocoles.
| Code | Nom | Description | Utilisation pratique |
|---|---|---|---|
| 100 | Continue | Le serveur a reçu les en-têtes de la requête et le client peut envoyer le corps. | Upload de gros fichiers — vérifie les droits avant d'envoyer le contenu. |
| 101 | Switching Protocols | Le serveur accepte de changer de protocole (ex : HTTP → WebSocket). | Établissement d'une connexion WebSocket ou HTTP/2. |
| 102 | Processing | Le serveur traite une requête longue (WebDAV). Évite le timeout client. | Opérations WebDAV volumineuses, imports massifs de données. |
| 103 | Early Hints | Envoie des en-têtes Link au client avant la réponse finale pour précharger des ressources. |
Optimisation performance — précharge CSS/JS avant que la page soit générée. |
Link: rel=preload pendant que le serveur génère encore la réponse principale, réduisant le temps de chargement perçu.
Codes 2xx — Succès
Les codes 2xx confirment que la requête a été traitée avec succès. C'est la famille la plus fréquemment rencontrée lors du bon fonctionnement d'une application. Choisir le bon code 2xx dans vos APIs REST est un signal fort de qualité pour les consommateurs.
| Code | Nom | Description | Cas d'usage |
|---|---|---|---|
| 200 | OK | Requête réussie. Le corps contient la ressource demandée. | GET, PUT, PATCH réussis avec corps de réponse. |
| 201 | Created | Ressource créée avec succès. Le header Location pointe vers la nouvelle ressource. |
POST créant une ressource (utilisateur, commande, article). |
| 202 | Accepted | Requête acceptée mais traitement différé (asynchrone). | Tâches en arrière-plan : envoi d'e-mail, génération de rapport PDF. |
| 203 | Non-Authoritative Information | Les données proviennent d'une source tierce ou d'un proxy (pas du serveur d'origine). | Proxy ou cache ayant modifié la réponse originale. |
| 204 | No Content | Requête réussie mais aucun corps dans la réponse. | DELETE ou PUT sans retour de données, sauvegarde automatique. |
| 205 | Reset Content | Le client doit réinitialiser la vue (formulaire, éditeur). | Soumission de formulaire — vider les champs après envoi. |
| 206 | Partial Content | Réponse partielle à une requête avec header Range. |
Téléchargements reprennables, streaming vidéo/audio. |
| 207 | Multi-Status (WebDAV) | La réponse contient plusieurs codes de statut (XML). | Opérations WebDAV sur plusieurs ressources simultanément. |
| 208 | Already Reported (WebDAV) | Les membres d'un DAV binding ont déjà été listés dans une réponse précédente. | Évite les boucles dans les collections WebDAV. |
| 226 | IM Used | Le serveur a appliqué une instance-manipulation (delta encoding) à la ressource. | HTTP Delta encoding — transferts optimisés de ressources modifiées. |
Exemples de réponses pour les codes 2xx les plus courants
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"data": [
{ "id": 1, "title": "Guide HTTP", "status": "published" },
{ "id": 2, "title": "REST API", "status": "draft" }
],
"total": 2
}
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: /api/articles/42
{
"id": 42,
"title": "Nouveau article",
"createdAt": "2026-05-13T10:00:00Z"
}
HTTP/1.1 204 No Content
Location pointant vers l'URL de la nouvelle ressource. Cela respecte les conventions REST et facilite la navigation client.
Codes 3xx — Redirections
Les codes 3xx indiquent que la ressource demandée a été déplacée ou nécessite une action supplémentaire. Le client doit généralement effectuer une nouvelle requête vers l'URL indiquée dans le header Location. Ces codes ont un impact direct sur le référencement naturel (SEO).
| Code | Nom | Description | Impact SEO |
|---|---|---|---|
| 300 | Multiple Choices | Plusieurs représentations disponibles pour la ressource (langues, formats). | Neutre — rarement utilisé en pratique. |
| 301 | Moved Permanently | La ressource a été déplacée définitivement vers la nouvelle URL (Location). |
Transfert du PageRank vers la nouvelle URL. Idéal pour les migrations. |
| 302 | Found | Redirection temporaire. La ressource revient normalement à cette URL. | Ne transfère pas le PageRank. Utiliser avec précaution en SEO. |
| 303 | See Other | La réponse se trouve ailleurs. Toujours suivi d'un GET vers le Location. |
Pattern PRG (Post-Redirect-Get) — évite les doubles soumissions de formulaire. |
| 304 | Not Modified | La ressource n'a pas changé depuis le dernier accès (cache valide). | Optimise la performance — le navigateur utilise sa version en cache. |
| 307 | Temporary Redirect | Redirection temporaire qui préserve la méthode HTTP (POST reste POST). | Ne transfère pas le PageRank. Méthode HTTP conservée. |
| 308 | Permanent Redirect | Redirection permanente qui préserve la méthode HTTP (POST reste POST). | Transfère le PageRank. Méthode HTTP conservée. Moderne alternative au 301. |
Différence entre 301 et 308, entre 302 et 307
La distinction essentielle est la préservation de la méthode HTTP :
- 301 et 302 : un POST peut être transformé en GET par le navigateur lors de la redirection (comportement historique des navigateurs).
- 307 et 308 : la méthode HTTP est strictement conservée. Un POST reste un POST après redirection.
Le code 304 — Gestion du cache HTTP
GET /api/articles HTTP/1.1
If-None-Match: "abc123etag"
If-Modified-Since: Wed, 01 Jan 2026 00:00:00 GMT
HTTP/1.1 304 Not Modified
ETag: "abc123etag"
Cache-Control: max-age=3600
Codes 4xx — Erreurs client
Les codes 4xx indiquent une erreur du côté client. La requête est mal formée, non autorisée, ou pointe vers une ressource inexistante. C'est la famille la plus riche et la plus importante à maîtriser pour concevoir des APIs claires et informatives.
| Code | Nom | Description | Cas d'usage |
|---|---|---|---|
| 400 | Bad Request | La requête est syntaxiquement incorrecte ou contient des paramètres invalides. | JSON malformé, paramètres manquants, types invalides. |
| 401 | Unauthorized | Authentification requise. Le client n'est pas identifié. | Token JWT manquant ou expiré, session expirée. |
| 402 | Payment Required | Paiement requis pour accéder à cette ressource. | Contenu premium, quota d'API dépassé (Google Maps, Stripe). |
| 403 | Forbidden | Accès interdit même authentifié. Permissions insuffisantes. | Rôle utilisateur insuffisant (admin requis), IP bloquée. |
| 404 | Not Found | La ressource n'existe pas à cette URL. | Article supprimé, ID inexistant, URL mal tapée. |
| 405 | Method Not Allowed | La méthode HTTP utilisée n'est pas autorisée sur cette ressource. | DELETE sur une route qui n'accepte que GET/POST. |
| 406 | Not Acceptable | Le serveur ne peut pas répondre dans le format demandé (header Accept). |
Client demande du XML mais l'API ne produit que du JSON. |
| 407 | Proxy Authentication Required | Authentification auprès d'un proxy intermédiaire requise. | Accès via proxy d'entreprise nécessitant des identifiants. |
| 408 | Request Timeout | Le client a mis trop de temps à envoyer sa requête. | Connexion lente, client inactif trop longtemps. |
| 409 | Conflict | Conflit avec l'état actuel de la ressource. | Tentative de création d'un utilisateur avec un email déjà existant. |
| 410 | Gone | La ressource existait mais a été supprimée définitivement. | Article supprimé volontairement, compte désactivé. |
| 411 | Length Required | Le header Content-Length est obligatoire pour cette requête. |
Upload de fichier sans indiquer la taille du contenu. |
| 412 | Precondition Failed | Une précondition dans les en-têtes (If-Match, If-Unmodified-Since) n'est pas satisfaite. |
Mise à jour concurrente — optimistic locking dans les APIs. |
| 413 | Content Too Large | Le corps de la requête dépasse la taille maximale autorisée par le serveur. | Upload d'un fichier dépassant la limite configurée (ex : 10 MB). |
| 414 | URI Too Long | L'URL de la requête dépasse la longueur maximale acceptée par le serveur. | Paramètres trop nombreux dans l'URL (utiliser POST plutôt que GET). |
| 415 | Unsupported Media Type | Le format du corps de la requête n'est pas supporté par le serveur. | Envoyer du XML alors que l'API attend du JSON (Content-Type: application/json manquant). |
| 416 | Range Not Satisfiable | La plage demandée (header Range) est en dehors des limites de la ressource. |
Téléchargement reprenant à une position au-delà de la fin du fichier. |
| 417 | Expectation Failed | Le serveur ne peut pas satisfaire la valeur du header Expect. |
Header Expect: 100-continue non supporté. |
| 418 | I'm a teapot | Poisson d'avril RFC 2324. Un théière refuse de préparer du café. | Easter egg — utilisé par certains services pour indiquer des requêtes absurdes ou humoristiques. |
| 421 | Misdirected Request | La requête a été envoyée à un serveur qui ne peut pas produire de réponse. | Configuration incorrecte de virtual hosting ou de SNI TLS. |
| 422 | Unprocessable Content | La requête est syntaxiquement correcte mais sémantiquement invalide (validation échouée). | Erreurs de validation métier : email invalide, date dans le passé, montant négatif. |
| 423 | Locked (WebDAV) | La ressource est verrouillée et ne peut être modifiée. | Document en cours d'édition par un autre utilisateur (WebDAV). |
| 424 | Failed Dependency (WebDAV) | L'action a échoué car une action précédente dont elle dépendait a échoué. | Transactions WebDAV avec dépendances entre ressources. |
| 425 | Too Early | Le serveur refuse de traiter une requête qui pourrait être rejouée. | Requêtes TLS 0-RTT — protection contre les attaques par rejeu. |
| 426 | Upgrade Required | Le client doit utiliser un protocole plus récent (indiqué dans Upgrade). |
Forcer la migration vers TLS 1.3 ou HTTP/2. |
| 428 | Precondition Required | Le serveur exige que la requête soit conditionnelle (header If-Match obligatoire). |
Prévenir les mises à jour "à l'aveugle" — obliger le client à fournir un ETag. |
| 429 | Too Many Requests | Le client a envoyé trop de requêtes dans un intervalle de temps. | Rate limiting API — inclure Retry-After dans la réponse. |
| 431 | Request Header Fields Too Large | Les en-têtes de la requête dépassent la taille maximale autorisée. | Cookies excessifs, token JWT trop grand, trop d'en-têtes personnalisés. |
| 451 | Unavailable For Legal Reasons | La ressource est inaccessible pour des raisons légales (censure, RGPD, DMCA). | Contenu bloqué dans certains pays, retrait suite à une décision de justice. |
Exemples de réponses JSON pour les erreurs 4xx les plus courantes
// 400 Bad Request — corps JSON mal formé ou paramètre invalide
{
"error": "Bad Request",
"status": 400,
"message": "Le champ 'email' est requis.",
"details": [
{ "field": "email", "issue": "missing" },
{ "field": "age", "issue": "must be a positive integer" }
]
}
// 401 Unauthorized — token manquant ou expiré
{
"error": "Unauthorized",
"status": 401,
"message": "Token d'authentification manquant ou expiré.",
"hint": "Ajoutez le header Authorization: Bearer "
}
// 403 Forbidden — authentifié mais droits insuffisants
{
"error": "Forbidden",
"status": 403,
"message": "Vous n'avez pas les permissions pour effectuer cette action.",
"requiredRole": "admin"
}
// 404 Not Found — ressource introuvable
{
"error": "Not Found",
"status": 404,
"message": "L'article avec l'identifiant 99 n'existe pas.",
"resource": "/api/articles/99"
}
// 422 Unprocessable Content — erreurs de validation métier
{
"error": "Unprocessable Content",
"status": 422,
"message": "Les données soumises ne sont pas valides.",
"errors": [
{ "field": "email", "message": "Format d'email invalide." },
{ "field": "birthdate", "message": "La date de naissance doit être dans le passé." },
{ "field": "price", "message": "Le prix ne peut pas être négatif." }
]
}
// 429 Too Many Requests — rate limiting atteint
{
"error": "Too Many Requests",
"status": 429,
"message": "Limite de requêtes dépassée. Réessayez dans 60 secondes.",
"retryAfter": 60,
"limit": 100,
"remaining": 0,
"resetAt": "2026-05-13T10:05:00Z"
}
Codes 5xx — Erreurs serveur
Les codes 5xx indiquent que le serveur a rencontré une erreur lors du traitement d'une requête valide du client. Contrairement aux erreurs 4xx, la faute revient au serveur. Ces erreurs doivent être surveillées activement en production et ne jamais exposer de détails techniques sensibles aux clients.
| Code | Nom | Description | Cause fréquente |
|---|---|---|---|
| 500 | Internal Server Error | Erreur générique côté serveur. Quelque chose a mal tourné. | Exception non gérée, bug applicatif, erreur de base de données. |
| 501 | Not Implemented | La méthode HTTP demandée n'est pas implémentée par le serveur. | Méthode HTTP exotique non supportée (PATCH sur un serveur legacy). |
| 502 | Bad Gateway | Le serveur, agissant en proxy, a reçu une réponse invalide du serveur en amont. | Application PHP crashée, conteneur Docker stoppé, upstream Nginx KO. |
| 503 | Service Unavailable | Le serveur est temporairement indisponible (surcharge ou maintenance). | Maintenance planifiée, autoscaling en cours, surcharge de CPU/RAM. |
| 504 | Gateway Timeout | Le serveur proxy n'a pas reçu de réponse de l'upstream dans les délais. | Requête trop longue (requête SQL complexe, API tierce lente). |
| 505 | HTTP Version Not Supported | La version du protocole HTTP utilisée n'est pas supportée. | Client forçant HTTP/3 sur un serveur ne supportant que HTTP/1.1. |
| 506 | Variant Also Negotiates | Erreur de configuration dans la négociation de contenu transparente. | Mauvaise configuration des variants de contenu côté serveur. |
| 507 | Insufficient Storage (WebDAV) | Le serveur ne peut pas stocker la représentation nécessaire pour terminer la requête. | Disque plein lors d'un upload ou d'une opération WebDAV. |
| 508 | Loop Detected (WebDAV) | Le serveur a détecté une boucle infinie lors du traitement de la requête. | Liens symboliques circulaires dans une collection WebDAV. |
| 510 | Not Extended | Des extensions supplémentaires sont nécessaires pour traiter la requête. | Protocole d'extension HTTP non satisfait par le serveur. |
| 511 | Network Authentication Required | Le client doit s'authentifier pour accéder au réseau (portail captif). | Wi-Fi d'hôtel, hotspot public demandant une connexion via portail web. |
Les codes 502, 503 et 504 en détail
Ces trois codes sont fréquemment confondus en environnement avec proxy inverse (Nginx, HAProxy, Cloudflare) :
- 502 Bad Gateway : l'application en amont (PHP-FPM, Node.js, container) a renvoyé une réponse invalide ou s'est plantée.
- 503 Service Unavailable : l'application est volontairement indisponible (déploiement, maintenance) ou surchargée.
- 504 Gateway Timeout : l'application a mis trop de temps à répondre — le proxy a coupé la connexion avant la fin du traitement.
- Configurez des pages d'erreur personnalisées (503.html statique) servies directement par Nginx — elles fonctionnent même si l'application est complètement KO.
- Activez des alertes immédiates (PagerDuty, Slack webhook) sur toute occurrence de 500, 502, 503 ou 504.
- Stockez les détails d'erreur dans les logs serveur uniquement — ne retournez jamais les stack traces ou les messages d'exception au client.
- Pour le 503, retournez le header
Retry-Afterpour indiquer au client la durée estimée de la maintenance.
HTTP/1.1 503 Service Unavailable
Content-Type: application/json; charset=utf-8
Retry-After: 3600
{
"error": "Service Unavailable",
"status": 503,
"message": "Maintenance planifiée en cours. Service disponible dans environ 1 heure.",
"retryAfter": 3600
}
Bonnes pratiques API REST
Utiliser les bons codes HTTP dans une API REST n'est pas optionnel — c'est un contrat implicite avec les consommateurs de votre API. Un code 200 sur une erreur, ou un 500 pour un problème de validation, crée de la confusion et rend le débogage difficile.
Tableau CRUD — quel code HTTP retourner
| Opération | Méthode HTTP | Code succès | Codes d'erreur courants |
|---|---|---|---|
| Lire une liste | GET /articles |
200 OK | 401, 403, 500 |
| Lire une ressource | GET /articles/1 |
200 OK | 401, 403, 404 |
| Créer une ressource | POST /articles |
201 Created | 400, 401, 403, 409, 422 |
| Remplacer entièrement | PUT /articles/1 |
200 OK | 400, 401, 403, 404, 422 |
| Mettre à jour partiellement | PATCH /articles/1 |
200 OK | 400, 401, 403, 404, 422 |
| Supprimer une ressource | DELETE /articles/1 |
204 No Content | 401, 403, 404 |
| Action métier (non CRUD) | POST /articles/1/publish |
200 OK | 400, 401, 403, 404, 409, 422 |
| Authentification | POST /auth/login |
200 OK | 400, 401, 422, 429 |
Structure de réponse JSON standardisée
Adoptez une structure cohérente pour toutes vos réponses, succès comme erreurs :
// Structure de réponse succès avec pagination
{
"status": "success",
"data": [
{ "id": 1, "title": "Guide HTTP complet", "category": "html" },
{ "id": 2, "title": "REST API Design", "category": "back" }
],
"meta": {
"total": 142,
"page": 1,
"perPage": 20,
"lastPage": 8
}
}
// Structure de réponse erreur — format RFC 7807 (Problem Details)
{
"type": "https://api.example.com/problems/validation-error",
"title": "Erreur de validation",
"status": 422,
"detail": "Les données soumises contiennent des erreurs.",
"instance": "/api/articles",
"errors": [
{
"field": "title",
"message": "Le titre est requis et doit contenir entre 10 et 60 caractères."
},
{
"field": "category",
"message": "La catégorie 'unknown' n'est pas valide. Valeurs acceptées : html, css, js."
}
]
}
- Utiliser 201 (pas 200) pour la création d'une ressource via POST
- Retourner 204 No Content pour une suppression réussie — sans corps de réponse
- Distinguer 400 (syntaxe invalide) de 422 (règle métier violée)
- Distinguer 401 (non authentifié) de 403 (authentifié mais non autorisé)
- Utiliser 409 Conflict pour les doublons ou conflits d'état (pas 422)
- Inclure
Retry-Afterdans les réponses 429 et 503 - Inclure
Locationdans les réponses 201 et 301/302 - Ne jamais retourner 200 OK avec un corps contenant une erreur ("success: false")
- Adopter le format RFC 7807 (Problem Details) pour les réponses d'erreur
- Logger les 4xx (pour détecter les bugs clients) et les 5xx (pour détecter les bugs serveur)
200 OK avec un champ "success": false dans le corps JSON. Ce pattern, fréquent dans les anciennes APIs, rend les codes HTTP inutiles et oblige chaque client à parser le corps pour détecter une erreur. Utilisez les vrais codes HTTP — c'est pour ça qu'ils existent.
Conclusion
Les codes de statut HTTP sont le langage universel du web. Maîtriser les cinq familles — 1xx informationnel, 2xx succès, 3xx redirection, 4xx erreur client, 5xx erreur serveur — est indispensable pour concevoir des APIs cohérentes, debugger efficacement et optimiser le référencement de vos sites.
La prochaine fois que vous concevez un endpoint d'API, posez-vous toujours ces deux questions : "Quelle est la sémantique exacte de cette opération ?" et "Quel code HTTP exprime le mieux ce résultat ?". Un bon choix de code HTTP réduit la documentation nécessaire et accélère l'intégration pour les développeurs qui consomment votre API.