Continue
InformationalServer received headers, client should send the body. Used with Expect: 100-continue.
Typical use: Automatic. Application code rarely sets this.
Switching Protocols
InformationalServer is changing protocols (e.g. HTTP→WebSocket).
Typical use: WebSocket upgrade handshake.
Processing
InformationalRequest received, processing ongoing. Prevents client timeout.
Typical use: WebDAV long operations.
Early Hints
InformationalSend preload headers before the final response.
Typical use: Performance: Cloudflare / HTTP/2+ servers.
OK
SuccessStandard success. Response body contains requested data.
Typical use: Default for successful GET, PUT, POST returning data.
Created
SuccessA new resource was created. Location header gives the URL.
Typical use: POST that creates a row, sign-up, file upload.
Accepted
SuccessRequest received but not yet acted upon. Async processing.
Typical use: Background jobs, async endpoints returning a job ID.
No Content
SuccessSuccess, no response body. MUST NOT include a body.
Typical use: DELETE success, PUT/PATCH without returning data.
Partial Content
SuccessServer delivered only the requested Range.
Typical use: Video streaming, resumable downloads.
Moved Permanently
RedirectionResource permanently moved to a new URL.
Typical use: www→non-www, http→https, slug changes.
Found
RedirectionTemporary redirect. Historically changes POST to GET.
Typical use: Prefer 307 for protocol-preserving redirects.
See Other
RedirectionRedirect using GET. Post-Redirect-Get pattern.
Typical use: After form submission, redirect to result page.
Not Modified
RedirectionCached version still valid. Sent with ETag/Last-Modified.
Typical use: HTTP caching, automatic.
Temporary Redirect
RedirectionLike 302 but preserves HTTP method.
Typical use: Modern alternative to 302.
Permanent Redirect
RedirectionLike 301 but preserves HTTP method.
Typical use: Permanent redirects for non-GET methods.
Bad Request
Client errorMalformed request: bad JSON, missing field, invalid value.
Typical use: Always include a JSON body explaining what was wrong.
Unauthorized
Client errorMisnamed — means "unauthenticated". Missing or invalid credentials.
Typical use: Missing/invalid auth token. Pair with WWW-Authenticate.
Payment Required
Client errorReserved for future use. Stripe uses it for billing rejections.
Typical use: Mostly unused outside payment APIs.
Forbidden
Client errorAuthenticated, but not authorized for this resource.
Typical use: User logged in but accessing someone else's data.
Not Found
Client errorResource does not exist.
Typical use: Resource ID missing from your database.
Method Not Allowed
Client errorHTTP method not supported. Response MUST include Allow header.
Typical use: POST to a GET-only endpoint.
Not Acceptable
Client errorServer can't produce a response matching the client's Accept header.
Typical use: Client wants XML; server only does JSON.
Request Timeout
Client errorServer timed out waiting for the request.
Typical use: Slow clients, keep-alive idle.
Conflict
Client errorRequest conflicts with current resource state.
Typical use: Duplicate creation, optimistic concurrency mismatch.
Gone
Client errorResource existed but is permanently removed.
Typical use: Deleted posts, deleted accounts (stronger than 404 for SEO).
Length Required
Client errorMissing Content-Length header.
Typical use: Strict servers.
Precondition Failed
Client errorIf-Match / If-Unmodified-Since precondition failed.
Typical use: Conditional PUT/DELETE.
Payload Too Large
Client errorBody exceeds server limit.
Typical use: Upload size limits.
URI Too Long
Client errorURL too long (typical limit ~2048 chars).
Typical use: Move long params to request body.
Unsupported Media Type
Client errorServer doesn't support the request body's Content-Type.
Typical use: XML body sent to a JSON-only endpoint.
Range Not Satisfiable
Client errorRange header asks for a non-existent range.
Typical use: Range-based file downloads.
I'm a teapot
Client errorRFC 2324 April Fools — the server refuses to brew coffee.
Typical use: Never seriously. Easter eggs only.
Unprocessable Entity
Client errorRequest well-formed but semantically wrong. Validation failure.
Typical use: GitHub / Stripe-style validation errors.
Too Early
Client errorServer unwilling to process possibly-replayed request.
Typical use: TLS 1.3 0-RTT data.
Upgrade Required
Client errorClient must upgrade to a different protocol.
Typical use: Server refuses HTTP/1, requires HTTP/2.
Precondition Required
Client errorServer requires the request to be conditional.
Typical use: APIs preventing lost-update on PUT.
Too Many Requests
Client errorRate limit exceeded.
Typical use: Rate limiting. Always include Retry-After.
Request Header Fields Too Large
Client errorHeaders exceed server limit. Often oversized cookies.
Typical use: Servers with strict header limits.
Unavailable For Legal Reasons
Client errorResource blocked by legal demand (Fahrenheit 451 reference).
Typical use: Court orders, DMCA, GDPR right-to-be-forgotten.
Internal Server Error
Server errorGeneric server error. Unhandled exception.
Typical use: Should be rare in well-instrumented services.
Not Implemented
Server errorFunctionality not yet implemented.
Typical use: Stubbed endpoints.
Bad Gateway
Server errorProxy got bad response from upstream.
Typical use: Upstream service down or unhealthy.
Service Unavailable
Server errorServer temporarily down. Include Retry-After.
Typical use: Maintenance, circuit breakers, intentional shedding.
Gateway Timeout
Server errorProxy timed out waiting for upstream response.
Typical use: Slow upstream, ALB/nginx timeouts.
HTTP Version Not Supported
Server errorServer doesn't support the HTTP version.
Typical use: Probably an HTTP/0.9 client. Rare.
Insufficient Storage
Server errorServer out of disk space.
Typical use: WebDAV.
Network Authentication Required
Server errorClient must authenticate to the network.
Typical use: WiFi captive portals.
The five status code classes
HTTP status codes are three digits. The first digit decides the category, the remaining two specify the exact condition. Every well-behaved HTTP API uses them consistently — the right status code is the first thing any client (browser, fetch library, monitoring tool, load balancer) checks to decide what to do with the response.
- 1xx Informational — interim responses. Rarely seen by application code; mostly protocol-layer.
- 2xx Success — request was processed successfully. 200 (general OK), 201 (resource created), 204 (success-no-body).
- 3xx Redirection — client must take additional action. 301 permanent, 302/307 temporary, 304 cached.
- 4xx Client error — request was malformed or refused. Client shouldn't retry without modifying the request.
- 5xx Server error — something went wrong server-side. Client may retry with exponential backoff.
The dozen you'll actually use
Out of 60+ defined codes, a typical REST API uses about a dozen: 200, 201, 204, 301, 304, 400, 401, 403, 404, 409, 422, 429, 500, 502, 503. Everything else is either niche (WebDAV, Range requests, captive portals) or rare enough that learning it on demand is fine.
A common pattern question: 400 vs 422. The standard says 400 is for "malformed" (JSON didn't parse, missing header) and 422 for "well-formed but semantically wrong" (the email field exists, but the value isn't a valid email). Many APIs use them interchangeably; GitHub and Stripe reserve 422 for validation errors and 400 for parse errors. Pick a convention and document it.
Common confusions worth memorizing
- 401 vs 403. 401 = "I don't know who you are — log in"; 403 = "I know who you are, and you can't access this". Returning 401 for permission errors on authenticated requests is the most common API design mistake.
- 301 vs 302 vs 307 vs 308. 301 permanent; 302 temporary but historically changed POST to GET; 307 temporary preserving method; 308 permanent preserving method. For a modern API, prefer 307/308 whenever the HTTP method matters semantically.
- 404 vs 410. 404 = "I can't find it"; 410 = "it existed but is gone forever". Search engines drop 410 URLs from the index faster.
- 500 vs 502 vs 503 vs 504. 500 = exception in your app; 502 = upstream returned bad response; 503 = your service is intentionally down or overloaded; 504 = upstream timed out. Distinguishing them speeds up incident debugging enormously.
- 429 without Retry-After is unhelpful — clients have no way to know how long to wait. Always include Retry-After when rate-limiting.
Best practices for API design
- Always include a structured error body with 4xx and 5xx responses.
{"error": "invalid_email", "message": "Email format not recognized", "field": "email"}is much more useful than a bare status code. - Never use 200 for errors. Some APIs return
200 OKwith{"error": "..."}in the body — this breaks every monitoring tool and forces clients to parse JSON to check success. - Be specific. If you can return 409 instead of 400 to indicate a conflict, do. If you can return 410 instead of 404 to indicate a deleted resource, do. Specific codes carry more information.
- Include
Retry-Afteron 429 and 503 so clients can implement sensible backoff without guessing. - Don't invent custom codes. The 4xx and 5xx ranges have plenty of unused values, but inventing one (e.g. 460) confuses clients, breaks proxies, and is filtered out by some HTTP libraries.
Common use cases
- Look up an unfamiliar status code
- Decide between 400 and 422 for validation errors
- Reference for API design reviews
- Debug load balancer 5xx errors
Frequently asked questions
401 vs 403 — what's the difference?
401 means "I don't know who you are — please authenticate". 403 means "I know who you are, and you're not allowed to do this". Returning 401 for permission errors on authenticated requests is the most common API mistake.
When should I use 422 vs 400?
GitHub and Stripe convention: 400 for malformed (the JSON didn't parse, a required header was missing); 422 for well-formed but semantically wrong (the email field is present but the value isn't a valid email). Many APIs use them interchangeably; pick a convention and stick to it.
Why is 410 better than 404 for deleted resources?
410 Gone tells search engines and crawlers that the resource is permanently removed (not just missing). They drop the URL from their index more aggressively. 404 leaves them re-checking forever.
How should I distinguish 502 vs 503 vs 504?
502 Bad Gateway = upstream returned an invalid response (often connection refused). 503 Service Unavailable = your service is intentionally rejecting traffic (maintenance, overload, circuit breakers). 504 Gateway Timeout = upstream didn't respond in time. Distinguishing them properly speeds up incident debugging.