SEC Security Headers

RES TYPE

Strict-Transport-Security (HSTS)

Tells the browser to only load the site using secure HTTPS connections, so you never accidentally use regular HTTP.
Strict-Transport-Security: max-age=31536000; includeSubDomains
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
header("Strict-Transport-Security: max-age=31536000; includeSubDomains");
res.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
RES TYPE

Content-Security-Policy (CSP)

Prevents XSS attacks by restricting exactly where scripts, fonts, and images can load from.
Content-Security-Policy: default-src 'self'; img-src https://*;
add_header Content-Security-Policy "default-src 'self'; img-src https://*;";
Header set Content-Security-Policy "default-src 'self'; img-src https://*;"
header("Content-Security-Policy: default-src 'self'; img-src https://*;");
res.set('Content-Security-Policy', 'default-src \'self\'; img-src https://*;');
response.headers['Content-Security-Policy'] = 'default-src \'self\'; img-src https://*;'
RES TYPE

X-Frame-Options

Stops your site from being embedded in an iframe on another website, which prevents clickjacking.
X-Frame-Options: DENY or SAMEORIGIN
add_header X-Frame-Options "DENY or SAMEORIGIN";
Header set X-Frame-Options "DENY or SAMEORIGIN"
header("X-Frame-Options: DENY or SAMEORIGIN");
res.set('X-Frame-Options', 'DENY or SAMEORIGIN');
response.headers['X-Frame-Options'] = 'DENY or SAMEORIGIN'
RES TYPE

X-Content-Type-Options

Stops the browser from trying to guess the MIME type, forcing it to stick to what our server declares.
X-Content-Type-Options: nosniff
add_header X-Content-Type-Options "nosniff";
Header set X-Content-Type-Options "nosniff"
header("X-Content-Type-Options: nosniff");
res.set('X-Content-Type-Options', 'nosniff');
response.headers['X-Content-Type-Options'] = 'nosniff'
RES TYPE

Permissions-Policy

Controls which browser features (like the camera, microphone, or geolocation) the page is actually allowed to use.
Permissions-Policy: camera=(), geolocation=(self)
add_header Permissions-Policy "camera=(), geolocation=(self)";
Header set Permissions-Policy "camera=(), geolocation=(self)"
header("Permissions-Policy: camera=(), geolocation=(self)");
res.set('Permissions-Policy', 'camera=(), geolocation=(self)');
response.headers['Permissions-Policy'] = 'camera=(), geolocation=(self)'
RES TYPE

Clear-Site-Data

A fast way to force the browser to clear all cookies, storage, and cache for your site.
Clear-Site-Data: "cache", "cookies", "storage"
add_header Clear-Site-Data "\"cache\", \"cookies\", \"storage\"";
Header set Clear-Site-Data "\"cache\", \"cookies\", \"storage\""
header("Clear-Site-Data: \"cache\", \"cookies\", \"storage\"");
res.set('Clear-Site-Data', '"cache", "cookies", "storage"');
response.headers['Clear-Site-Data'] = '"cache", "cookies", "storage"'
RES TYPE

Cross-Origin-Opener-Policy (COOP)

Ensures your top-level document does not share a browsing window with cross-origin documents, protecting against side-channel attacks.
Cross-Origin-Opener-Policy: same-origin
add_header Cross-Origin-Opener-Policy "same-origin";
Header set Cross-Origin-Opener-Policy "same-origin"
header("Cross-Origin-Opener-Policy: same-origin");
res.set('Cross-Origin-Opener-Policy', 'same-origin');
response.headers['Cross-Origin-Opener-Policy'] = 'same-origin'
RES TYPE

X-XSS-Protection DEPRECATED

