Choosing HTTP status codes

API design: REST, HTTP, GraphQL and gRPC Junior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Pick the fix

A logged-in user requests another customer's invoice they may not see. Which response?

Options
Hint 1 of 1

Is the problem who they are, or what they may do?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A 403 Forbidden, or 404 if you don't want to reveal the invoice exists

Correct. Authenticated but not allowed; 404 hides existence.

401 asks the client to authenticate and 403 says who they are is known but the answer is no. Some APIs answer 404 instead, so a caller can't probe which invoice ids exist.

Why not the others?
  • B 401 Unauthorized. 401 means 'authenticate'; they already did.
  • C 400 Bad Request. The request is well-formed.
  • D 200 with an empty body. Hides a denial as success and confuses clients.

30-second answer

Use the code clients can act on. 400 for a malformed request, 422 when it's well-formed but fails validation, 401 when credentials are missing or invalid (the client should authenticate), 403 when the caller is known but not allowed, 404 when it doesn't exist (or to hide that it does), 409 for a conflict with current state, 412 when an If-Match precondition fails, 429 for rate limits with Retry-After, and 503 when the server is temporarily unavailable.

Practise saying it · 35 s. No recording, just a timer

Pick status codes for an API.

Say your answer out loud, then check which of these points you covered:

  • 4xx client must change
  • 5xx server failed
  • 401 vs 403
  • 409, 412, 422
  • 429 with Retry-After

Deep dive

201 Created with Location for new resources; 202 Accepted for work that continues in the background; 204 No Content for success with no body.

5xx means the server failed and the client may retry; 4xx means the client must change something.

Returning 200 with an error body breaks monitoring, caches and clients.

Document the codes each endpoint can return.

Common mistakes

  • 200 for everything with an 'error' field.
  • 401 when the user is logged in but lacks permission (that's 403).
  • 500 for validation errors.

Senior take & follow-ups

Group by who must act (client vs server) and give the common codes with one-line meanings.

Follow-up questions

Think of your answer first, then open the hint.

  1. 401 or 404 for another tenant's resource?

    Show hint

    404 often, to avoid revealing it exists.

  2. When is 202 right?

    Show hint

    When the work is queued; return a status URL.

Suggest a fix if something here is wrong or out of date.