Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 316 minIntermédiaire

Codes de statut HTTP : 200, 201, 400, 401, 403, 404, 500

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • classer un code de statut dans sa famille et dire qui doit agir ;
  • choisir entre 401, 403 et 404, et entre 400, 409 et 422 ;
  • repérer les mauvais choix de code dans une API existante ;
  • lire un journal d'accès et y reconnaître une anomalie.

3 exercices corrigés1 schéma

Un code de statut HTTP est le nombre à trois chiffres que le serveur place en tête de chaque réponse pour dire ce qui s'est passé : 200 pour une réussite, 404 pour une ressource introuvable, 500 pour une panne du serveur. Le premier chiffre donne la famille (succès, redirection, erreur du client, erreur du serveur). Ce chapitre présente les codes qu'une API utilise vraiment, comment choisir entre des codes voisins (401, 403 et 404 ; 400 et 422) et les erreurs de choix les plus fréquentes.

Cinq familles

FamilleSensQui doit agirExemples
1xx InformationRéponse provisoire, la suite arrivePersonne : c'est géré par le protocole100 Continue, 103 Early Hints
2xx SuccèsLa requête a été comprise et traitéePersonne200, 201, 202, 204
3xx RedirectionLa ressource est ailleurs, ou la copie du client est encore bonneLe client suit la redirection ou réutilise sa copie301, 304, 307, 308
4xx Erreur du clientLa requête est incorrecte ou refuséeLe client doit corriger sa requête400, 401, 403, 404, 409, 422, 429
5xx Erreur du serveurLa requête semblait correcte, mais le serveur a échouéLe serveur (ses développeurs, son exploitant)500, 502, 503, 504

La distinction entre 4xx et 5xx est la plus importante : elle dit de quel côté est le problème. Un client qui reçoit 400 sait que renvoyer la même requête ne servira à rien ; un client qui reçoit 503 peut réessayer plus tard.

Les codes de succès (2xx)

CodeLibelléQuand le renvoyerCorps
200OKLecture réussie (GET), modification réussie (PUT, PATCH) qui renvoie la ressourceLa ressource ou la liste
201CreatedUne ressource a été créée, en général par POSTLa ressource créée, avec l'en-tête Location qui donne son URI
202AcceptedLa demande est acceptée mais sera traitée plus tard (export, génération de PDF, envoi de masse)Souvent l'adresse où suivre l'avancement
204No ContentRéussite sans rien à renvoyer : suppression, modification qui ne renvoie pas la ressourceAucun corps

Une liste vide est une réussite : GET /v1/fiches?etat=VA qui ne trouve aucune fiche validée renvoie 200 avec une liste vide ([]), pas 404. La collection existe ; elle ne contient simplement rien qui corresponde au filtre.

Les redirections (3xx)

Une API redirige rarement, mais deux cas arrivent :

  • 304 Not Modified répond à une requête conditionnelle (If-None-Match) : la copie du client est toujours à jour (chapitre 2) ;
  • 308 Permanent Redirect et 307 Temporary Redirect déplacent une ressource en conservant la méthode et le corps. Leurs ancêtres 301 et 302 autorisent historiquement le client à transformer un POST en GET lors de la redirection, ce qui fait perdre le corps. Pour une API, préfère 308 et 307.

Les erreurs du client (4xx)