A legacy header that stops older browsers from loading the page if they detect reflected cross-site scripting.
X-XSS-Protection: 1; mode=block
add_header X-XSS-Protection "1; mode=block";
Header set X-XSS-Protection "1; mode=block"
header("X-XSS-Protection: 1; mode=block");
res.set('X-XSS-Protection', '1; mode=block');
response.headers['X-XSS-Protection'] = '1; mode=block'
RES TYPE

Cross-Origin-Embedder-Policy (COEP)

Prevents a document from loading any cross-origin resources that do not explicitly grant permission.
Cross-Origin-Embedder-Policy: require-corp
add_header Cross-Origin-Embedder-Policy "require-corp";
Header set Cross-Origin-Embedder-Policy "require-corp"
header("Cross-Origin-Embedder-Policy: require-corp");
res.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers['Cross-Origin-Embedder-Policy'] = 'require-corp'
RES TYPE

Cross-Origin-Resource-Policy (CORP)

Tells the browser whether a resource (like an image or script) can be shared with other websites.
Cross-Origin-Resource-Policy: same-origin
add_header Cross-Origin-Resource-Policy "same-origin";
Header set Cross-Origin-Resource-Policy "same-origin"
header("Cross-Origin-Resource-Policy: same-origin");
res.set('Cross-Origin-Resource-Policy', 'same-origin');
response.headers['Cross-Origin-Resource-Policy'] = 'same-origin'

COR CORS (Cross-Origin)

RES TYPE

Access-Control-Allow-Origin

Tells the browser which external websites are allowed to read the response. Crucial for APIs.
Access-Control-Allow-Origin: https://example.com or *
add_header Access-Control-Allow-Origin "https://example.com or *";
Header set Access-Control-Allow-Origin "https://example.com or *"
header("Access-Control-Allow-Origin: https://example.com or *");
res.set('Access-Control-Allow-Origin', 'https://example.com or *');
response.headers['Access-Control-Allow-Origin'] = 'https://example.com or *'
RES TYPE

Access-Control-Allow-Methods

Specifies which HTTP methods (GET, POST, etc.) are allowed when accessing the resource.
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
RES TYPE

Access-Control-Allow-Headers

Lists the custom headers the browser is allowed to send in the actual request.
Access-Control-Allow-Headers: Content-Type, Authorization
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
header("Access-Control-Allow-Headers: Content-Type, Authorization");
res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
RES TYPE

Access-Control-Allow-Credentials

Tells the browser if it should include cookies or auth headers in cross-origin requests.
Access-Control-Allow-Credentials: true
add_header Access-Control-Allow-Credentials "true";
Header set Access-Control-Allow-Credentials "true"
header("Access-Control-Allow-Credentials: true");
res.set('Access-Control-Allow-Credentials', 'true');
response.headers['Access-Control-Allow-Credentials'] = 'true'
RES TYPE

Access-Control-Expose-Headers

Tells the browser which custom response headers your frontend JavaScript is actually allowed to see.
Access-Control-Expose-Headers: X-My-Custom-Header
add_header Access-Control-Expose-Headers "X-My-Custom-Header";
Header set Access-Control-Expose-Headers "X-My-Custom-Header"
header("Access-Control-Expose-Headers: X-My-Custom-Header");
res.set('Access-Control-Expose-Headers', 'X-My-Custom-Header');
response.headers['Access-Control-Expose-Headers'] = 'X-My-Custom-Header'
RES TYPE

Access-Control-Max-Age

How many seconds the browser should cache a preflight request so it doesn't have to keep asking.
Access-Control-Max-Age: 86400
add_header Access-Control-Max-Age "86400";
Header set Access-Control-Max-Age "86400"
header("Access-Control-Max-Age: 86400");
res.set('Access-Control-Max-Age', '86400');
response.headers['Access-Control-Max-Age'] = '86400'
REQ TYPE

Origin

Indicates where a fetch request originates from. The browser sends this automatically for CORS requests.
Origin: https://mywebsite.com
curl -H "Origin: https://mywebsite.com" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Origin': 'https://mywebsite.com' }
});
axios.get('https://api.example.com', {
  headers: { 'Origin': 'https://mywebsite.com' }
});

