HTTP Headers

Headers are key-value pairs sent in both requests and responses. Names are case-insensitive. Values are strings. Multiple values can be comma-separated or sent as multiple header lines.

Header-Name: value
Header-Name: value1, value2

Headers are grouped by purpose, not by whether they appear in requests or responses.

Request Headers

Sent by the client to provide context about the request, the client, and what it will accept.

Identity & Routing

HeaderExampleDescription
HostHost: api.example.comTarget host and port. Mandatory in HTTP/1.1. Enables virtual hosting (multiple sites on one IP).
User-AgentUser-Agent: Mozilla/5.0 ...Client software identity. Browser, version, OS.
RefererReferer: https://example.com/pageURL of the page that initiated the request. Note: intentionally misspelled in the spec.
OriginOrigin: https://app.example.comOrigin of the request. Used in CORS. Does not include path.
FromFrom: bot@example.comEmail of the user/bot. Mainly used by crawlers.

Content Negotiation

HeaderExampleDescription
AcceptAccept: application/json, text/html;q=0.9Preferred response MIME types. q values indicate priority (default 1.0).
Accept-EncodingAccept-Encoding: gzip, brAcceptable compression algorithms for the response body.
Accept-LanguageAccept-Language: en-US, en;q=0.8Preferred natural languages for the response.
Accept-CharsetAccept-Charset: utf-8Acceptable character encodings. Mostly obsolete; UTF-8 is assumed.

Authentication & Authorization

HeaderExampleDescription
AuthorizationAuthorization: Bearer eyJhbGc...Credentials for the request. Common schemes: Basic, Bearer, Digest, AWS4-HMAC-SHA256.
CookieCookie: session=abc123; theme=darkCookies previously set by Set-Cookie. Sent automatically by the browser.
Proxy-AuthorizationProxy-Authorization: Basic dXNlcjpwYXNzCredentials for an authenticating proxy.

Conditional Requests

Used with caching and to prevent lost-update problems.

HeaderExampleDescription
If-None-MatchIf-None-Match: "abc123"Returns 304 Not Modified if the resource ETag hasn’t changed.
If-Modified-SinceIf-Modified-Since: Tue, 01 Jan 2025 00:00:00 GMTReturns 304 if the resource hasn’t changed since the given date.
If-MatchIf-Match: "abc123"Proceeds only if resource ETag matches. Used for safe updates (optimistic concurrency). Returns 412 on mismatch.
If-Unmodified-SinceIf-Unmodified-Since: Tue, 01 Jan 2025 00:00:00 GMTProceeds only if resource hasn’t changed since the date. Returns 412 otherwise.

Connection & Transmission

HeaderExampleDescription
ConnectionConnection: keep-aliveControl options for the current connection. keep-alive or close.
Keep-AliveKeep-Alive: timeout=5, max=100Parameters for persistent connection. Works with Connection: keep-alive.
Content-LengthContent-Length: 348Byte length of the request body. Required when sending a body without chunked encoding.
Content-TypeContent-Type: application/jsonMIME type of the request body. Required when sending a body.
Transfer-EncodingTransfer-Encoding: chunkedHow the body is encoded for transfer. chunked is most common.
ExpectExpect: 100-continueAsks the server to acknowledge readiness to receive body before the client sends it. Useful for large payloads.
UpgradeUpgrade: websocketRequest to switch to a different protocol (e.g., WebSocket).

Range Requests

HeaderExampleDescription
RangeRange: bytes=0-1023Requests a specific byte range of the resource. Server responds with 206 Partial Content.
If-RangeIf-Range: "abc123"Combined with Range; only applies the range request if the resource hasn’t changed.

Forwarding & Proxy Headers

HeaderExampleDescription
X-Forwarded-ForX-Forwarded-For: 203.0.113.5, 198.51.100.1Original client IP, added by each proxy in the chain. Rightmost IP is the most recently added.
X-Forwarded-ProtoX-Forwarded-Proto: httpsOriginal protocol (HTTP or HTTPS) used by the client. Set by load balancers/proxies when terminating TLS.
X-Forwarded-HostX-Forwarded-Host: api.example.comOriginal Host header, preserved by the proxy.
ForwardedForwarded: for=203.0.113.5;proto=httpsStandard RFC 7239 replacement for X-Forwarded-* headers.

