Référence développeur/API pour les méthodes HTTP, les codes de statut et les headers les plus courants. Ces éléments sont le vocabulaire de toute API REST, GraphQL ou WebSocket.

Pour la structure bas niveau des requêtes HTTP, TLS et les versions du protocole → Requêtes HTTP et HTTPS


Méthodes HTTP

MéthodeSémantiqueIdempotentSafeBody requêteBody réponse
GETLire une ressourceNonOui
POSTCréer / soumettreOuiOui
PUTRemplacer entièrementOuiOui
PATCHModifier partiellement✅*OuiOui
DELETESupprimerNonRarement
HEADComme GET, sans le body de réponseNonNon
OPTIONSMéthodes autorisées sur cette URL (CORS preflight)NonOui

Idempotent : appeler N fois donne le même résultat qu’une seule fois.
Safe : ne modifie pas l’état du serveur (lecture seule).

Quand utiliser PATCH vs PUT ?

Ressource : { "id": 42, "name": "Alice", "role": "admin", "email": "alice@ex.com" }

PUT /users/42  ← remplace TOUT l'objet
Body : { "name": "Alice", "role": "viewer", "email": "alice@ex.com" }
       ↑ doit inclure tous les champs, même ceux non modifiés

PATCH /users/42  ← modifie uniquement ce qui est envoyé
Body : { "role": "viewer" }
       ↑ seul le champ modifié est nécessaire

Codes de statut HTTP

2xx — Succès

CodeSignificationQuand l’utiliser
200 OKRequête réussieGET, PUT, PATCH — réponse avec body
201 CreatedRessource crééePOST réussi — inclure Location: /users/42
202 AcceptedAccepté mais traitement asynchroneTâches longues (background jobs)
204 No ContentSuccès sans bodyDELETE, PUT sans retour
206 Partial ContentContenu partielTéléchargement avec Range

3xx — Redirection

CodeSignificationQuand l’utiliser
301 Moved PermanentlyURL définitivement déplacéeMigration de domaine
302 FoundRedirection temporaireRedirection après POST (PRG pattern)
304 Not ModifiedContenu inchangéCache côté client toujours valide
307 Temporary RedirectRedirection temporaire (méthode conservée)Préférer à 302 pour les APIs
308 Permanent RedirectRedirection permanente (méthode conservée)Préférer à 301 pour les APIs

4xx — Erreur client

CodeSignificationQuand l’utiliser
400 Bad RequestRequête malforméeJSON invalide, paramètre manquant
401 UnauthorizedNon authentifiéToken absent, expiré ou invalide
403 ForbiddenNon autoriséAuthentifié mais pas les droits
404 Not FoundRessource introuvableID inexistant
405 Method Not AllowedMéthode non autoriséeDELETE sur une ressource en lecture seule
409 ConflictConflit d’étatEmail déjà utilisé, version obsolète
410 GoneRessource définitivement suppriméeRessource qui existait mais plus disponible
422 Unprocessable EntityDonnées sémantiquement incorrectesValidation métier échouée
429 Too Many RequestsRate limitingQuota dépassé — inclure Retry-After

5xx — Erreur serveur

CodeSignificationQuand l’utiliser
500 Internal Server ErrorErreur interne non géréeException non catchée
502 Bad GatewayLe proxy/LB n’a pas eu de réponse valideBackend en panne
503 Service UnavailableService temporairement indisponibleMaintenance, surcharge
504 Gateway TimeoutTimeout de réponseBackend trop lent

401 vs 403 — la confusion fréquente

401 Unauthorized (mal nommé — devrait être "Unauthenticated") :
  → Le serveur ne sait pas qui tu es
  → Tu dois t'authentifier (token manquant, expiré, invalide)
  → Réponse : "Connecte-toi d'abord"

403 Forbidden :
  → Le serveur sait qui tu es, mais tu n'as pas la permission
  → Tu es authentifié mais pas autorisé
  → Réponse : "Tu n'as pas les droits pour ça"

Headers HTTP importants

Headers de requête (Client → Serveur)