CAC Caching & Performance

BOTH TYPE

Cache-Control

The absolute main header for caching. Tells the browser and CDN exactly how long to store the file.
Cache-Control: public, max-age=86400
add_header Cache-Control "public, max-age=86400";
Header set Cache-Control "public, max-age=86400"
header("Cache-Control: public, max-age=86400");
res.set('Cache-Control', 'public, max-age=86400');
response.headers['Cache-Control'] = 'public, max-age=86400'
curl -H "Cache-Control: public, max-age=86400" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Cache-Control': 'public, max-age=86400' }
});
axios.get('https://api.example.com', {
  headers: { 'Cache-Control': 'public, max-age=86400' }
});
RES TYPE

ETag

A unique ID for a specific version of a file. If the file changes, the ETag changes with it.
ETag: "33a64df551425fcc55e4"
add_header ETag "\"33a64df551425fcc55e4\"";
Header set ETag "\"33a64df551425fcc55e4\""
header("ETag: \"33a64df551425fcc55e4\"");
res.set('ETag', '"33a64df551425fcc55e4"');
response.headers['ETag'] = '"33a64df551425fcc55e4"'
REQ TYPE

If-None-Match

The browser sends the ETag back. If it matches, the server returns a 304 Not Modified, saving bandwidth.
If-None-Match: "33a64df551425fcc55e4"
curl -H "If-None-Match: \"33a64df551425fcc55e4\"" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'If-None-Match': '"33a64df551425fcc55e4"' }
});
axios.get('https://api.example.com', {
  headers: { 'If-None-Match': '"33a64df551425fcc55e4"' }
});
RES TYPE

Vary

Tells caches that the response might look different depending on specific request headers (like mobile vs desktop).
Vary: Accept-Encoding, User-Agent
add_header Vary "Accept-Encoding, User-Agent";
Header set Vary "Accept-Encoding, User-Agent"
header("Vary: Accept-Encoding, User-Agent");
res.set('Vary', 'Accept-Encoding, User-Agent');
response.headers['Vary'] = 'Accept-Encoding, User-Agent'
RES TYPE

Expires

The exact date and time when the file becomes stale. We mostly use Cache-Control instead nowadays, but this is still valid.
Expires: Wed, 21 Oct 2026 07:28:00 GMT
add_header Expires "Wed, 21 Oct 2026 07:28:00 GMT";
Header set Expires "Wed, 21 Oct 2026 07:28:00 GMT"
header("Expires: Wed, 21 Oct 2026 07:28:00 GMT");
res.set('Expires', 'Wed, 21 Oct 2026 07:28:00 GMT');
response.headers['Expires'] = 'Wed, 21 Oct 2026 07:28:00 GMT'
RES TYPE

Last-Modified

The server's record of the last time this specific file was changed.
Last-Modified: Tue, 15 Nov 2026 12:45:26 GMT
add_header Last-Modified "Tue, 15 Nov 2026 12:45:26 GMT";
Header set Last-Modified "Tue, 15 Nov 2026 12:45:26 GMT"
header("Last-Modified: Tue, 15 Nov 2026 12:45:26 GMT");
res.set('Last-Modified', 'Tue, 15 Nov 2026 12:45:26 GMT');
response.headers['Last-Modified'] = 'Tue, 15 Nov 2026 12:45:26 GMT'
REQ TYPE

If-Modified-Since

The browser asks the server to only send the file if it has actually been updated since this date.
If-Modified-Since: Tue, 15 Nov 2026 12:45:26 GMT
curl -H "If-Modified-Since: Tue, 15 Nov 2026 12:45:26 GMT" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'If-Modified-Since': 'Tue, 15 Nov 2026 12:45:26 GMT' }
});
axios.get('https://api.example.com', {
  headers: { 'If-Modified-Since': 'Tue, 15 Nov 2026 12:45:26 GMT' }
});
RES TYPE