Response Headers

Sent by the server to describe the response, control caching, and set client-side state.

Content Description

HeaderExampleDescription
Content-TypeContent-Type: application/json; charset=utf-8MIME type and optional character encoding of the response body.
Content-LengthContent-Length: 1234Byte length of the response body. Absent when Transfer-Encoding: chunked.
Content-EncodingContent-Encoding: gzipCompression applied to the body. Client decompresses before processing.
Content-LanguageContent-Language: en-USNatural language of the response body.
Content-LocationContent-Location: /api/users/42Alternate URI for the returned resource.
Content-RangeContent-Range: bytes 0-1023/5120Range of bytes returned in a 206 response. Format: unit start-end/total.
Transfer-EncodingTransfer-Encoding: chunkedHow the body is transmitted. Mutually exclusive with Content-Length.

Resource Identity

HeaderExampleDescription
ETagETag: "abc123"Opaque identifier for a specific version of a resource. Used in conditional requests (If-None-Match, If-Match).
Last-ModifiedLast-Modified: Mon, 20 Jan 2025 10:00:00 GMTTimestamp of last modification. Used in If-Modified-Since checks.
LocationLocation: /api/users/42URI of a new or moved resource. Used with 201 Created and all 3xx redirects.
VaryVary: Accept-EncodingLists request headers that affect the response. Tells caches to store separate versions per header value.

Connection Control

HeaderExampleDescription
ConnectionConnection: keep-aliveDirects the client on connection handling after the response.
Keep-AliveKeep-Alive: timeout=5, max=100Parameters for how long the server will keep the connection open.
UpgradeUpgrade: websocketServer agrees to switch protocols (response to a client Upgrade request).

Authentication Challenges

HeaderExampleDescription
WWW-AuthenticateWWW-Authenticate: Bearer realm="api"Required on 401 responses. Tells the client what auth scheme to use.
Proxy-AuthenticateProxy-Authenticate: Basic realm="proxy"Required on 407 Proxy Auth Required.

Cookies

HeaderExampleDescription
Set-CookieSet-Cookie: session=abc; Path=/; HttpOnly; Secure; SameSite=LaxSets a cookie in the browser. Can be repeated for multiple cookies.

Cookie attributes:

AttributeDescription
Path=Scope of the cookie by URL path
Domain=Scope by domain (and subdomains if leading dot)
Expires= / Max-Age=Cookie lifetime. Max-Age takes precedence. Session cookie if omitted.
HttpOnlyPrevents JavaScript access (document.cookie). Mitigates XSS cookie theft.
SecureCookie only sent over HTTPS.
SameSite=StrictCookie not sent on cross-site requests.
SameSite=LaxCookie not sent on cross-site sub-resource requests, but sent on top-level navigation. Default in modern browsers.
SameSite=NoneCookie sent on all cross-site requests. Requires Secure.
⚠️

SameSite=None requires the Secure attribute. Browsers silently reject SameSite=None cookies that are not also marked Secure.

Rate Limiting (Common Conventions)

Not standardized in HTTP/1.1; widely adopted by APIs.

HeaderExampleDescription
X-RateLimit-LimitX-RateLimit-Limit: 1000Max requests allowed in the window.
X-RateLimit-RemainingX-RateLimit-Remaining: 42Requests remaining in the current window.
X-RateLimit-ResetX-RateLimit-Reset: 1706745600Unix timestamp when the window resets.
Retry-AfterRetry-After: 30Seconds to wait before retrying. Used with 429 and 503. Can be a date instead of seconds.

Caching Headers

Caching headers control how responses are stored and reused by browsers, CDNs, and proxies.

