October 4, 2026 · Yunus Emre Vurgun

Which REST API Status Code Should I Return?

api · http · reference · tutorial

Return 200 for successful reads and updates, 201 when you create a resource, and 204 when there is nothing to send back. For client mistakes use 400 for malformed input, 401 for missing or invalid credentials, 403 for forbidden access, and 404 for absent resources; for server failures use 500, or 503 when the outage is temporary. The rules below cover every common case so you can pick the right code without guessing.

The 2xx codes: success with a difference

All 2xx codes mean the request worked, but each tells the client something different. Use 200 OK as the default for successful GET, PUT, and PATCH requests that return a body. Use 201 Created when a POST creates a new resource, and include a Location header pointing at the new resource so the client knows where to find it. Use 202 Accepted when the request is valid but will be processed asynchronously, such as a bulk import job or a video transcode — the response body should explain how to track progress. Use 204 No Content for successful requests that intentionally return no body, most commonly DELETE and some PUT or PATCH endpoints.

A frequent mistake is returning 200 with an empty body after a DELETE. That works, but 204 is more precise: it tells clients and intermediaries that the absence of a body is deliberate, not a truncated response. Conversely, never return 204 with a body — intermediaries are allowed to strip it, and some clients will ignore it.

The 4xx codes: the client made a mistake

Use 4xx codes when the request cannot be fulfilled because of something the client sent. The most useful ones for APIs fit in a small table:

CodeMeaningUse it when
400 Bad RequestMalformed requestThe JSON does not parse, a required field is missing, or a value has the wrong type.
401 UnauthorizedNot authenticatedNo credentials were sent, or the token is expired or invalid.
403 ForbiddenAuthenticated but not allowedThe user is logged in but lacks permission for this resource or action.
404 Not FoundNo such resourceThe id in the URL does not exist. Never use 404 for validation failures.
405 Method Not AllowedWrong verbThe resource exists but does not support this method; include an Allow header.
409 ConflictState conflictA duplicate unique value, a version mismatch, or an edit that collides with current state.
422 Unprocessable ContentValid syntax, bad semanticsThe JSON parses but the values fail business rules, such as an end date before a start date.
429 Too Many RequestsRate limitedThe client exceeded its quota; include a Retry-After header.

For the full reference behind this table, including the rarer codes, see the HTTP status codes cheat sheet and the HTTP status code best practices dataset.

401 vs 403: the most confused pair

Despite its name, 401 Unauthorized really means unauthenticated: the server does not know who you are. Return it when the Authorization header is missing, the token has expired, or the signature is invalid. The correct client response is to obtain fresh credentials and retry. A 401 response to a browser should also include a WWW-Authenticate header describing how to authenticate.

Return 403 Forbidden when the server knows who the client is but refuses the action. The user is logged in with a valid token yet tries to read another tenant's invoice, call an admin-only endpoint, or exceed a plan limit that authentication cannot fix. Retrying with the same credentials will never help, which is exactly what distinguishes 403 from 401. One more subtlety: some APIs return 404 instead of 403 for resources the caller may not know exist, to avoid leaking their existence. That is a deliberate security trade-off — document it if you do it.

The 5xx codes: the server is at fault

Use 5xx codes when the request was fine but the server failed to fulfill it. Return 500 Internal Server Error for unexpected failures: unhandled exceptions, failed database queries, or bugs. Log the details server-side, but send the client a generic message plus a correlation id — never a stack trace. Return 502 Bad Gateway when an upstream service you depend on returned an invalid response, and 504 Gateway Timeout when the upstream did not answer in time. Return 503 Service Unavailable for temporary conditions the client should retry: deploys, overload, or maintenance windows. Always pair 503 with a Retry-After header so well-behaved clients back off instead of hammering you.

A good rule of thumb: if retrying the identical request later could succeed without changing anything, prefer 503 over 500. It keeps client retry logic, load balancers, and on-call dashboards honest about whether the failure is transient or a real bug.

What status code should a failed validation return?

This is the single most asked question about API status codes, and the honest answer is that both 400 and 422 are defensible — but you should pick one and use it consistently. Return 400 when the request itself is malformed: invalid JSON, a missing required field, or a string where a number belongs. Return 422 when the request is well-formed but semantically wrong: a well-typed date range where the end precedes the start, or an email address that is syntactically fine but already registered.

Whichever you choose, the response body matters more than the code. Return a machine-readable list of problems naming each field and what was wrong with it, so clients can highlight errors without parsing prose. Pair your status-code decisions with the right verbs from the HTTP methods guide, and keep the complete reference handy as data at http-status-codes-complete.json.