REST APIs in Depth · REST Foundations
Headers, Content Negotiation and Representations
Media types, Accept, Content-Type, Vary, compression and custom headers.
HTTP separates the resource from its representations. Clients state preferences with Accept (media type), Accept-Language, Accept-Encoding; servers declare Content-Type, Content-Language, Content-Encoding and Vary (so caches store variants correctly). Use application/json (or a vendor type like application/vnd.acme+json if you version by media type), application/problem+json for errors, and 415 Unsupported Media Type / 406 Not Acceptable when negotiation fails. Prefer standard headers over custom X- headers; when you need custom ones, document them.
Headers every API designer should know
| Header | Direction | Purpose |
|---|---|---|
| Accept / Content-Type | Req / Resp | Media type negotiation |
| Accept-Encoding / Content-Encoding | Req / Resp | Compression (br, gzip, zstd) |
| Vary | Resp | Tell caches which request headers change the response |
| Location | Resp | URI of a created resource or job |
| Retry-After | Resp | When to retry (429/503/202 polling) |
| Idempotency-Key | Req | Deduplicate retried unsafe requests |
| traceparent | Req | Distributed tracing context |
GET /reports/2026-q3 HTTP/1.1
Accept: text/csv;q=1.0, application/json;q=0.8
Accept-Encoding: br, gzip
HTTP/1.1 200 OK
Content-Type: text/csv; charset=utf-8
Content-Encoding: br
Vary: Accept, Accept-Encoding
Content-Disposition: attachment; filename="report-2026-q3.csv"
Common pitfalls
- Ignoring
Acceptand always returning JSON (or HTML error pages from proxies). - Missing
Vary, so caches serve the wrong variant. - Putting auth tokens or secrets in custom headers that get logged.
Key points
- Resources vs representations
- Negotiate with Accept; declare with Content-Type
- Vary for correct caching
Further reading: RFC 9110: Content negotiation
Practice questions
What does the Vary header do?
Answer
It lists request headers that influence the response (e.g., Accept-Encoding, Accept-Language) so caches store and serve separate variants instead of mixing them.
When should an API return 415 vs 406?
Answer
415 when the request body's Content-Type isn't supported; 406 when the server can't produce any representation matching the client's Accept header.
Open in the app to mark lessons complete, take notes and track your progress.