HeaderDirectionDescription
Cache-ControlBothPrimary cache directive. See directives below.
ExpiresResponseAbsolute expiry date. Overridden by Cache-Control: max-age. Legacy.
ETagResponseVersion identifier. Client sends back in If-None-Match.
Last-ModifiedResponseModification timestamp. Client sends back in If-Modified-Since.
PragmaBothLegacy no-cache directive for HTTP/1.0 proxies. Effectively replaced by Cache-Control.

Cache-Control Directives

ℹ️

Cache-Control: no-cache does not mean “don’t cache.” It means “store it, but revalidate with the server before every use.” Use no-store to actually prevent caching.

Common Cache Patterns

Use CaseCache-Control Value
Content-hashed static assets (JS, CSS)public, max-age=31536000, immutable
HTML pagesno-cache (revalidate every time)
Private user dataprivate, no-store
API responses (short TTL)private, max-age=60
CDN-cached API responsespublic, s-maxage=300, max-age=0

Security Headers

Set by the server to instruct the browser on security policies.

HeaderExampleDescription
Strict-Transport-Security (HSTS)max-age=31536000; includeSubDomains; preloadForces browser to use HTTPS for the domain for max-age seconds. preload submits to browser preload lists.
Content-Security-Policy (CSP)default-src 'self'; script-src 'self' cdn.example.comControls which sources the browser may load resources from. Primary defense against XSS.
X-Content-Type-OptionsnosniffPrevents browser from MIME-sniffing. Forces use of declared Content-Type.
X-Frame-OptionsDENY or SAMEORIGINControls iframe embedding. Replaced by CSP frame-ancestors but still widely used.
Referrer-Policystrict-origin-when-cross-originControls how much of the Referer URL is sent on navigation.
Permissions-Policycamera=(), microphone=()Controls which browser APIs the page may use. Replaces Feature-Policy.
Cross-Origin-Opener-Policy (COOP)same-originIsolates browsing context from cross-origin windows. Required to enable SharedArrayBuffer.
Cross-Origin-Embedder-Policy (COEP)require-corpRequires all sub-resources to opt in to cross-origin loading. Also required for SharedArrayBuffer.
Cross-Origin-Resource-Policy (CORP)same-siteRestricts who can load the resource.

CORS Headers

Cross-Origin Resource Sharing — allows controlled cross-origin requests from browsers.

Response headers (set by server):

HeaderExampleDescription
Access-Control-Allow-Origin* or https://app.example.comWhich origins may access the resource. * disallows credentials.
Access-Control-Allow-MethodsGET, POST, PUTAllowed HTTP methods for cross-origin requests.
Access-Control-Allow-HeadersContent-Type, AuthorizationAllowed request headers.
Access-Control-Allow-CredentialstrueWhether cookies/auth headers are included. Cannot be used with * origin.
Access-Control-Max-Age86400Seconds the preflight response may be cached.
Access-Control-Expose-HeadersX-Request-IdResponse headers the browser JS may read beyond the safe defaults.
⚠️

Access-Control-Allow-Origin: * and Access-Control-Allow-Credentials: true are mutually exclusive. Browsers will block the response if both are set. Use an explicit origin (e.g., https://app.example.com) when credentials are required.

Preflight flow (for non-simple requests):

sequenceDiagram
    participant B as Browser
    participant S as Server

    B->>S: OPTIONS /api/data (preflight)
    Note right of B: Origin: https://app.example.com
    S->>B: 204 No Content
    Note left of S: Access-Control-Allow-Origin: https://app.example.com
    Note left of S: Access-Control-Allow-Methods: POST
    B->>S: POST /api/data (actual request)
    S->>B: 200 OK

Custom / Vendor Headers

ℹ️

The X- prefix convention was deprecated by RFC 6648 in 2012. New custom headers should not use X-. Existing ones (X-Forwarded-For, X-Request-Id, etc.) remain in widespread use and are not going away.

HeaderDescription
X-Request-IdUnique identifier for the request. Used for distributed tracing and log correlation.
X-Correlation-IdSimilar to X-Request-Id. Common in microservice architectures.
X-Real-IPOriginal client IP as set by Nginx. Simpler alternative to X-Forwarded-For.
X-Api-VersionAPI version indicator. Some APIs use this instead of URL versioning.