Server-Timing

Passes backend server metrics (like database fetch times) straight to the browser's developer tools.
Server-Timing: db;dur=53, app;dur=47.2
add_header Server-Timing "db;dur=53, app;dur=47.2";
Header set Server-Timing "db;dur=53, app;dur=47.2"
header("Server-Timing: db;dur=53, app;dur=47.2");
res.set('Server-Timing', 'db;dur=53, app;dur=47.2');
response.headers['Server-Timing'] = 'db;dur=53, app;dur=47.2'

CON Content & Format

BOTH TYPE

Content-Type

Tells the receiver what file type is being sent (like JSON, HTML, or an image format).
Content-Type: application/json; charset=utf-8
add_header Content-Type "application/json; charset=utf-8";
Header set Content-Type "application/json; charset=utf-8"
header("Content-Type: application/json; charset=utf-8");
res.set('Content-Type', 'application/json; charset=utf-8');
response.headers['Content-Type'] = 'application/json; charset=utf-8'
curl -H "Content-Type: application/json; charset=utf-8" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Content-Type': 'application/json; charset=utf-8' }
});
axios.get('https://api.example.com', {
  headers: { 'Content-Type': 'application/json; charset=utf-8' }
});
REQ TYPE

Accept

Tells the server what file formats the browser can actually understand and process.
Accept: text/html, application/xhtml+xml
curl -H "Accept: text/html, application/xhtml+xml" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Accept': 'text/html, application/xhtml+xml' }
});
axios.get('https://api.example.com', {
  headers: { 'Accept': 'text/html, application/xhtml+xml' }
});
REQ TYPE

Accept-Language

Tells the server which human languages the user prefers, so you can serve the right translation.
Accept-Language: en-US, en;q=0.9
curl -H "Accept-Language: en-US, en;q=0.9" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Accept-Language': 'en-US, en;q=0.9' }
});
axios.get('https://api.example.com', {
  headers: { 'Accept-Language': 'en-US, en;q=0.9' }
});
REQ TYPE

Accept-Encoding

Tells the server which compression methods the browser supports.
Accept-Encoding: gzip, deflate, br
curl -H "Accept-Encoding: gzip, deflate, br" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Accept-Encoding': 'gzip, deflate, br' }
});
axios.get('https://api.example.com', {
  headers: { 'Accept-Encoding': 'gzip, deflate, br' }
});
RES TYPE

Content-Encoding

Tells the browser which compression method was actually used on the file.
Content-Encoding: gzip
add_header Content-Encoding "gzip";
Header set Content-Encoding "gzip"
header("Content-Encoding: gzip");
res.set('Content-Encoding', 'gzip');
response.headers['Content-Encoding'] = 'gzip'
BOTH TYPE

Content-Length

The exact size of the data being sent, measured in bytes.
Content-Length: 3495
add_header Content-Length "3495";
Header set Content-Length "3495"
header("Content-Length: 3495");
res.set('Content-Length', '3495');
response.headers['Content-Length'] = '3495'
curl -H "Content-Length: 3495" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Content-Length': '3495' }
});
axios.get('https://api.example.com', {
  headers: { 'Content-Length': '3495' }
});
RES TYPE

Content-Disposition

Tells the browser whether to display the file inline or force a download as an attachment.
Content-Disposition: attachment; filename="invoice.pdf"
add_header Content-Disposition "attachment; filename=\"invoice.pdf\"";
Header set Content-Disposition "attachment; filename=\"invoice.pdf\""
header("Content-Disposition: attachment; filename=\"invoice.pdf\"");
res.set('Content-Disposition', 'attachment; filename="invoice.pdf"');
response.headers['Content-Disposition'] = 'attachment; filename="invoice.pdf"'
RES TYPE

Transfer-Encoding

