Skip to content

HTTP Headers

HTTP headers are key-value pairs sent with every HTTP request and response. They provide metadata about the message, such as what format the client expects, how the server should cache the response, or what credentials are being used for authentication.

Headers appear between the request/response line and the body, following this structure:

Header-Name: value

A single request or response can include multiple headers, each on its own line.


Here is what a typical HTTP request looks like with its headers:

GET /api/cameras HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
User-Agent: Mozilla/5.0

And the corresponding response:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1024
Cache-Control: max-age=3600
ETag: "abc123"

Request headers are sent by the client to provide information about the request or about the client itself.

HeaderDescriptionExample
HostThe hostname of the target server. Required in HTTP/1.1.Host: api.example.com
AcceptThe media types the client can handle in the response.Accept: application/json
Content-TypeThe media type of the request body (used with POST, PUT, PATCH).Content-Type: application/json
AuthorizationCredentials for authenticating the client with the server.Authorization: Bearer <token>
User-AgentIdentifies the client software making the request.User-Agent: Mozilla/5.0
Accept-LanguageThe preferred language(s) for the response.Accept-Language: en-US, fr
Accept-EncodingThe compression encodings the client supports.Accept-Encoding: gzip, deflate
Cache-ControlDirectives for caching behavior.Cache-Control: no-cache
If-None-MatchMakes the request conditional based on an ETag value. The server returns 304 Not Modified if the ETag matches.If-None-Match: "abc123"
If-Modified-SinceMakes the request conditional based on a date. The server returns 304 Not Modified if the resource has not changed.If-Modified-Since: Wed, 01 Jan 2025 00:00:00 GMT

Response headers are sent by the server to provide information about the response or instructions to the client.

HeaderDescriptionExample
Content-TypeThe media type of the response body.Content-Type: application/json
Content-LengthThe size of the response body in bytes.Content-Length: 1024
LocationThe URI of a newly created resource (with 201) or a redirect target (with 3xx).Location: /api/cameras/42
Cache-ControlDirectives that control how the response should be cached.Cache-Control: max-age=3600
ETagA version identifier for the resource. Used with If-None-Match for conditional requests.ETag: "abc123"
Set-CookieSets a cookie on the client.Set-Cookie: session_id=xyz; HttpOnly
Access-Control-Allow-OriginSpecifies which origins are allowed to access the resource (CORS).Access-Control-Allow-Origin: *
Retry-AfterTells the client how long to wait before retrying (used with 429 or 503).Retry-After: 60
VaryIndicates which request headers the server used to select the response. Important for caching.Vary: Accept, Accept-Encoding

APIs sometimes include custom headers for application-specific metadata. Historically, custom headers used the X- prefix:

X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42

Here is a complete request and response showing how several headers work together:

Request:

POST /api/cameras HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
{
"brand": "Canon",
"model": "EOS R5",
"price": 3899.99
}

Response:

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/cameras/42
Cache-Control: no-cache
ETag: "v1-camera-42"
{
"id": 42,
"brand": "Canon",
"model": "EOS R5",
"price": 3899.99
}

In this example:

  • The client sends Content-Type to tell the server the body is JSON, and Accept to request a JSON response.
  • The client includes an Authorization header with a Bearer token.
  • The server responds with 201 Created and a Location header pointing to the new resource.
  • The server includes an ETag so the client can use If-None-Match in future requests to check if the resource has changed.