A Comprehensive Guide to HTTP Status Codes
Stop guessing what 401 vs 403 means: a developer-focused tour of every status family with realistic examples, anti-patterns, and the codes that actually matter for SEO.

More utilities that pair well with this guide:
Why this matters
A backend engineer returns 200 OK with {"error": "Unauthorized"} in the body. The frontend's generic error handler treats it as success because the status was 200. The login form gets stuck in a loop. Tiny status-code mistakes like this cost real engineering hours — and worse, they distort SEO crawls and broken-link reporting. Knowing which code to send when is part of the job.
Three real scenarios
A request lacking a token? 401. A token without permission? 403. The resource simply doesn't exist? 404.
Predictable client behavior
301 keeps PageRank; 302 signals temporary, no rank transfer. Pick deliberately.
Permanent redirect, ranking transferred
503 with a Retry-After header tells crawlers to come back later instead of de-indexing.
Search engines know to retry
The five families at a glance
| Range | Family | Common members |
|---|---|---|
| 1xx | Informational | 100 Continue, 101 Switching Protocols |
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirection | 301, 302, 304 Not Modified, 308 |
| 4xx | Client Error | 400, 401, 403, 404, 422, 429 |
| 5xx | Server Error | 500, 502, 503, 504 |
Walkthrough — using the status reference
Open the HTTP status reference.
Search by code or description
Type "401" or "unauthorized" or "rate limit". The matching codes float to the top.
Read the canonical meaning
Each entry explains what the spec says, not just what curl prints.
See real-world usage
Notes call out where popular APIs (GitHub, Stripe, AWS) deviate slightly.
Spot SEO impact
Each code is tagged with the search-engine treatment (indexable / not, transfers rank / not).
Copy a one-liner
Drop the description into your API documentation or inline code comment.
Scenario
POST /admin/users
(No Authorization header)Recommended response
401 Unauthorized
WWW-Authenticate: Bearer realm="admin"Scenario
POST /admin/users
Authorization: Bearer eyJ... (valid token, viewer scope)Recommended response
403 Forbidden
{"error": "scope_admin_required"}
Power tips
- Use 422 for "well-formed but semantically invalid" input (e.g., a JSON body with the wrong field types). 400 is for malformed requests.
- 204 No Content for deletes is more polite than 200 with an empty body — it tells the client there is intentionally no payload.
- Always include
Retry-Afterwith 429 / 503. Tells smart clients exactly when to come back. - Avoid 200 with
error: ...in the body. It defeats the entire purpose of HTTP status codes and confuses every monitoring tool.
Common pitfalls
Common mistake
A vague 404 hides existence — sometimes that's what you want (e.g., private repos), but for normal authenticated APIs prefer 403 so clients know auth is the issue.
Common mistake
Caching a 302 forever
302 is temporary by spec, but some intermediaries cache aggressively. If the redirect is permanent, send 301 (or 308 to keep the method).
Common mistake
Returning 500 for client mistakes
500 means server error. If the client sent bad data, return a 4xx — otherwise your alerting fires for a bug in their code.
When this is the wrong tool
- Designing a brand new protocol — HTTP status codes are tied to HTTP semantics; gRPC, WebSockets, and proprietary protocols have their own status conventions.
- In-app error reporting — application-level error codes belong inside the response body alongside the HTTP code.
- Monitoring — your APM should categorize status codes automatically; this reference is for the design decisions before you ship.
FAQ
What's the difference between 301 and 308?
Both are permanent redirects. 308 guarantees the HTTP method is preserved; 301 historically allowed clients to switch POST → GET on follow.
Yes, RFC 2324 (April 1, 1998), and reaffirmed in RFC 7168. It is a joke response not used in production APIs.
Should I expose framework-specific codes (e.g. 419, 440)?
Avoid non-standard codes if you can. Stick to the IANA-registered set so generic clients understand them.
Next steps
- Inspect responses with the URL parser when debugging odd behavior.
- Look up Git or Linux commands you might run while triaging at the Git command and Linux command references.
- Verify the underlying server's IP/ASN with the IP lookup tool when 502/504 errors point at upstream issues.