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 Accept and 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.