cURL Headers: Set, Send & View HTTP Headers
HTTP headers carry metadata about requests and responses. With cURL, you can set custom request headers, view response headers, and debug header-related issues. This guide covers everything you need to know about working with headers in cURL.
Viewing Response Headers
# Show response headers only
curl -I https://example.com
Show response headers + body
curl -i https://example.com
Verbose mode (shows both request and response headers)
curl -v https://example.com
Extract a specific header
curl -sI https://example.com | grep -i "content-type"
Show only status line
curl -sI https://example.com | head -1
Understanding Verbose Output
curl -v https://example.com 2>&1
> = Request headers (what you sent)
< = Response headers (what the server returned)
* = Connection info (cURL internal)
> GET / HTTP/2
> Host: example.com
> User-Agent: curl/8.4.0
> Accept: /
>
< HTTP/2 200
< content-type: text/html; charset=UTF-8
< content-length: 1256
Setting Request Headers
The -H Flag
# Set a single header
curl -H "Accept: application/json" https://api.example.com/data
Set multiple headers
curl -H "Accept: application/json" \
-H "Authorization: Bearer TOKEN" \
-H "X-Request-ID: abc-123" \
-H "Cache-Control: no-cache" \
https://api.example.com/data
Override default headers
curl -H "User-Agent: MyApp/2.0" https://example.com
curl -H "Accept: text/plain" https://example.com
Remove a Default Header
cURL sends some headers by default (Host, User-Agent, Accept). To remove one, set it to empty:
# Remove User-Agent header
curl -H "User-Agent:" https://example.com
Remove Accept header
curl -H "Accept:" https://example.com
Common HTTP Headers
Request Headers
| Header | Purpose | Example |
|---|---|---|
Accept | Preferred response format | application/json |
Authorization | Authentication credentials | Bearer token123 |
Content-Type | Request body format | application/json |
User-Agent | Client identification | Mozilla/5.0... |
Accept-Language | Preferred language | en-US,en;q=0.9 |
Accept-Encoding | Supported compression | gzip, deflate, br |
Cookie | Session cookies | session=abc123 |
Referer | Referring page URL | https://google.com |
Origin | Request origin (CORS) | https://example.com |
Cache-Control | Caching directives | no-cache |
If-Modified-Since | Conditional request | Mon, 01 Jan 2024... |
X-Forwarded-For | Client IP (through proxy) | 203.0.113.50 |
Response Headers
| Header | Purpose | Example |
|---|---|---|
Content-Type | Response body format | text/html; charset=UTF-8 |
Content-Length | Response body size | 1256 |
Set-Cookie | Set browser cookie | session=xyz; Path=/ |
Location | Redirect URL | https://example.com/new |
Cache-Control | Caching rules | max-age=3600 |
X-RateLimit-Remaining | API rate limit | 99 |
Retry-After | When to retry | 60 |
Server | Server software | nginx/1.24.0 |
Access-Control-Allow-Origin | CORS policy | * |
Practical Examples
Mimic a Browser
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8" \
-H "Accept-Language: en-US,en;q=0.5" \
-H "Accept-Encoding: gzip, deflate, br" \
-H "Connection: keep-alive" \
-H "Upgrade-Insecure-Requests: 1" \
--compressed \
https://example.com
API Authentication
# Bearer token
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
https://api.example.com/me
API key
curl -H "X-API-Key: sk-abc123def456" https://api.example.com/data
Basic auth (manual header)
curl -H "Authorization: Basic $(echo -n 'user:pass' | base64)" https://api.example.com/data
JSON API Requests
# GET JSON
curl -H "Accept: application/json" https://api.example.com/users
POST JSON
curl -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "John"}' \
https://api.example.com/users
CORS Preflight Simulation
# Simulate a CORS preflight request
curl -X OPTIONS \
-H "Origin: https://frontend.example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type, Authorization" \
-I https://api.example.com/data
Saving Headers to a File
# Save response headers to a file
curl -D headers.txt https://example.com
Save headers and body separately
curl -D headers.txt -o body.html https://example.com
Save only headers (no body)
curl -I -o /dev/null -D headers.txt https://example.com
Header Debugging Tips
# Show request headers only (filter verbose output)
curl -v https://example.com 2>&1 | grep "^>"
Show response headers only
curl -v https://example.com 2>&1 | grep "^<"
Full trace for debugging header issues
curl --trace-ascii - https://example.com | head -50
Python Equivalent
import requests
Set custom headers
headers = {
"Accept": "application/json",
"Authorization": "Bearer TOKEN",
"User-Agent": "MyApp/2.0",
"X-Custom-Header": "value",
}
response = requests.get("https://api.example.com/data", headers=headers)
View response headers
print(dict(response.headers))
print(response.headers["Content-Type"])
print(response.headers.get("X-RateLimit-Remaining"))
View request headers that were sent
print(dict(response.request.headers))
Headers with Proxies
When using proxies, be aware that some headers behave differently:
# Proxy may add X-Forwarded-For header
curl -x http://proxy:8080 \
-H "X-Forwarded-For: 203.0.113.50" \
https://httpbin.org/headers
Some proxies strip or modify headers
Use verbose mode to verify
curl -v -x http://user:pass@proxy:8080 https://httpbin.org/headers
FAQ
How many headers can I send with cURL?
There is no hard limit on the number of headers, but total header size is typically limited by the server (usually 8-16 KB).
Does the order of headers matter?
Generally no. However, some servers or WAFs may inspect header order to detect automated tools. Browsers send headers in a consistent order, so mimicking that order can help avoid detection.
How do I send the same header multiple times?
Use multiple -H flags with the same header name: curl -H "X-Custom: value1" -H "X-Custom: value2" URL. Whether the server receives both depends on the header and server implementation.
Why does my cURL request fail but my browser works?
Browsers send many headers automatically (User-Agent, Accept, Cookies, etc.). Your cURL request may be missing headers the server requires. Use browser DevTools to copy the exact headers.