HeaderExempleRôle
Hostapi.exemple.comDomaine ciblé — obligatoire en HTTP/1.1
AuthorizationBearer eyJhbGci...Token d’authentification
Content-Typeapplication/jsonFormat du body envoyé
Acceptapplication/jsonFormat de réponse souhaité
Accept-Languagefr-FR, fr;q=0.9Langue préférée
Accept-Encodinggzip, deflate, brCompression acceptée
Cookiesession=abc123Cookies envoyés au serveur
User-AgentMozilla/5.0Identifiant du client
X-Forwarded-For192.168.1.5IP originale (ajoutée par le proxy)
X-Request-IDf47ac10b-58ccID unique de la requête (tracing)
Originhttps://app.exemple.comOrigine de la requête (CORS)
Refererhttps://exemple.com/pageURL de la page précédente
If-None-Match"abc123"ETag pour cache conditionnel
If-Modified-SinceSat, 01 Jan 2026 00:00:00 GMTDate pour cache conditionnel

Headers de réponse (Serveur → Client)

HeaderExempleRôle
Content-Typeapplication/json; charset=utf-8Format du body de réponse
Content-Length1234Taille du body en octets
Content-EncodinggzipCompression appliquée
Cache-Controlmax-age=3600, publicRègles de mise en cache
ETag"abc123"Version de la ressource (cache)
Last-ModifiedSat, 01 Jan 2026 00:00:00 GMTDate de dernière modification
Location/api/users/42URL de redirection (201, 301, 302)
Set-Cookiesession=xyz; HttpOnly; Secure; SameSite=StrictDéfinit un cookie
WWW-AuthenticateBearer realm="api"Méthode d’auth requise (401)
Retry-After60Secondes avant de réessayer (429, 503)
X-RateLimit-Limit1000Quota total
X-RateLimit-Remaining743Requêtes restantes
X-Request-IDf47ac10b-58ccID de la requête pour le tracing

Headers de sécurité

HeaderExempleRôle
Strict-Transport-Securitymax-age=31536000; includeSubDomainsForce HTTPS (HSTS)
Content-Security-Policydefault-src 'self'Empêche XSS et injection
X-Content-Type-OptionsnosniffEmpêche le MIME sniffing
X-Frame-OptionsDENYEmpêche le clickjacking (iframe)
Access-Control-Allow-Originhttps://app.exemple.comCORS — domaines autorisés
Access-Control-Allow-MethodsGET, POST, PUT, DELETECORS — méthodes autorisées
Permissions-Policygeolocation=()Contrôle les APIs navigateur

CORS — Cross-Origin Resource Sharing

Le navigateur bloque par défaut les requêtes vers un domaine différent de la page courante.

Page : https://app.exemple.com
API  : https://api.exemple.com   ← domaine différent → bloqué par défaut

Preflight (requête OPTIONS automatique du navigateur) :
  OPTIONS /api/users HTTP/1.1
  Origin: https://app.exemple.com
  Access-Control-Request-Method: POST
  Access-Control-Request-Headers: Content-Type, Authorization

Réponse du serveur si CORS configuré :
  HTTP/1.1 204 No Content
  Access-Control-Allow-Origin: https://app.exemple.com
  Access-Control-Allow-Methods: GET, POST, PUT, DELETE
  Access-Control-Allow-Headers: Content-Type, Authorization
  Access-Control-Max-Age: 86400   ← cache le preflight 24h
# FastAPI — configuration CORS
from fastapi.middleware.cors import CORSMiddleware
 
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.exemple.com"],  # jamais "*" en prod si credentials
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Authorization", "Content-Type"],
    allow_credentials=True,
)

Format des erreurs d’API

Une réponse d’erreur doit être cohérente et informative pour le client.

// Format recommandé (RFC 7807 — Problem Details)
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json
 
{
  "type": "https://api.exemple.com/errors/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "Le champ 'email' est invalide",
  "instance": "/api/users",
  "errors": [
    { "field": "email", "message": "Format invalide" },
    { "field": "role",  "message": "Valeur inconnue : 'superadmin'" }
  ]
}
// À éviter — retourner 200 avec une erreur dans le body
HTTP/1.1 200 OK
{ "success": false, "error": "something went wrong" }   ← antipattern

En relation avec