Skip to content

Choosing Status Codes

A handful of status codes cover almost every case. The skill is in the close calls — the pairs that are easy to confuse.

  • 200 OK — success with a body.
  • 201 Created — a resource was created; include a Location header.
  • 204 No Content — success, nothing to return (e.g. a DELETE).
  • 400 Bad Request — the request is malformed (bad JSON, missing required parts).
  • 401 Unauthorized — no/invalid credentials; the client must authenticate.
  • 403 Forbidden — authenticated, but not allowed.
  • 404 Not Found — no such resource.
  • 409 Conflict — the request conflicts with current state (duplicate, version clash).
  • 422 Unprocessable Entity — syntactically valid but semantically invalid (failed validation).
  • 429 Too Many Requests — rate limited.
  • 500 Internal Server Error / 503 Service Unavailable — the server failed.
  • 200 vs 201 vs 204 — returning a body → 200; created a resource → 201; nothing to say → 204.
  • 400 vs 422 — can the server even parse the request? Unparseable → 400; parsed fine but the values are invalid → 422.
  • 401 vs 403 — do we know who you are? Not authenticated → 401; authenticated but not permitted → 403.
  • 404 vs 409 — the resource does not exist → 404; it exists but your request conflicts with its state → 409.
JavaScript
The request body is valid JSON but a required field is missing. Best code?
The caller is authenticated but lacks permission. Which code?
A create request duplicates a resource that already exists. Which code fits?