Specifies the form of encoding used to safely transfer the payload. Often used for streaming data.
Transfer-Encoding: chunked
add_header Transfer-Encoding "chunked";
Header set Transfer-Encoding "chunked"
header("Transfer-Encoding: chunked");
res.set('Transfer-Encoding', 'chunked');
response.headers['Transfer-Encoding'] = 'chunked'
REQ TYPE

Range

Asks the server for just a specific portion of a file, which is great for resuming paused video or downloads.
Range: bytes=200-1000
curl -H "Range: bytes=200-1000" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Range': 'bytes=200-1000' }
});
axios.get('https://api.example.com', {
  headers: { 'Range': 'bytes=200-1000' }
});
RES TYPE

Accept-Ranges

Lets the browser know that the server supports partial requests for things like video scrubbing.
Accept-Ranges: bytes
add_header Accept-Ranges "bytes";
Header set Accept-Ranges "bytes"
header("Accept-Ranges: bytes");
res.set('Accept-Ranges', 'bytes');
response.headers['Accept-Ranges'] = 'bytes'

AUT Auth & Context

REQ TYPE

Authorization

Contains the credentials (like a JWT) needed to prove who is making the request.
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1Ni..." https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Authorization': 'Bearer eyJhbGciOiJIUzI1Ni...' }
});
axios.get('https://api.example.com', {
  headers: { 'Authorization': 'Bearer eyJhbGciOiJIUzI1Ni...' }
});
REQ TYPE

User-Agent

A string identifying the browser, operating system, and device making the request.
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64)...
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64)..." https://api.example.com
fetch('https://api.example.com', {
  headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64)...' }
});
axios.get('https://api.example.com', {
  headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64)...' }
});
REQ TYPE

Referer

The URL of the previous page that linked to the current one. Note the historical misspelling of "referrer".
Referer: https://google.com/search?q=...
curl -H "Referer: https://google.com/search?q=..." https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Referer': 'https://google.com/search?q=...' }
});
axios.get('https://api.example.com', {
  headers: { 'Referer': 'https://google.com/search?q=...' }
});
REQ TYPE

Host

The domain name of the server. This is the only header legally required in all HTTP/1.1 requests.
Host: api.codeshack.io
curl -H "Host: api.codeshack.io" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Host': 'api.codeshack.io' }
});
axios.get('https://api.example.com', {
  headers: { 'Host': 'api.codeshack.io' }
});
REQ TYPE

X-Requested-With

Used to identify AJAX requests. Many JavaScript frameworks send this automatically to prevent CSRF.
X-Requested-With: XMLHttpRequest
curl -H "X-Requested-With: XMLHttpRequest" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
RES TYPE

WWW-Authenticate

Sent alongside a 401 Unauthorized error to tell the client what kind of authentication it needs to provide.
WWW-Authenticate: Bearer realm="api"
add_header WWW-Authenticate "Bearer realm=\"api\"";
Header set WWW-Authenticate "Bearer realm=\"api\""
header("WWW-Authenticate: Bearer realm=\"api\"");
res.set('WWW-Authenticate', 'Bearer realm="api"');
response.headers['WWW-Authenticate'] = 'Bearer realm="api"'
REQ TYPE

X-Forwarded-For

Identifies the original IP address of a user connecting through an HTTP proxy or load balancer.
X-Forwarded-For: 203.0.113.195
curl -H "X-Forwarded-For: 203.0.113.195" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Forwarded-For': '203.0.113.195' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Forwarded-For': '203.0.113.195' }
});
REQ TYPE

X-Real-IP

A common non-standard header used by Nginx and proxies to forward the real client IP to the backend.
X-Real-IP: 198.51.100.14
curl -H "X-Real-IP: 198.51.100.14" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Real-IP': '198.51.100.14' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Real-IP': '198.51.100.14' }
});
REQ TYPE

X-Forwarded-Proto

