Selecting the right status code improves client behavior, caching efficiency, SEO, and observability.


Pick the status class

flowchart TD A[Request handled successfully] A -->|Yes| S[2xx] A -->|No| Q{Client problem} Q -->|Yes| C[4xx] Q -->|No| E[5xx]
  • 2xx: the server accepted and completed the request.
  • 4xx: the request is invalid or not allowed.
  • 5xx: the server or an upstream failed to process a valid request.

Success details: 200 vs 201 vs 202 vs 204

flowchart TD S[2xx] --> K{Created new resource} K -->|Yes| C201[201 Created] K -->|No| P{Processing deferred} P -->|Yes| C202[202 Accepted] P -->|No| B{Response body present} B -->|Yes| C200[200 OK] B -->|No| C204[204 No Content]
  • 201 Created: resource was created; include a Location header.
  • 202 Accepted: accepted for processing; finish later; provide a status endpoint or webhook if possible.
  • 200 OK: success with a representation in the body.
  • 204 No Content: success with no body to return.

Conditional responses: 200 vs 304

flowchart TD P[Conditional request] P --> J{Representation changed} J -->|No| N304[304 Not Modified] J -->|Yes| N200[200 OK]
  • 304 Not Modified: client can reuse its cached representation.
  • 200 OK: representation changed or no valid validators.

Authentication vs authorization: 401 vs 403

flowchart TD A[Access failed] --> X{Credentials present and valid} X -->|No| U401[401 Unauthorized] X -->|Yes| F403[403 Forbidden]
  • 401 Unauthorized: include WWW-Authenticate with the challenge.
  • 403 Forbidden: user is authenticated but not allowed.

Validation vs business rules: 400 vs 422

flowchart TD V[Request invalid] V --> P{Syntax or schema malformed} P -->|Yes| B400[400 Bad Request] P -->|No| B422[422 Unprocessable Content]
  • 400 Bad Request: malformed JSON, wrong types, missing required fields.
  • 422 Unprocessable Content: syntactically valid but fails business rules or domain validation.

Redirects

See the dedicated guide: Redirects Deep Dive: 301 vs 302 vs 307 vs 308


CDN notes

  • 2xx and 3xx are often cacheable when headers allow; 304 reduces origin bandwidth.
  • Short defensive caching for select 4xx can protect origins.
  • 5xx is usually not cacheable; use retries, shields, multi-origin setups, and stale-if-error where supported.

See also