HTTP Status Reference
Searchable reference for every HTTP status code with descriptions and when to use them
Searchable reference for every HTTP status code with descriptions and when to use them
The initial part of the request has been received and the client should continue.
When: Sent in response to an Expect: 100-continue header before a large request body.
The server is switching protocols as requested by the client.
When: Used to upgrade an HTTP connection to WebSocket via the Upgrade header.
Used to return some response headers before the final response.
When: Lets the browser preload critical assets while the server still works on the main response.
Standard success response with a body.
When: Default for any successful GET, PUT, POST, or DELETE that returns content.
A new resource has been created.
When: Return after a successful POST that creates a row. Include a Location header pointing at it.
The request has been accepted but processing is not complete.
When: For async work — return 202 with a status URL the client can poll.
Success, with intentionally no response body.
When: Ideal for DELETE handlers and PUT updates where there's nothing to send back.
The server is returning a byte range of the resource.
When: Used when serving Range requests for video scrubbing or resumable downloads.
The resource has permanently moved to a new URL.
When: SEO-safe redirect for renames. Browsers and proxies will cache it forever.
The resource is temporarily at a different URL.
When: Historically the catch-all redirect — prefer 303 or 307 for clearer semantics.
The response can be found at another URL using GET.
When: POST-redirect-GET pattern: redirect to a GET URL after handling a form submission.
The cached version is still fresh.
When: Returned when If-None-Match or If-Modified-Since matches. Send no body.
Temporary redirect that preserves the request method.
When: Use instead of 302 when you need to redirect a POST without it becoming a GET.
Permanent redirect that preserves the request method.
When: Use instead of 301 when redirecting non-GET requests (e.g. webhook URL changes).
The request is malformed and the server can't parse it.
When: Schema validation failures, malformed JSON, missing required fields.
Authentication is required and has failed or not been provided.
When: Missing or invalid token. Don't use this for forbidden — that's 403.
Reserved for future use; in practice some APIs use it for paywalls.
When: Stripe and a few SaaS APIs return it for over-quota or billing-blocked accounts.
The server understood the request but refuses to authorize it.
When: Authenticated user lacks permission. Returning 404 here can be a hardening choice.
The requested resource doesn't exist.
When: Unknown URL or missing record. Also used to hide existence of forbidden resources.
The HTTP method isn't supported on this resource.
When: Set the Allow header listing the methods the route does accept.
Server can't produce a response matching the Accept headers.
When: Content negotiation failed — client asked for application/xml but you only speak JSON.
The client took too long to send the request.
When: Used by some servers to close idle keep-alive connections.
The request conflicts with the current state of the resource.
When: Concurrent edits, duplicate unique fields, version mismatches.
The resource is permanently unavailable with no forwarding address.
When: Stronger than 404 — tells search engines to drop the URL from their index.
Server requires a Content-Length header.
When: Chunked transfer disabled or required for legacy reasons.
A request precondition (like If-Match) failed.
When: Optimistic concurrency: client sent ETag, but it no longer matches.
The request body exceeds the server's limit.
When: File upload over the size cap. Include the limit in the response.
The request URL exceeds the server's limit.
When: Usually means a GET should have been a POST.
The server doesn't support the request body's media type.
When: Client sent text/xml but the endpoint only accepts application/json.
The server refuses to brew coffee because it is a teapot.
When: An April Fool's joke from RFC 2324 that lives on as an easter egg.
The request was well-formed but semantically wrong.
When: JSON parsed fine but business rules failed. Common in REST APIs over 400.
Server unwilling to risk processing a request that might be replayed.
When: TLS 1.3 0-RTT replay protection.
The client should switch to a different protocol.
When: Force HTTP clients to upgrade to TLS or HTTP/2.
The origin server requires the request to be conditional.
When: Forces clients to use If-Match — prevents lost-update bugs in concurrent edits.
The client is sending requests too fast.
When: Rate limiting. Include a Retry-After header.
Headers are too large for the server to process.
When: Usually a runaway cookie or auth token.
Resource is blocked by legal demand.
When: Geoblocking, takedown notices, court orders. Named after Fahrenheit 451.
Generic catch-all for unexpected server failures.
When: Uncaught exceptions, null pointer crashes — anything you didn't anticipate.
The server doesn't support the functionality required.
When: Stub endpoints that aren't built yet. Better than 500 because it's intentional.
The upstream server returned an invalid response.
When: Your reverse proxy got garbage from your origin server.
The server is temporarily unable to handle the request.
When: Maintenance windows, overloaded backends. Include Retry-After.
The upstream server didn't respond in time.
When: Reverse proxy gave up waiting on a slow origin.
Server doesn't support the HTTP version used in the request.
When: Client asked for HTTP/2 against an HTTP/1.0-only server.
Server can't store the representation needed to complete the request.
When: Disk full. Most often from WebDAV PUTs.
Client must authenticate to gain network access.
When: Captive portals on hotel and airport WiFi.
HTTP status codes are a three-digit response that every HTTP message carries, telling the client at a glance what happened. The first digit categorizes the response: 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error. Picking the right code is one of the cheapest API-design decisions you can make and one of the most useful — good codes mean clients can handle errors generically without parsing your error messages.
For most REST APIs, the working set is small: 200, 201, 204, 400, 401, 403, 404, 409, 422, 429, and 500. The rest are situational — reach for them when their precise meaning fits, but don't reach for 418.
401 Unauthorizedmeans "I don't know who you are." Send it when the request has no credentials or invalid credentials. 403 Forbiddenmeans "I know who you are and you're not allowed." Send it when an authenticated user tries to access something they're not authorized for. Some teams deliberately return 404 instead of 403 to avoid leaking the existence of forbidden resources.