Identifies the original protocol (HTTP or HTTPS) a client used to connect to your load balancer.
X-Forwarded-Proto: https
curl -H "X-Forwarded-Proto: https" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Forwarded-Proto': 'https' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Forwarded-Proto': 'https' }
});
REQ TYPE

X-Forwarded-Host

Identifies the original host requested by the client in the Host HTTP request header.
X-Forwarded-Host: api.codeshack.io
curl -H "X-Forwarded-Host: api.codeshack.io" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Forwarded-Host': 'api.codeshack.io' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Forwarded-Host': 'api.codeshack.io' }
});

NET Network & Connections

BOTH TYPE

Connection

Controls whether the network connection stays open after the current transaction finishes.
Connection: keep-alive
add_header Connection "keep-alive";
Header set Connection "keep-alive"
header("Connection: keep-alive");
res.set('Connection', 'keep-alive');
response.headers['Connection'] = 'keep-alive'
curl -H "Connection: keep-alive" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Connection': 'keep-alive' }
});
axios.get('https://api.example.com', {
  headers: { 'Connection': 'keep-alive' }
});
BOTH TYPE

Upgrade

Used to ask the server to switch to a different protocol, like going from HTTP to WebSockets.
Upgrade: websocket
add_header Upgrade "websocket";
Header set Upgrade "websocket"
header("Upgrade: websocket");
res.set('Upgrade', 'websocket');
response.headers['Upgrade'] = 'websocket'
curl -H "Upgrade: websocket" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Upgrade': 'websocket' }
});
axios.get('https://api.example.com', {
  headers: { 'Upgrade': 'websocket' }
});
BOTH TYPE

Via

Shows all the proxies and gateways the request or response passed through.
Via: 1.1 vegur, 1.1 varnish
add_header Via "1.1 vegur, 1.1 varnish";
Header set Via "1.1 vegur, 1.1 varnish"
header("Via: 1.1 vegur, 1.1 varnish");
res.set('Via', '1.1 vegur, 1.1 varnish');
response.headers['Via'] = '1.1 vegur, 1.1 varnish'
curl -H "Via: 1.1 vegur, 1.1 varnish" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Via': '1.1 vegur, 1.1 varnish' }
});
axios.get('https://api.example.com', {
  headers: { 'Via': '1.1 vegur, 1.1 varnish' }
});
RES TYPE

Server

Tells the client what software the web server is running, though security teams often hide this.
Server: nginx/1.24.0
add_header Server "nginx/1.24.0";
Header set Server "nginx/1.24.0"
header("Server: nginx/1.24.0");
res.set('Server', 'nginx/1.24.0');
response.headers['Server'] = 'nginx/1.24.0'

API API & Rate Limiting

BOTH TYPE

X-Request-ID

A unique UUID used to trace a single request as it passes through multiple microservices and logs.
X-Request-ID: 123e4567-e89b-12d3-a456-426614174000
add_header X-Request-ID "123e4567-e89b-12d3-a456-426614174000";
Header set X-Request-ID "123e4567-e89b-12d3-a456-426614174000"
header("X-Request-ID: 123e4567-e89b-12d3-a456-426614174000");
res.set('X-Request-ID', '123e4567-e89b-12d3-a456-426614174000');
response.headers['X-Request-ID'] = '123e4567-e89b-12d3-a456-426614174000'
curl -H "X-Request-ID: 123e4567-e89b-12d3-a456-426614174000" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'X-Request-ID': '123e4567-e89b-12d3-a456-426614174000' }
});
axios.get('https://api.example.com', {
  headers: { 'X-Request-ID': '123e4567-e89b-12d3-a456-426614174000' }
});
RES TYPE

Retry-After

Tells the client exactly how long to wait (in seconds or a date) before making another request. Usually paired with a 429 status code.
Retry-After: 120
add_header Retry-After "120";
Header set Retry-After "120"
header("Retry-After: 120");
res.set('Retry-After', '120');
response.headers['Retry-After'] = '120'
RES TYPE

