← Concepts

阅读中文版本

Content Negotiation

Content negotiation lets clients request a representation by media type, language, or encoding through Accept headers, and the server selects and labels the response.

web

Definition

Content negotiation is the HTTP mechanism by which a client states preferences with Accept, Accept-Language, and Accept-Encoding, and the server chooses one representation, returning 406 when no acceptable option exists.

Context and scope

Use it when one resource has multiple representations, such as JSON and XML, several languages, or compressed and uncompressed bodies, and clients differ in what they can handle.

Common misconceptions

  • It only covers languages; media type, charset, and encoding are negotiated too
  • The Accept header forces a representation; the server may return another acceptable type and labels it via Content-Type
  • Negotiation has no caching cost; responses vary by headers, which requires Vary

Anti-patterns

  • Ignoring Vary so shared caches serve the wrong representation
  • Using Accept for API versioning without documenting fallback behavior
  • Returning 500 instead of 406 when no representation matches

Related concepts

Related examples

Authoritative source

https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation

How it works

A request can carry several preference headers. Accept lists media types, Accept-Language lists languages, and Accept-Encoding lists compression schemes. Each entry may include a quality value from 0 to 1, so the server can rank options. The server picks the best available representation, returns it with a matching Content-Type or Content-Language, and adds Vary so caches key on the request headers that influenced the choice.

GET /docs/guide HTTP/1.1
Accept: text/html;q=1.0, application/json;q=0.8
Accept-Language: fr-CA, en;q=0.7
Accept-Encoding: br, gzip

If nothing is acceptable, the correct response is 406 Not Acceptable. A server may also ignore preferences and return its default, but it must then label the representation honestly.

When to use it

Negotiation fits content platforms, internationalized sites, and APIs that support multiple media types or versions. It keeps one URL per resource while allowing clients to choose a format, which is useful for accessibility, bandwidth, and localization.

Trade-offs

Every negotiated dimension multiplies cache variants. A Vary: Accept, Accept-Language, Accept-Encoding header can fragment a CDN cache badly; normalizing headers or using separate URLs is often more efficient. Quality values are easy to misread, and few clients send precise preferences. Debugging requires inspecting request headers, not just paths.

Example and misconceptions

A frequent mistake is assuming Accept is a demand. If a client asks for XML and the server only has JSON, returning JSON with Content-Type: application/json is legitimate only when the client did not forbid it; otherwise 406 is correct. Another mistake is changing language via Accept-Language while caching one variant for everyone.

Related concepts: HTTP Caching, API Versioning, and Cache Invalidation.