API Request Headers: Complete Introduction (2026)
Everything you need to know about HTTP request headers for API development
Start Building with Hypereal
Access Kling, Flux, Sora, Veo & more through a single API. Free credits to start, scale to millions.
No credit card required • 100k+ developers • Enterprise ready
API Request Headers: Complete Introduction (2026)
HTTP request headers are key-value pairs sent by the client to the server with every API request. They carry metadata about the request -- what format the data is in, who is making the request, what response format is acceptable, and how the server should handle caching, security, and routing.
If you are building or consuming APIs, understanding request headers is fundamental. This guide covers the most important headers, when to use them, and practical code examples in cURL, Python, and JavaScript.
What Are Request Headers?
Every HTTP request consists of three parts:
- Request line: The method (GET, POST, etc.) and the URL.
- Headers: Key-value metadata about the request.
- Body: The data payload (for POST, PUT, PATCH requests).
Here is a raw HTTP request showing all three parts:
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json
User-Agent: MyApp/1.0
Content-Length: 52
{"name": "Alice", "email": "alice@example.com"}
The lines between the request line and the body are the headers. Each header has a name and a value separated by a colon.
Essential Request Headers
Content-Type
Tells the server the format of the request body.
| Value | When to Use |
|---|---|
application/json |
Most REST APIs |
application/x-www-form-urlencoded |
HTML form submissions, OAuth token requests |
multipart/form-data |
File uploads |
text/plain |
Plain text payloads |
application/xml |
XML-based APIs (SOAP, some enterprise APIs) |
application/octet-stream |
Raw binary data |
Example: JSON request
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}'
Example: Form-encoded request
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=abc&client_secret=xyz"
Example: File upload
curl -X POST https://api.example.com/upload \
-H "Content-Type: multipart/form-data" \
-F "file=@photo.jpg" \
-F "description=Profile photo"
A common mistake is sending application/json as the Content-Type but sending form-encoded data in the body, or vice versa. The server will return a 400 or 415 error when the Content-Type does not match the actual format of the body.
Authorization
Identifies the caller and grants access to protected resources.
| Scheme | Format | Use Case |
|---|---|---|
| Bearer | Bearer <token> |
OAuth 2.0, JWT-based APIs |
| Basic | Basic <base64(user:pass)> |
Simple API key authentication |
| API Key | X-API-Key: <key> |
Proprietary APIs (custom header) |
| Digest | Digest <params> |
Legacy systems |
Bearer token (most common):
import requests
response = requests.get(
"https://api.example.com/users/me",
headers={
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
)
Basic auth:
import requests
response = requests.get(
"https://api.example.com/data",
auth=("username", "password"), # requests handles Base64 encoding
)
API key in custom header:
response = requests.get(
"https://api.example.com/data",
headers={
"X-API-Key": "your-api-key-here"
},
)
Accept
Tells the server what response format you want to receive.
# Request JSON response
curl -H "Accept: application/json" https://api.example.com/data
# Request XML response (if the API supports it)
curl -H "Accept: application/xml" https://api.example.com/data
# Accept multiple formats with preference (quality factor)
curl -H "Accept: application/json;q=0.9, text/html;q=0.8" https://api.example.com/data
The q parameter (quality factor) indicates your preference on a scale of 0 to 1. If the server supports multiple formats, it will choose the one with the highest quality factor.
User-Agent
Identifies the client making the request. While not always required, many APIs use it for analytics, rate limiting, and debugging.
headers = {
"User-Agent": "MyApp/2.0 (Python 3.12; Linux x86_64)"
}
Some APIs reject requests without a User-Agent header or with generic library defaults. Always set a descriptive User-Agent for production applications.
Caching Headers
Proper caching headers reduce server load and improve response times.
Cache-Control (Request)
| Directive | Meaning |
|---|---|
no-cache |
Validate with server before using cached response |
no-store |
Do not cache the response at all |
max-age=0 |
Treat cached response as expired |
only-if-cached |
Only return cached response; fail if not cached |
# Force a fresh response, bypassing any cache
curl -H "Cache-Control: no-cache" https://api.example.com/data
If-None-Match / If-Modified-Since
These are conditional request headers that enable efficient caching:
# First request: server returns ETag in response
response = requests.get("https://api.example.com/data")
etag = response.headers.get("ETag")
# Subsequent request: send ETag back
response = requests.get(
"https://api.example.com/data",
headers={"If-None-Match": etag},
)
if response.status_code == 304:
print("Data has not changed, use cached version")
else:
print("Data updated, process new response")
This avoids transferring the full response body when the data has not changed, saving bandwidth and reducing latency.
CORS Headers
Cross-Origin Resource Sharing (CORS) headers are relevant when your browser-based JavaScript application calls an API on a different domain.
Preflight Request Headers
When the browser sends a preflight (OPTIONS) request, it includes:
| Header | Purpose |
|---|---|
Origin |
The domain making the request |
Access-Control-Request-Method |
The HTTP method the actual request will use |
Access-Control-Request-Headers |
Custom headers the actual request will include |
You do not set these manually -- the browser adds them automatically. But understanding them helps when debugging CORS issues.
Common CORS Debugging Checklist
- Check the browser console for the exact CORS error message.
- Verify the
Access-Control-Allow-Originheader in the server's response matches your domain (or is*). - If you are sending custom headers (like
Authorization), the server must include them inAccess-Control-Allow-Headers. - If the server requires credentials, both
Access-Control-Allow-Credentials: trueand a specific (not*) origin are required.
Rate Limiting Headers
APIs use headers to communicate rate limit status:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the window |
X-RateLimit-Remaining |
Requests remaining in the current window |
X-RateLimit-Reset |
When the window resets (Unix timestamp) |
Retry-After |
Seconds to wait before retrying (sent with 429 responses) |
Handling rate limits in Python:
import time
import requests
def make_request(url, headers):
response = requests.get(url, headers=headers)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
return make_request(url, headers) # Retry
remaining = response.headers.get("X-RateLimit-Remaining")
if remaining and int(remaining) < 10:
print(f"Warning: only {remaining} requests remaining")
return response
Request ID and Tracing Headers
For debugging distributed systems, include request tracing headers:
| Header | Purpose |
|---|---|
X-Request-ID |
Unique identifier for the request (for log correlation) |
X-Correlation-ID |
Trace ID that persists across service-to-service calls |
Traceparent |
W3C standard trace context header |
import uuid
headers = {
"X-Request-ID": str(uuid.uuid4()),
"X-Correlation-ID": "user-session-abc-123",
}
Many API providers return a request ID in the response. Always log this value -- it is essential for troubleshooting issues with the provider's support team.
Setting Headers in Different Languages
Python (requests)
import requests
response = requests.post(
"https://api.example.com/data",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer your-token",
"Accept": "application/json",
"X-Request-ID": "req-12345",
},
json={"key": "value"}, # automatically sets Content-Type to application/json
)
Note: When you use the json parameter in requests.post(), the library automatically sets Content-Type: application/json. You do not need to set it manually in that case.
JavaScript (fetch)
const response = await fetch("https://api.example.com/data", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer your-token",
"Accept": "application/json",
},
body: JSON.stringify({ key: "value" }),
});
JavaScript (axios)
import axios from "axios";
// Set default headers for all requests
axios.defaults.headers.common["Authorization"] = "Bearer your-token";
axios.defaults.headers.post["Content-Type"] = "application/json";
// Or per-request
const response = await axios.post(
"https://api.example.com/data",
{ key: "value" },
{
headers: {
"X-Custom-Header": "custom-value",
},
}
);
cURL
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-H "Accept: application/json" \
-H "X-Request-ID: req-12345" \
-d '{"key": "value"}'
Quick Reference Table
| Header | Required? | Example Value | Purpose |
|---|---|---|---|
Content-Type |
For requests with body | application/json |
Format of request body |
Authorization |
For protected endpoints | Bearer eyJ... |
Authentication |
Accept |
Recommended | application/json |
Desired response format |
User-Agent |
Recommended | MyApp/1.0 |
Client identification |
Cache-Control |
Optional | no-cache |
Caching behavior |
If-None-Match |
Optional | "etag-value" |
Conditional request |
Origin |
Auto (browser) | https://myapp.com |
CORS |
X-Request-ID |
Recommended | uuid-value |
Request tracing |
Conclusion
Understanding request headers is essential for working with any HTTP API. The most important ones to remember are Content-Type (what you are sending), Authorization (who you are), and Accept (what you want back). Beyond those, caching headers, CORS headers, and rate limit headers become relevant as your applications grow in complexity.
If you are building applications that call AI media generation APIs -- for images, videos, talking avatars, or audio -- check out Hypereal AI. Hypereal provides a unified API with simple authentication headers and pay-as-you-go pricing for the latest generative AI models.
Related Articles
Start Building Today
Get 35 free credits on signup. No credit card required. Generate your first image in under 5 minutes.
