HTTP headers are key-value pairs sent between client and server with every HTTP request and response. They carry metadata about the message body, authentication, caching, security policies, and more. This complete HTTP headers list and reference covers every header you need to know as a web developer, with practical examples and best practices.
Look up HTTP status codes with our HTTP Status Code Checker β
Convert curl commands with custom headers using our cURL to Code Converter β
What Are HTTP Headers?
HTTP headers are metadata fields included in HTTP requests and responses. They follow the format Header-Name: value and appear after the request/response line but before the body. Headers control how data is transmitted, cached, authenticated, and rendered.
Headers are grouped into four categories:
- General Headers β Apply to both requests and responses (e.g.,
Connection,Date) - Request Headers β Sent by the client to provide context (e.g.,
Accept,User-Agent,Authorization) - Response Headers β Sent by the server to describe the response (e.g.,
Server,Set-Cookie) - Entity Headers β Describe the body of the message (e.g.,
Content-Type,Content-Length)
GET /api/users HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
User-Agent: Mozilla/5.0
Connection: keep-alive
---
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: max-age=3600
X-Request-ID: abc-123-def
Content-Length: 1234Common Request Headers
Request headers are sent by the client (browser, API client, or curl) to tell the server what kind of response is expected, who is making the request, and how to handle the connection.
| Header | Description | Example |
|---|---|---|
Accept | Tells the server what content types the client can handle | application/json |
Authorization | Carries authentication credentials (Bearer token, Basic auth, API key) | Bearer eyJhbGci... |
Content-Type | Specifies the media type of the request body | application/json |
User-Agent | Identifies the client software making the request | Mozilla/5.0 (Windows NT 10.0; Win64; x64) |
Cookie | Sends stored cookies back to the server | session_id=abc123; theme=dark |
Referer | URL of the page that linked to the current request | https://example.com/page |
Host | The domain name and port of the server (required in HTTP/1.1) | api.example.com |
Origin | Indicates where the request originated from (used in CORS) | https://myapp.com |
If-None-Match | Conditional request based on ETag; returns 304 if unchanged | "33a64df5" |
If-Modified-Since | Conditional request based on date; returns 304 if unchanged | Wed, 21 Oct 2025 07:28:00 GMT |
Common Response Headers
Response headers are sent by the server to provide metadata about the response. They control caching, set cookies, specify content types, and direct the client where to redirect.
| Header | Description | Example |
|---|---|---|
Content-Type | The media type of the response body | text/html; charset=utf-8 |
Set-Cookie | Sets a cookie on the client with optional flags (HttpOnly, Secure, SameSite) | session=abc123; HttpOnly; Secure |
Cache-Control | Directives for caching mechanisms in browsers and CDNs | public, max-age=3600 |
Location | URL to redirect the client to (used with 3xx status codes) | https://example.com/new-page |
Server | Information about the server software (often hidden for security) | nginx/1.24.0 |
ETag | A unique identifier for a specific version of a resource | "33a64df551425fcc55e" |
WWW-Authenticate | Defines the authentication method the client should use (sent with 401) | Bearer realm="api" |
Content-Length | The size of the response body in bytes | 3495 |
Content Negotiation Headers
Content negotiation allows clients and servers to agree on the best representation of a resource. The client sends preference headers, and the server responds with the most appropriate version.
# Client sends preferences
GET /api/data HTTP/1.1
Accept: application/json, text/html;q=0.9, */*;q=0.8
Accept-Language: en-US, en;q=0.9, fr;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Charset: utf-8
# Server responds with best match
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Language: en-US
Content-Encoding: gzip
Vary: Accept, Accept-Language, Accept-EncodingThe q parameter (quality value) ranges from 0 to 1 and indicates preference. Default is 1.0 (highest priority). The Vary response header tells caches which request headers affect the response, preventing incorrect cached versions from being served.
Caching Headers
Caching headers are critical for web performance. They tell browsers and CDNs how long to store resources, when to revalidate, and how to handle stale content. Proper caching can reduce page load times by 50% or more.
# Aggressive caching for static assets (1 year)
Cache-Control: public, max-age=31536000, immutable
# No caching (API responses with sensitive data)
Cache-Control: no-store, no-cache, must-revalidate, private
# Revalidation caching (HTML pages)
Cache-Control: no-cache
ETag: "abc123"
# Time-based caching with revalidation
Cache-Control: public, max-age=3600, must-revalidate
Last-Modified: Tue, 15 Oct 2025 10:30:00 GMT
# Stale content while revalidating (modern approach)
Cache-Control: public, max-age=300, stale-while-revalidate=60
# Legacy HTTP/1.0 caching
Expires: Thu, 01 Dec 2025 16:00:00 GMT
Pragma: no-cache| Directive | Purpose |
|---|---|
max-age=N | Cache for N seconds from the time of the request |
s-maxage=N | Like max-age but only for shared caches (CDNs) |
no-cache | Cache but revalidate with the server before each use |
no-store | Do not cache the response at all |
public | Any cache (browser, CDN, proxy) can store the response |
private | Only the browser can cache the response (not CDNs) |
must-revalidate | Once stale, the cache must revalidate before using the cached version |
immutable | The resource will never change; skip revalidation entirely |
stale-while-revalidate=N | Serve stale content for N seconds while fetching a fresh version in the background |
Security Headers
Security headers protect your application from common web vulnerabilities like XSS, clickjacking, MIME sniffing, and protocol downgrade attacks. Every production website should implement these headers.
# Content Security Policy - prevents XSS
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com
# HTTP Strict Transport Security - force HTTPS
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
# Prevent MIME type sniffing
X-Content-Type-Options: nosniff
# Prevent clickjacking
X-Frame-Options: DENY
# Modern alternative:
Content-Security-Policy: frame-ancestors 'none'
# Control referrer information
Referrer-Policy: strict-origin-when-cross-origin
# Restrict browser features
Permissions-Policy: camera=(), microphone=(), geolocation=(self), payment=()| Header | Protection Against |
|---|---|
Content-Security-Policy | XSS, code injection, unauthorized resource loading |
Strict-Transport-Security | Protocol downgrade attacks, cookie hijacking |
X-Content-Type-Options | MIME sniffing attacks |
X-Frame-Options | Clickjacking via iframes |
Referrer-Policy | Information leakage via Referer header |
Permissions-Policy | Unauthorized access to browser APIs (camera, mic, location) |
Cross-Origin-Opener-Policy | Cross-origin window attacks (Spectre-like) |
Cross-Origin-Embedder-Policy | Cross-origin resource loading without explicit permission |
CORS Headers
Cross-Origin Resource Sharing (CORS) headers control which origins can access your resources. When a browser makes a cross-origin request, it performs a preflight check to verify the server allows the request.
# Preflight request (sent by browser automatically)
OPTIONS /api/data HTTP/1.1
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
# Preflight response (server must respond to allow the request)
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: true
# Actual response with CORS headers
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining
Content-Type: application/json| Header | Purpose |
|---|---|
Access-Control-Allow-Origin | Specifies which origin(s) can access the resource. Use a specific origin or * (not with credentials). |
Access-Control-Allow-Methods | HTTP methods allowed for cross-origin requests |
Access-Control-Allow-Headers | Custom headers allowed in cross-origin requests |
Access-Control-Allow-Credentials | Whether cookies and auth headers can be sent cross-origin |
Access-Control-Max-Age | How long the preflight result can be cached (in seconds) |
Access-Control-Expose-Headers | Response headers that JavaScript can access cross-origin |
Authentication Headers
Authentication headers carry credentials between the client and server. Understanding the different authentication schemes is essential for building secure APIs.
# Basic Authentication (base64-encoded username:password)
GET /api/protected HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
# Decoded: username:password
# Bearer Token (JWT or OAuth2)
GET /api/data HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
# API Key (custom header)
GET /api/data HTTP/1.1
X-API-Key: sk_live_abc123def456
# Server responds with 401 when authentication fails
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="invalid_token", error_description="The token has expired"
# Digest Authentication
Authorization: Digest username="admin", realm="api@example.com", nonce="abc123", uri="/api/data", response="def456"Compression Headers
Compression headers enable the client and server to negotiate compressed transfer of response bodies. Compression typically reduces payload sizes by 60-80%, significantly improving load times.
# Client tells server what compression it supports
GET /api/large-data HTTP/1.1
Accept-Encoding: gzip, deflate, br
# Server responds with compressed content
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Type: application/json
Transfer-Encoding: chunked
Vary: Accept-Encoding| Algorithm | Description | Best For |
|---|---|---|
gzip | Most widely supported compression. Good compression ratio. | Universal compatibility, text-based content |
br (Brotli) | Better compression than gzip (15-20% smaller). Requires HTTPS. | Modern browsers, static assets, HTTPS sites |
deflate | Older algorithm, rarely used alone. Inconsistent implementations. | Legacy systems only |
zstd | Newest algorithm. Excellent speed and compression ratio. | Emerging support, high-throughput APIs |
Custom Headers
Custom headers allow applications to pass additional metadata outside the standard HTTP specification. While the X- prefix convention was common, it has been deprecated by RFC 6648 (2012).
# Common custom headers (still using X- prefix for compatibility)
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
X-Forwarded-For: 203.0.113.50, 70.41.3.18
X-Forwarded-Proto: https
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1672531200
# Modern naming (no X- prefix, per RFC 6648)
Request-ID: 550e8400-e29b-41d4-a716-446655440000
RateLimit-Limit: 1000
RateLimit-Remaining: 999
RateLimit-Reset: 1672531200
# Application-specific headers
Idempotency-Key: unique-operation-key-123
Retry-After: 120
Deprecation: true
Sunset: Sat, 01 Mar 2025 00:00:00 GMTBest Practices for Custom Headers:
- Use meaningful, descriptive names without the
X-prefix for new headers - Keep existing
X-prefixed headers for backward compatibility - Document all custom headers in your API documentation
- Use
Request-IDorX-Request-IDfor distributed tracing - Include rate limit information in response headers
HTTP Headers in Code
Here is how to set and read HTTP headers in the most common languages and tools. These examples cover both client-side and server-side usage.
JavaScript (fetch API)
// Setting request headers with fetch
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token-here',
'Accept': 'application/json',
'X-Request-ID': crypto.randomUUID(),
},
body: JSON.stringify({ name: 'John' }),
});
// Reading response headers
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('X-RateLimit-Remaining'));
// Iterating all response headers
for (const [key, value] of response.headers.entries()) {
console.log(`${key}: ${value}`);
}JavaScript (axios)
import axios from 'axios';
// Setting request headers with axios
const response = await axios.post('https://api.example.com/data',
{ name: 'John' },
{
headers: {
'Authorization': 'Bearer your-token-here',
'Content-Type': 'application/json',
'Accept-Language': 'en-US',
},
}
);
// Reading response headers
console.log(response.headers['content-type']);
console.log(response.headers['x-ratelimit-remaining']);
// Setting default headers for all requests
axios.defaults.headers.common['Authorization'] = 'Bearer token';
axios.defaults.headers.post['Content-Type'] = 'application/json';curl
# Setting custom headers with curl
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token-here" \
-H "Accept: application/json" \
-H "X-Request-ID: $(uuidgen)" \
-d '{"name": "John"}'
# View response headers only
curl -I https://example.com
# View both request and response headers (verbose)
curl -v https://example.com
# Save response headers to a file
curl -D headers.txt https://example.comNode.js (http module)
import http from 'node:http';
// Setting headers in an HTTP server response
const server = http.createServer((req, res) => {
// Reading request headers
console.log(req.headers['authorization']);
console.log(req.headers['content-type']);
// Setting response headers
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-store');
res.setHeader('X-Request-ID', crypto.randomUUID());
res.setHeader('Access-Control-Allow-Origin', 'https://myapp.com');
// Set multiple values for a header
res.setHeader('Set-Cookie', [
'session=abc123; HttpOnly; Secure; SameSite=Strict',
'theme=dark; Path=/; Max-Age=31536000',
]);
res.writeHead(200);
res.end(JSON.stringify({ message: 'Hello' }));
});Complete HTTP Headers Reference Table
This table lists all commonly used HTTP headers with their descriptions, example values, and whether they appear in requests, responses, or both.
| Header | Type | Description | Example Value |
|---|---|---|---|
Cache-Control | Both | Caching directives for request and response | max-age=3600, public |
Connection | Both | Control whether the connection stays open | keep-alive |
Date | Both | Date and time of the message | Tue, 15 Oct 2025 10:30:00 GMT |
Accept | Request | Acceptable content types | application/json, text/html |
Accept-Encoding | Request | Acceptable compression algorithms | gzip, deflate, br |
Accept-Language | Request | Preferred response language | en-US, en;q=0.9 |
Authorization | Request | Authentication credentials | Bearer eyJhbGci... |
Cookie | Request | Cookies sent to the server | session=abc123 |
Host | Request | Server domain name | api.example.com |
If-Modified-Since | Request | Conditional request by date | Wed, 21 Oct 2025 07:28:00 GMT |
If-None-Match | Request | Conditional request by ETag | "33a64df5" |
Origin | Request | Origin of the request (for CORS) | https://myapp.com |
Referer | Request | URL of the referring page | https://example.com/page |
User-Agent | Request | Client software identification | Mozilla/5.0... |
Access-Control-Allow-Origin | Response | Allowed CORS origin(s) | https://myapp.com |
Content-Encoding | Response | Compression algorithm used | gzip |
Content-Length | Both | Size of the body in bytes | 3495 |
Content-Security-Policy | Response | CSP rules to prevent XSS | default-src 'self' |
Content-Type | Both | Media type of the body | application/json; charset=utf-8 |
ETag | Response | Resource version identifier | "33a64df551425fcc55e" |
Expires | Response | Date/time after which response is stale | Thu, 01 Dec 2025 16:00:00 GMT |
Last-Modified | Response | Date the resource was last modified | Tue, 15 Oct 2025 10:30:00 GMT |
Location | Response | Redirect target URL | https://example.com/new |
Permissions-Policy | Response | Restrict browser features | camera=(), microphone=() |
Referrer-Policy | Response | Controls Referer header behavior | strict-origin-when-cross-origin |
Retry-After | Response | Seconds to wait before retrying | 120 |
Server | Response | Server software information | nginx/1.24.0 |
Set-Cookie | Response | Set a cookie on the client | session=abc; HttpOnly; Secure |
Strict-Transport-Security | Response | Force HTTPS connections | max-age=63072000; includeSubDomains |
Vary | Response | Headers that affect cached response selection | Accept, Accept-Encoding |
WWW-Authenticate | Response | Authentication scheme required | Bearer realm="api" |
X-Content-Type-Options | Response | Prevent MIME sniffing | nosniff |
X-Frame-Options | Response | Prevent clickjacking | DENY |
X-Request-ID | Both | Unique request identifier for tracing | 550e8400-e29b-41d4... |
Frequently Asked Questions
What is the difference between request headers and response headers?
Request headers are sent by the client (browser or API client) to the server, providing context about the request β such as accepted content types, authentication tokens, and user agent information. Response headers are sent by the server back to the client, providing metadata about the response β such as content type, caching rules, and security policies. Some headers like Content-Type can appear in both.
What are the most important security headers to implement?
The essential security headers are: Content-Security-Policy (CSP) to prevent XSS attacks, Strict-Transport-Security (HSTS) to enforce HTTPS, X-Content-Type-Options: nosniff to prevent MIME sniffing, X-Frame-Options to prevent clickjacking, and Referrer-Policy to control information leakage. Modern applications should also implement Permissions-Policy to restrict browser features.
Why was the X- prefix for custom headers deprecated?
RFC 6648 (published in 2012) deprecated the X- prefix convention because removing the prefix when a custom header became standardized caused compatibility issues. The recommendation is to choose a meaningful, unique header name without any prefix. However, many existing headers like X-Forwarded-For and X-Request-ID remain widely used for backward compatibility.
How does Cache-Control differ from Expires?
Cache-Control is the modern, more powerful caching header that uses relative time directives (e.g., max-age=3600 means "cache for 1 hour from now"). Expires uses an absolute date/time and is the older HTTP/1.0 approach. When both are present, Cache-Control takes precedence. Use Cache-Control in modern applications β it offers granular control with directives like no-cache, no-store, must-revalidate, public, and private.
What is a CORS preflight request and when does it happen?
A CORS preflight is an automatic OPTIONS request sent by the browser before certain cross-origin requests. It happens when the request uses methods other than GET, HEAD, or POST, or includes custom headers, or sends a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain. The server must respond with appropriate Access-Control-Allow-* headers. The browser caches preflight results based on the Access-Control-Max-Age header.
Understanding HTTP headers is essential for building performant, secure, and well-architected web applications. Bookmark this reference for quick access to header names, values, and usage patterns.
Check HTTP status codes with our HTTP Status Code Tool β
Convert curl commands to any language with our cURL to Code Converter β