Lesson 5 / 25

HTTP Status Codes

Choose the right 2xx, 3xx, 4xx and 5xx status codes so clients, proxies and monitoring read outcomes without parsing JSON.

The five families

2xx success (200 OK, 201 Created, 204 No Content). 3xx redirection (301 Moved, 304 Not Modified). 4xx the client made a mistake (400 Bad Request, 401/403 auth, 404 Not Found). 5xx the server failed (500 Internal Error, 503 Unavailable).

Common picks

A few codes cover most real responses.

200 OK              - GET/PUT/PATCH succeeded
201 Created         - POST created a resource
204 No Content      - DELETE succeeded, no body
400 Bad Request     - malformed input
401 Unauthorized    - missing/invalid credentials
403 Forbidden       - authenticated, not allowed
404 Not Found       - resource doesn't exist
409 Conflict        - state conflict (duplicate, version clash)
422 Unprocessable   - valid JSON, invalid semantics
429 Too Many Requests
500 Internal Server Error
503 Service Unavailable

Don't always return 200

A common anti-pattern is 200 OK with { "success": false } in the body. Let the status code carry the outcome — clients, proxies, and monitoring tools all read it without parsing JSON.

Quick check: A client sends valid JSON, but tries to create a user with an email that already exists. Which status code fits best?

  • 400 Bad Request
  • 500 Internal Server Error
  • 200 OK with an error message
  • 409 Conflict
Answer

409 Conflict — 409 Conflict signals the request is well-formed but clashes with the current state of the resource (a duplicate).