HTTP Status Codes (2xx, 4xx, 5xx)

Status codes tell the client whether the request succeeded, failed because of the client (4xx), or failed because of the server (5xx). Using them correctly helps clients retry, show errors, and cache correctly.

Code ranges

flowchart LR subgraph 2xx[2xx Success] A[200 OK] B[201 Created] C[204 No Content] end subgraph 4xx[4xx Client Error] D[400 Bad Request] E[401 Unauthorized] F[403 Forbidden] G[404 Not Found] end subgraph 5xx[5xx Server Error] H[500 Internal] I[502 Bad Gateway] J[503 Unavailable] end
CodeMeaningWhen to use
200OKSuccess (GET, PUT, PATCH)
201CreatedResource created (POST), include Location header
204No ContentSuccess, no body (e.g. DELETE)
400Bad RequestInvalid input, malformed body
401UnauthorizedNot authenticated (login / token missing or invalid)
403ForbiddenAuthenticated but not allowed to do this
404Not FoundResource doesn’t exist (or hide existence with 403)
500Internal Server ErrorUnexpected server bug
502Bad GatewayInvalid response from upstream
503Service UnavailableOverloaded or down; retry later

Who is at fault?

flowchart TB R[Request] --> D{Valid?} D -->|No| C[4xx - Client fix] D -->|Yes| S{Server OK?} S -->|No| E[5xx - Retry / back off] S -->|Yes| O[2xx - Success] C --> C1[400, 401, 403, 404...] E --> E1[500, 502, 503]

401 vs 403: Use 401 when the user is not identified (missing or bad credentials). Use 403 when the user is known but not permitted to perform the action.