RateLimit-Limit

Tells the client how many requests they are allowed to make in the current time window.
RateLimit-Limit: 1000
add_header RateLimit-Limit "1000";
Header set RateLimit-Limit "1000"
header("RateLimit-Limit: 1000");
res.set('RateLimit-Limit', '1000');
response.headers['RateLimit-Limit'] = '1000'
RES TYPE

RateLimit-Remaining

Tells the client exactly how many requests they have left in the current time window.
RateLimit-Remaining: 995
add_header RateLimit-Remaining "995";
Header set RateLimit-Remaining "995"
header("RateLimit-Remaining: 995");
res.set('RateLimit-Remaining', '995');
response.headers['RateLimit-Remaining'] = '995'
RES TYPE

RateLimit-Reset

The exact time (usually in UTC epoch seconds) when the rate limit window will reset.
RateLimit-Reset: 1712061234
add_header RateLimit-Reset "1712061234";
Header set RateLimit-Reset "1712061234"
header("RateLimit-Reset: 1712061234");
res.set('RateLimit-Reset', '1712061234');
response.headers['RateLimit-Reset'] = '1712061234'

CLI Client Hints & Fetch

REQ TYPE

Sec-CH-UA

The modern replacement for User-Agent. Safely provides the browser brand and version without giving away fingerprinting data.
Sec-CH-UA: "Google Chrome";v="125", "Chromium";v="125"
curl -H "Sec-CH-UA: \"Google Chrome\";v=\"125\", \"Chromium\";v=\"125\"" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-CH-UA': '"Google Chrome";v="125", "Chromium";v="125"' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-CH-UA': '"Google Chrome";v="125", "Chromium";v="125"' }
});
REQ TYPE

Sec-CH-UA-Mobile

A simple boolean indicating if the user is on a mobile device.
Sec-CH-UA-Mobile: ?1
curl -H "Sec-CH-UA-Mobile: ?1" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-CH-UA-Mobile': '?1' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-CH-UA-Mobile': '?1' }
});
REQ TYPE

Sec-CH-UA-Platform

Provides the operating system the user is on, like Windows, macOS, or Android.
Sec-CH-UA-Platform: "macOS"
curl -H "Sec-CH-UA-Platform: \"macOS\"" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-CH-UA-Platform': '"macOS"' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-CH-UA-Platform': '"macOS"' }
});
REQ TYPE

Sec-Fetch-Dest

Tells the server exactly what the browser plans to do with the requested data (like rendering it as an image, an iframe, or a script).
Sec-Fetch-Dest: image
curl -H "Sec-Fetch-Dest: image" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-Fetch-Dest': 'image' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-Fetch-Dest': 'image' }
});
REQ TYPE

Sec-Fetch-Mode

Indicates the mode of the request, letting the server know if this is a cross-origin CORS request or a standard navigation.
Sec-Fetch-Mode: cors
curl -H "Sec-Fetch-Mode: cors" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-Fetch-Mode': 'cors' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-Fetch-Mode': 'cors' }
});
REQ TYPE

Sec-Fetch-Site

Tells the server the relationship between the requester and the server (e.g., cross-site, same-origin, or same-site).
Sec-Fetch-Site: same-origin
curl -H "Sec-Fetch-Site: same-origin" https://api.example.com
fetch('https://api.example.com', {
  headers: { 'Sec-Fetch-Site': 'same-origin' }
});
axios.get('https://api.example.com', {
  headers: { 'Sec-Fetch-Site': 'same-origin' }
});

Complete Guide to HTTP Headers

Every time you click a link or fetch data, your browser and the server pass secret notes back and forth. We call these HTTP headers. They don't show up on the screen, but they quietly control almost everything about your website.

Headers manage caching, tell the browser how to format data, verify your login tokens, and set up strict security boundaries. You just need to know which ones to send.