CodeLibelléQuand le renvoyerExemple dans AppliFrais
400Bad RequestLa requête est mal formée : JSON illisible, paramètre de type incorrectCorps {"mois": 2026-11 (accolade manquante)
401UnauthorizedPas d'authentification valide : jeton absent, invalide ou expiré. Ajoute l'en-tête WWW-AuthenticateRequête sans en-tête Authorization
403ForbiddenLe client est authentifié mais n'a pas le droitUn visiteur tente de valider une fiche, action réservée aux comptables
404Not FoundLa ressource n'existe pas (ou le client ne doit pas savoir qu'elle existe)GET /v1/fiches/999
405Method Not AllowedLa méthode n'est pas prévue sur cette URI. Ajoute l'en-tête AllowPUT /v1/fiches (on ne remplace pas une collection)
406Not AcceptableAucun format demandé dans Accept n'est disponibleAccept: application/xml sur une API JSON
409ConflictLa requête contredit l'état actuel de la ressourceCréer une deuxième fiche pour le même mois ; clôturer une fiche déjà validée
410GoneLa ressource a existé et a été retirée définitivementUne ancienne version de l'API arrêtée
412Precondition FailedLa condition If-Match n'est plus vraie : quelqu'un a modifié la ressource entre-tempsDeux comptables valident la même fiche en même temps
413Content Too LargeLe corps dépasse la taille permiseUn justificatif de 40 Mo pour une limite de 5 Mo
415Unsupported Media TypeLe format du corps (Content-Type) n'est pas acceptéCorps envoyé en XML à une API JSON
422Unprocessable ContentLe JSON est bien formé, mais son contenu viole les règles de validation{"mois":"2026-13"} : il n'y a pas de 13e mois
428Precondition RequiredLe serveur exige une requête conditionnelle (If-Match) pour éviter les écrasementsModification d'une fiche sans If-Match
429Too Many RequestsLe client a dépassé la limite de débit. Ajoute Retry-AfterPlus de 100 requêtes par minute avec la même clé

Les erreurs du serveur (5xx)

