How to use
Type a code, a name, or a use-case keyword into the search box (`404`, `not found`, `redirect`, `unauthorized`, `idempotent`) and the table filters live. Click a class chip (1xx / 2xx / 3xx / 4xx / 5xx) to narrow further. Each row carries the canonical name, a one-line description, a "when to use" hint, and a link to the IETF section that defines it — `RFC 9110` for the core 2022 revision that replaced the long-lived RFC 7231 / 7232 / 7233 / 7234 / 7235 series.
Reach for this when designing an API, reading server logs, or debugging a request that surfaces an unfamiliar code. The 4xx / 5xx classes get most of the attention, but the 3xx redirect codes and the 2xx success codes have real semantic weight — `301` vs `308`, `200` vs `204` vs `201`, `409` vs `422` all communicate different things to caches and clients. Picking the right code makes integration with libraries (axios, RestSharp, Spring) and infrastructure (CloudFront, nginx, AWS API Gateway) behave predictably without custom hooks.
Examples
Looking up `422`
Output
422 Unprocessable Content (RFC 9110 §15.5.21)
Use: request is syntactically valid but the server cannot process it for semantic reasons — failed validation, business rule violation. Often confused with 400.
`400 Bad Request` means the request itself is malformed (broken JSON, missing required header). `422` means the request was understood but its meaning is wrong (email already in use, age must be ≥ 18). Most modern APIs (Stripe, GitHub, Twilio) prefer `422` for validation errors so backend logs separate "client sent garbage" from "client tried something we cannot do".
`301` vs `308` redirect
Input
search: redirect permanent
Output
301 Moved Permanently — historic permanent redirect; browsers may rewrite the method to GET on POST / PUT.
308 Permanent Redirect (RFC 7538) — same semantics but preserves the original method and body.
Use `308` for new API endpoints when you want clients to keep using POST / PUT after the redirect. Use `301` for SEO and old-URL → new-URL moves where rewriting to GET is fine (and historically expected). The same split applies to temporary: `302` (legacy, may rewrite to GET) vs `307` (preserves method).
`401` vs `403`
Input
search: unauthorized forbidden
Output
401 Unauthorized — request lacks valid authentication. Server must return a WWW-Authenticate header. Despite the name, this is really "Unauthenticated".
403 Forbidden — request is authenticated but the principal is not allowed to perform this action. No WWW-Authenticate; retrying with different credentials won't help unless permissions change.
The naming is unfortunate — `401` is about authentication (who are you?) and `403` is about authorization (what can you do?). A common pattern: return `401` when the auth token is missing or expired (client should re-login), `403` when the token is valid but lacks scope (client should request elevated permissions). Some APIs use `404` instead of `403` to avoid leaking the existence of resources to unauthorized callers.
FAQ
Is the list authoritative?
Codes are sourced from the IANA HTTP Status Code Registry, which is the official authority. The current core definitions live in RFC 9110 (HTTP Semantics, June 2022), with extensions in RFC 9111 (Caching) and topic-specific RFCs like 7538 (308 redirect), 6585 (precondition required, too many requests), and 8297 (early hints). Each row links to the section that defines it so you can verify against the spec.
Why are some codes here that I have never seen in the wild?
The registry is permissive — anyone can request a code allocation through the IETF process. Some codes are common (`200`, `404`, `500`); others are niche (`418 I'm a teapot` from an April Fools RFC, `451 Unavailable For Legal Reasons` named after Fahrenheit 451). Some address narrow protocols (WebDAV adds 207 / 422 / 423 / 424 / 507 in RFC 4918). The reference shows all of them so you can recognize them when they appear in a CDN log or a third-party API.
My API returns `200` with an `errors: [...]` body. Is that legal?
Legal but misleading. HTTP status codes communicate to *infrastructure* — load balancers, retry libraries, cache layers, monitoring dashboards. Sending `200` for what is logically a failure tells the CDN to cache the error response, the retry library to consider the call successful, and the on-call dashboard to plot it as a green dot. Reserve `2xx` for actual success; use `4xx` for client errors and `5xx` for server errors so the surrounding ecosystem treats them correctly. GraphQL is the main exception — its spec returns `200` with errors in the body because the protocol layer is HTTP-agnostic.
Are 1xx codes ever useful in practice?
Two of them are. `100 Continue` is used by HTTP/1.1 clients with `Expect: 100-continue` to ask the server if a large request body is welcome before sending it; most servers handle this transparently. `103 Early Hints` (RFC 8297, 2017) lets the server send preload hints for CSS / JS before the actual `200` response is ready — Cloudflare and Fastly support it. The rest (`101 Switching Protocols` for WebSocket upgrade, `102 Processing` for WebDAV) are protocol-specific. Day-to-day API development rarely sees 1xx.
What is the difference between `502`, `503`, and `504`?
All three are upstream / gateway failures, but from different angles. **`502 Bad Gateway`** — the proxy got a *broken* response from the upstream (connection reset, malformed HTTP). **`503 Service Unavailable`** — the server itself is unable to handle the request (overload, maintenance, graceful shutdown); should include `Retry-After` header. **`504 Gateway Timeout`** — the proxy waited for the upstream and timed out. In an nginx → app stack: `502` is "app crashed", `503` is "app said `I am full`", `504` is "app took too long to answer". The right code helps on-call know whether to restart, scale, or investigate latency.
Can I make up my own status codes?
Technically no — the IANA registry is the source of truth and proxies, browsers, and middleware may treat unregistered codes as their class default (any 4xx behaves like 400, any 5xx like 500). In practice frameworks tolerate it as long as the first digit is meaningful, and some private APIs use unregistered codes like `419 Authentication Timeout` (Laravel) or `420 Method Failure` (deprecated Twitter API). For new public APIs stick to registered codes and put detail in the response body — clients ignore unknown codes uniformly enough that the extra information value is small.
Related concepts
HTTP status codes are 3-digit integers that the server returns alongside the response. The first digit identifies the **class**: `1xx` informational (rare, protocol-specific), `2xx` success, `3xx` redirection, `4xx` client error, `5xx` server error. RFC 9110 (June 2022) consolidated the previous status-code definitions from RFC 7231 / 7232 / 7233 / 7234 / 7235 into a single document and is the current normative reference. The IANA HTTP Status Code Registry holds the authoritative list of allocated values.
The semantic difference between adjacent codes matters more than people expect. `200` and `204` both say "success" but `204` carries no body — clients should not parse one. `201` confirms creation and the response carries the new resource's representation or a `Location` header. `301` and `308` are both "permanent redirect" but `308` preserves the HTTP method; `301` historically rewrites POST to GET. `409 Conflict` and `422 Unprocessable Content` both mean "I refused your write" but `409` is for state conflicts (concurrent edits, duplicate key) and `422` is for validation failures (bad email format). Picking the right code is signaling, not pedantry — caches, retry libraries, and observability tools all react to the code without reading the body.
Three adjacent concepts shape day-to-day API design. **Idempotency** classifies methods (`GET`, `PUT`, `DELETE` are idempotent; `POST` is not) and decides safe retry behavior; status code design works alongside this so a client knows whether to retry on `503`. **Caching** (RFC 9111) determines which responses get stored — `200`, `203`, `204`, `300`, `301`, `404`, `405`, `410`, `414`, `501` are cacheable by default; others need explicit headers. **Content negotiation** uses headers like `Accept`, `Accept-Language`, and returns `406 Not Acceptable` when none of the offered representations match. Status codes sit in the middle of all three, which is why getting them right pays off across the stack.