REST APIs in Depth · REST Foundations

Headers, Content Negotiation and Representations

Media types, Accept, Content-Type, Vary, compression and custom headers.

Create a free account to save this page, take notes and track your progress. Sign in

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.

Was this page helpful?