CodeLibelléCe qui s'est passé
500Internal Server ErrorUne erreur non prévue dans le code : exception non attrapée, bogue. Le détail va dans le journal, jamais dans la réponse
501Not ImplementedLe serveur ne connaît pas la méthode demandée
502Bad GatewayUn intermédiaire (reverse proxy nginx, passerelle d'API) a reçu une réponse invalide du serveur d'application, souvent parce qu'il est arrêté ou a planté
503Service UnavailableLe service est momentanément indisponible : maintenance, surcharge. Ajoute Retry-After si tu connais la durée
504Gateway TimeoutL'intermédiaire n'a pas reçu de réponse à temps du serveur d'application ou d'un service appelé

401, 403 ou 404 ?

C'est la question d'examen la plus fréquente sur les API. Pose-toi les questions dans l'ordre :

  1. Le serveur sait-il qui fait la requête ? Pas de jeton, jeton expiré, signature fausse, clé d'API inconnue : 401 Unauthorized. Le nom du code est trompeur, il signifie en réalité « non authentifié ».
  2. Le client a-t-il le droit de faire cette action sur cette ressource ? Le visiteur est bien identifié mais veut valider une fiche (réservé aux comptables) : 403 Forbidden.
  3. La ressource existe-t-elle ? GET /v1/fiches/999 alors que la fiche 999 n'existe pas : 404 Not Found.

Un cas mérite réflexion : Lucas demande la fiche 1188, qui existe mais appartient à une autre visiteuse. Répondre 403 est exact, mais révèle que la fiche 1188 existe : en essayant 1187, 1189, 1190…, un curieux dresse la liste des fiches. Beaucoup d'API répondent donc 404 pour une ressource qui appartient à quelqu'un d'autre : pour ce client, elle n'existe pas. Les deux réponses se défendent ; l'essentiel est que la fiche ne soit jamais renvoyée. Ce contrôle manquant est la faille n° 1 des API (BOLA, chapitre 10).

400 ou 422 ?

Les deux signalent une requête à corriger. La frontière :

  • 400 Bad Request : la requête est mal formée. Le serveur ne peut même pas la lire : JSON syntaxiquement faux, paramètre ?page=abc alors qu'un nombre est attendu, en-tête obligatoire absent.
  • 422 Unprocessable Content : la requête est bien formée, le JSON est valide et du bon type, mais son contenu viole une règle de validation : un mois 2026-13, un montant négatif, un champ obligatoire vide.

Toutes les API ne font pas cette distinction : beaucoup renvoient 400 pour tout problème de saisie, et ce n'est pas faux. Ce qui compte, c'est la cohérence dans toute l'API, et un corps d'erreur qui dit précisément quel champ pose problème.

Et 409 ? Il ne concerne pas le format mais l'état : la fiche d'octobre est valide en soi, mais elle existe déjà ; la demande de clôture est bien formée, mais la fiche est déjà validée. Les données seraient acceptables dans un autre contexte.

1. Le client est-il authentifié ?non401Unauthorizedoui2. La requête est-elle lisible ?non400Bad Requestoui3. La ressource existe-t-elle pour lui ?non404Not Foundoui4. A-t-il le droit de faire cette action ?non403Forbiddenoui5. Les données respectent-elles les règles ?non422Unprocessable Contentoui6. L'action est-elle compatible avec l'état ?non409ConflictouiRequête traitée : 200, 201 ou 204
Choisir le code d'erreur : six questions, dans l'ordre où l'API les vérifie

L'ordre de l'arbre suit l'ordre des contrôles dans le code : on authentifie d'abord (sinon on ne sait pas quoi vérifier), on lit la requête, on cherche la ressource, on vérifie les droits, on valide les données, puis on applique les règles de gestion. Quand la ressource appartient à un autre client, l'API peut fusionner les questions 3 et 4 et répondre 404, comme expliqué plus haut.

Les libellés ne comptent pas

Le libellé qui suit le code (OK, Not Found) est un texte destiné aux humains ; les programmes l'ignorent, et HTTP/2 ne le transmet même plus. Il a d'ailleurs changé pour deux codes avec la RFC 9110 : 413 s'appelle désormais Content Too Large (anciennement Payload Too Large) et 422 Unprocessable Content (anciennement Unprocessable Entity). Beaucoup de serveurs affichent encore les anciens libellés : Node.js répond HTTP/1.1 422 Unprocessable Entity. C'est sans conséquence.

Les erreurs de choix les plus fréquentes

ErreurPourquoi c'est fauxCorrection
200 avec {"erreur": "Fiche introuvable"}Le client, le cache, la supervision et le navigateur croient à une réussite ; le front doit lire le corps pour comprendre404 avec un corps d'erreur
500 quand une saisie est invalideLe problème vient du client ; un 500 fait croire à une panne et déclenche des alertes400 ou 422
404 pour une liste videLa collection existe ; elle est vide200 et []
401 quand le rôle est insuffisantLe client est bien authentifié ; se reconnecter ne changera rien403
403 sans jetonLe serveur ne sait pas qui appelle401 avec WWW-Authenticate
200 après une créationLe client ne sait pas qu'une ressource a été créée, ni où201 avec Location
Le détail d'une exception renvoyé avec un 500Fuite d'informations : chemins de fichiers, requêtes SQL, versionsMessage générique au client, détail dans le journal

Exercices

Exercice 1 sur 3 Le bon code de statut Réussi À revoir

Donne le code que l'API d'AppliFrais doit renvoyer dans chaque situation.

  1. Lucas lit la liste de ses fiches.
  2. Lucas crée sa fiche de décembre 2026.
  3. Lucas supprime un frais hors forfait de sa fiche en cours ; l'API ne renvoie rien.
  4. Une requête arrive sans en-tête Authorization.
  5. Lucas, visiteur, appelle PATCH /v1/fiches/12 avec {"etat":"VA"} : la validation est réservée aux comptables.
  6. Le corps envoyé est {"montant": 23.5, (le JSON s'arrête là).
  7. Le corps est un JSON valide, mais le montant vaut -15.
  8. Lucas crée une fiche pour octobre 2026, qui existe déjà.
  9. Un script envoie 300 requêtes en une minute, pour une limite de 100.
  10. La base de données ne répond plus et l'API ne peut rien lire.
  11. Le front demande GET /v1/fiches?etat=MP et Lucas n'a aucune fiche mise en paiement.
  12. Un client envoie DELETE /v1/fiches, qui n'est pas prévu.
Voir la réponseMasquer la réponse de l'exercice 1
  1. 200 OK, avec la liste.
  2. 201 Created, avec la fiche dans le corps et Location: /v1/fiches/<id>.
  3. 204 No Content.
  4. 401 Unauthorized, avec WWW-Authenticate: Bearer.
  5. 403 Forbidden : Lucas est authentifié mais son rôle ne permet pas de valider.
  6. 400 Bad Request : le JSON est mal formé, le serveur ne peut pas le lire.
  7. 422 Unprocessable Content (ou 400 si l'API ne distingue pas les deux) : le JSON est valide mais la donnée viole une règle.
  8. 409 Conflict : la demande contredit l'état existant (une seule fiche par mois).
  9. 429 Too Many Requests, avec Retry-After.
  10. 503 Service Unavailable si l'API détecte l'indisponibilité et la signale ; un 500 si l'erreur n'est pas gérée. Dans les deux cas, aucun détail technique dans la réponse.
  11. 200 OK avec une liste vide : la collection existe.
  12. 405 Method Not Allowed, avec Allow: GET, POST.

Tu avais trouvé ?

Exercice 2 sur 3 Corriger les codes d'une API Réussi À revoir

Un stagiaire a écrit une API de prêt de matériel. Repère et corrige les codes inadaptés.

RequêteSituationCode renvoyé
POST /v1/pretsPrêt créé200
GET /v1/prets/45Le prêt 45 n'existe pas200 avec {"erreur":"inconnu"}
POST /v1/pretsDate de retour antérieure à la date de prêt500
DELETE /v1/prets/12Jeton valide, mais l'utilisateur n'est pas gestionnaire401
GET /v1/materiels?type=tabletteAucune tablette404
POST /v1/pretsLe matériel demandé est déjà prêté400
Voir la réponseMasquer la réponse de l'exercice 2
RequêteCode correctRaison
POST /v1/prets, prêt créé201 avec LocationUne ressource a été créée
GET /v1/prets/45, inexistant404Le code doit dire l'échec, pas le corps seul
Dates incohérentes422 (ou 400)Erreur de saisie du client, pas panne du serveur
Pas gestionnaire403L'utilisateur est authentifié ; c'est son rôle qui est insuffisant
Aucune tablette200 et []Une liste vide est une réussite
Matériel déjà prêté409Le conflit vient de l'état actuel du matériel, pas du format de la requête

Tu avais trouvé ?

Exercice 3 sur 3 Lire un journal d'accès Réussi À revoir

Voici un extrait du journal du reverse proxy devant l'API (format simplifié : heure, adresse IP, requête, code).

text
09:14:02 203.0.113.50 GET /v1/fiches/1180 200
09:14:02 203.0.113.50 GET /v1/fiches/1181 404
09:14:03 203.0.113.50 GET /v1/fiches/1182 200
09:14:03 203.0.113.50 GET /v1/fiches/1183 200
09:14:03 203.0.113.50 GET /v1/fiches/1184 200
09:14:04 203.0.113.50 GET /v1/fiches/1185 429
09:31:47 198.51.100.7 POST /v1/fiches 502
  1. Que fait le client 203.0.113.50 ? Sachant qu'un visiteur ne possède qu'une fiche par mois, quel problème ces codes 200 révèlent-ils ?
  2. Quel mécanisme l'a arrêté à 09:14:04 ?
  3. Que t'apprend la dernière ligne, et où chercher la cause ?
Voir la réponseMasquer la réponse de l'exercice 3
  1. Il énumère les fiches en incrémentant l'identifiant, quatre requêtes par seconde. Un visiteur ne peut pas posséder les fiches 1180, 1182, 1183 et 1184 : l'API renvoie donc les fiches d'autres visiteurs. Elle vérifie l'authentification mais pas que la fiche appartient au demandeur : c'est une faille de contrôle d'accès à l'objet (BOLA). Elle aurait dû répondre 404 (ou 403) pour chaque fiche d'autrui.
  2. La limitation de débit : 429 Too Many Requests. Elle freine l'énumération mais ne corrige pas la faille.
  3. 502 Bad Gateway : le reverse proxy n'a pas obtenu de réponse valide du serveur d'application. Il faut regarder si le processus de l'API tourne encore et lire son journal à 09:31:47, pas chercher une erreur dans la requête du client.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Principes REST : ressources, URI et contraintesRevoir le sommaire du cours