How to View HTTP Headers in Your Browser

Before you start coding, it really helps to see what headers your browser is already sending. You don't need any special software to do this.

  1. Right-click anywhere on a webpage and select Inspect.
  2. Click on the Network tab at the top of the panel.
  3. Refresh the page. You will see a list of files loading.
  4. Click on the very first file in the list (usually the website name).
  5. Look at the Headers panel on the right. You will see the exact Request and Response headers for that page.

Request vs. Response Headers

Headers generally flow in two directions. So, depending on what you are trying to do, you need to understand who is sending the note:

  • Request Headers (REQ): Sent by the client (your browser, or an API tool like Postman) to the server. They provide context, like "I am a Chrome browser" or "Here is my login token."
  • Response Headers (RES): Sent by the server back to the client. They contain instructions, like "Save this file in cache for 24 hours" or "Do not load scripts from other domains."
  • Entity/Representation Headers (BOTH): These can be sent by either side to describe the actual data payload, such as defining the Content-Length or Content-Type.

Do HTTP Headers Affect SEO?

Absolutely. While status codes tell Google if a page exists, your headers tell Google how fast and secure the page is.

  • Speed: A proper Cache-Control header improves your Core Web Vitals, which is a direct ranking factor.
  • Security: Using Strict-Transport-Security (HSTS) ensures search engines know your site relies on HTTPS, keeping your security score high.
  • Mobile Indexing: The Vary header helps Googlebot understand if you serve different content to mobile vs. desktop users.

How to Set HTTP Headers in Code

Setting response headers is one of the most common tasks in backend web development. Here is how you can inject custom headers before sending data back to the user:

PHP (Native)
// Must be called before any HTML output
header("Content-Type: application/json");
header("Cache-Control: public, max-age=3600");
echo json_encode(['status' => 'success']);
Node.js (Express)
app.get('/api', (req, res) => {
  res.set({
    'Content-Type': 'application/json',
    'Cache-Control': 'public, max-age=3600'
  });
  res.send({ status: 'success' });
});
Python (Flask)
@app.route('/api')
def api():
    response = make_response(jsonify(status='success'))
    response.headers['Content-Type'] = 'application/json'
    response.headers['Cache-Control'] = 'public, max-age=3600'
    return response

Common Questions & Troubleshooting

1. What is the CORS Access-Control-Allow-Origin header?
It is a security mechanism. Browsers block front-end code from requesting data from a different domain by default. If you want a website at example.com to fetch data from your API at api.com, your API must reply with an Access-Control-Allow-Origin: https://example.com header to authorize it.

2. How do I force the browser to clear cache using headers?
If you updated a file but users are still seeing the old version, set your Cache-Control header to no-store, no-cache, must-revalidate. This tells the browser to skip the local cache and request a fresh copy right away.

3. Can I create my own custom HTTP headers?
Yes! You can send any custom data you want. Years ago, developers used an X- prefix for custom headers (like X-My-App-Version). But that standard is officially retired. Today, you should just name it whatever makes sense, like My-App-Version: 2.0.

4. Is there a size limit for HTTP headers?
There is no official size limit in the HTTP specification. But in the real world, most web servers (like Nginx and Apache) will block requests if the total header size goes over 8KB. If you try to stuff too much data into a Cookie header, you will get a 431 Request Header Fields Too Large error.

5. What is the difference between Authorization and Proxy-Authorization?
The Authorization header proves your identity to the main web server you are trying to reach. The Proxy-Authorization header is specifically used to prove your identity to an intermediate proxy server (like a corporate firewall) that sits between you and the web.

6. Why do I need a Content-Security-Policy (CSP) header?
A CSP header is your best defense against Cross-Site Scripting (XSS). Even if a hacker manages to inject bad JavaScript into your website's database, a strict CSP header will tell the browser, "Only execute scripts that originate from my own domain." The malicious script will be blocked automatically.