2026-09-19 · 6 min read · Rahul Chitturi
- http
- content-negotiation
- api
An API can support JSON and another representation yet return the wrong format because the client, framework, gateway, and cache interpret Accept differently. Wildcards, parameters, quality values, and server preference all influence the selected representation.
A request without Accept generally permits any representation. A present range with q=0 makes that range unacceptable, so treating absence and explicit rejection as equivalent creates hard-to-reproduce client failures.
Capture the complete selection input
Record the raw Accept field, route capabilities, response Content-Type, status, and the component that chose them. Parse comma-separated ranges with an HTTP library instead of splitting around delimiters that may appear inside quoted parameters.
- Validate q-values and their allowed precision.
- Keep media-type parameters attached to their range.
- Apply specificity and server preference deterministically.
- Return a documented fallback or 406 when nothing is acceptable.
Keep caches representation-aware
When Accept changes the selected response, shared caches need an appropriate Vary field and a cache key that respects it. Otherwise, a cached JSON response can be served to a client that requested another type, or each irrelevant header variation can fragment the cache.
Compare behavior through the production gateway and CDN as well as directly against the application. Intermediaries may normalize headers or cache a response before the origin's selection logic runs.
Build a negotiation matrix
Use Flashman's URL tool for endpoints, JSON formatter for harmless response fixtures, diff for request and response headers, and case converter to reveal accidental token handling assumptions.
Test absent Accept, exact types, structured suffixes, wildcards, parameters, equal and zero weights, malformed values, repeated field lines, unsupported types, error responses, Vary behavior, cache hits, and every supported client library.