HTTP Status Codes & Headers
Complete searchable reference for HTTP status codes (1xxβ5xx) and common request/response headers β with descriptions, use cases and examples.
Tracing a Stale-Cache Complaint to Its Root Header
A customer reports that a price change isn't showing up in the app, even minutes after the backend was updated. First, capture the response headers on the failing request in the browser's network panel: Cache-Control: max-age=3600 is present with no ETag at all β meaning the CDN and browser are both fully entitled to keep serving the old cached response for up to an hour with zero revalidation, which alone explains the staleness. Second, look up the fix: switching the endpoint to Cache-Control: no-cache forces every client to revalidate against the server before using a cached copy, via a conditional If-None-Match request checked against a server-issued ETag β the server can still respond 304 Not Modified and skip re-sending the body when nothing changed, so this isn't the same as disabling caching outright. Third, redeploy the header change and confirm it worked: the response now carries a fresh ETag, and a second identical request returns 304 instead of a full 200 payload. That capture-diagnose-verify loop is the standard way this kind of bug gets root-caused, and it depends entirely on knowing which header is doing the misbehaving.
Two Vocabularies for One Conversation
A status code and a header answer two different questions about the same HTTP exchange. The status code is a three-digit number in the response's first line, grouped into five classes β 1xx informational, 2xx success, 3xx redirection, 4xx client error, 5xx server error β that tells the client, before it even reads the body, whether the request succeeded and roughly why not if it didn't. Headers are key-value metadata attached to either the request or the response, carrying everything a status code can't: authentication credentials, cache directives, content negotiation, security policy, and tracing identifiers. This reference covers the status codes defined in RFC 7231 and subsequent RFCs, plus de facto standards like 429 Too Many Requests and 451 Unavailable for Legal Reasons, alongside the request headers a client sends and the response headers a server sends back β each entry with a plain-English description, common values, and notes on production usage.
Headers as the First Line of Defence
A meaningful share of the headers in this reference exist purely for security, not functionality, and getting them wrong is one of the more common ways a service ships an avoidable vulnerability. Content-Security-Policy restricts which scripts, styles, and resources a browser is allowed to load, which is the single most effective mitigation against XSS payloads that do make it into a page. Strict-Transport-Security tells browsers to never downgrade to plain HTTP for a domain again, closing the window an attacker on a shared network would otherwise have to strip TLS. X-Frame-Options and its modern replacement, the frame-ancestors CSP directive, prevent your page from being embedded in a hidden iframe on an attacker's site for clickjacking. None of these headers change what a page looks like when everything is working correctly β they only matter the day something goes wrong, which is exactly why they're so easy to skip during normal development and only get added after a security review flags their absence.
Where This Reference Gets Reached For
- API error-path design: Picking the correct status code for an edge case β partial success, a rate-limited request, a validation failure versus a malformed request β before the endpoint ships, rather than defaulting everything to 400 or 500.
- Security header audits: Running a live site's response headers against the reference to identify which of the standard protective headers are missing entirely.
- CDN and cache tuning: Diagnosing stale or duplicated content by cross-checking
Cache-Control,Vary, andETagbehaviour against what the CDN layer is configured to respect. - CORS troubleshooting: Confirming the exact set of
Access-Control-Allow-*headers a cross-origin request needs, rather than guessing and re-deploying repeatedly.
Header Habits Worth Enforcing in Review
- Set an explicit
Cache-Controlon every response, including error responses: An endpoint with no caching header at all leaves the behaviour up to whatever the client, proxy, or CDN defaults to, which differs across stacks and is rarely what you intended. - Never rely on
403vs.404without deciding on purpose: Returning 403 confirms a resource exists to anyone probing it; if that's a leak you care about, return 404 for unauthorized access to sensitive paths instead, and document the choice so future engineers don't "fix" it back. - Pin your security headers in one shared middleware, not per-route: Headers like
Strict-Transport-SecurityandX-Content-Type-Optionsshould be impossible to accidentally omit on a new route β apply them centrally rather than trusting every handler to set them. - Version your
Varyheader alongside your cache keys: If a response varies byAccept-Encodingor a custom header butVarydoesn't list it, CDNs will serve one client's response to another β a subtle bug that only appears under real multi-client traffic.
Frequently Asked Questions
What are the most important HTTP headers for API security?
The five security headers every HTTP response should include are: Strict-Transport-Security (forces all future requests to use HTTPS), Content-Security-Policy (restricts which scripts and resources the browser can load, preventing XSS), X-Content-Type-Options: nosniff (prevents browsers from MIME-sniffing responses), X-Frame-Options: DENY (blocks clickjacking by preventing your page from being embedded in an iframe), and Referrer-Policy: strict-origin-when-cross-origin (limits referer header leakage). For pure JSON APIs, also set Content-Type: application/json on every response and reject requests with mismatched Content-Type headers at the middleware level.
How does Cache-Control work, and when should I use no-cache vs no-store?
Cache-Control: no-cache means the cached response must be revalidated with the server before being served β the response is cached but always checked for freshness first. Cache-Control: no-store means the response must never be written to any cache at all β use this for responses containing sensitive data like banking information or personal health records. Use max-age=N to allow caching for N seconds without revalidation β appropriate for static assets with content hashes in the filename. When both Cache-Control and the older Expires header are present, Cache-Control takes precedence in all modern clients and CDNs.
What is the difference between 401 and 403, and when should I return 404 instead?
Return 401 Unauthorized when the request carries no authentication credentials or the credentials are invalid β include a WWW-Authenticate header so the client knows how to authenticate. Return 403 Forbidden when the caller is authenticated but lacks permission for the specific resource. Return 404 Not Found instead of 403 as a deliberate security choice when you want to prevent an unauthenticated caller from discovering that a resource exists at all β this is common for admin endpoints, private user data and sensitive configuration paths. The trade-off is slightly more confusing debugging for legitimate developers, so document this behaviour in your API spec.