What is content negotiation and how does the Accept header work?
Understand content negotiation in REST APIs: how the Accept header, q values, and Content-Type let one URL serve multiple formats and languages.
Expected Interview Answer
Content negotiation is the mechanism by which a client and server agree on the best representation of a resource, such as its format or language, and the Accept header is how the client states which media types it prefers.
The client sends headers like Accept: application/json, or Accept-Language and Accept-Encoding, often with quality values (q) ranking preferences. The server inspects these, picks the best matching representation it can produce, and responds with a Content-Type header describing what it actually sent. If it cannot satisfy any acceptable type, it returns 406 Not Acceptable. This is called server-driven (proactive) negotiation; agent-driven negotiation instead lets the client choose from options the server lists.
- One URL can serve multiple formats
- Decouples resources from representations
- Supports internationalization via Accept-Language
- Enables compression via Accept-Encoding
- Allows API versioning through media types
AI Mentor Explanation
Imagine asking the stadium announcer for the score. You say you'd prefer it in Hindi, then English if Hindi isn't available. The announcer checks which languages they can speak, picks Hindi, and tells you which one they chose before speaking. The Accept header is your ranked language request; the announcer's confirmation of the language used is the Content-Type; if they speak neither, they simply cannot serve you.
Step-by-Step Explanation
Step 1
Client sends Accept headers
The request lists acceptable media types, languages, and encodings, optionally with q quality weights.
Step 2
Server parses preferences
It reads the ranked list and compares it against representations it can produce.
Step 3
Server selects best match
Using highest q value and specificity, it chooses one representation to return.
Step 4
Server sets Content-Type
The response advertises exactly what was sent via Content-Type, Content-Language, or Content-Encoding.
Step 5
Handle no match
If nothing acceptable can be produced, the server returns 406 Not Acceptable (or a sensible default).
What Interviewer Expects
- What the Accept header and quality (q) values mean
- Difference between server-driven and agent-driven negotiation
- Role of the Content-Type response header
- When 406 Not Acceptable is returned
- Related headers: Accept-Language and Accept-Encoding
Common Mistakes
- Confusing the request Accept header with the response Content-Type header
- Ignoring q quality values when ranking preferences
- Always returning JSON regardless of what the client accepts
- Returning 200 with the wrong format instead of 406 when nothing matches
- Forgetting the Vary header, breaking caches that ignore Accept
Best Answer (HR Friendly)
“Content negotiation is how an app and a server agree on the format of a response, like JSON or XML, or the language of the text. The app says what it prefers through the Accept header, and the server sends back the best version it can, labelling exactly what it returned.”
Code Example
app.get('/api/user/:id', async (req, res) => {
const user = await getUser(req.params.id)
res.format({
'application/json': () => {
res.json(user)
},
'application/xml': () => {
res.type('application/xml')
res.send(`<user><id>${user.id}</id><name>${user.name}</name></user>`)
},
'text/html': () => {
res.send(`<h1>${user.name}</h1>`)
},
default: () => {
// No acceptable representation available
res.status(406).send('Not Acceptable')
},
})
})
// Example request:
// GET /api/user/7
// Accept: application/xml;q=0.9, application/json;q=1.0Follow-up Questions
- What does the q value in an Accept header control?
- What is the difference between server-driven and agent-driven negotiation?
- Why is the Vary header important with content negotiation?
- How can media types be used for API versioning?
- What status code is returned when no representation is acceptable?
MCQ Practice
1. Which header does a client use to state preferred response formats?
The Accept request header lists media types the client can handle; Content-Type describes what the server actually sent.
2. What status code means the server cannot produce any acceptable representation?
406 Not Acceptable indicates no representation matches the client's Accept headers; 415 is about an unsupported request body type.
3. What do q values in an Accept header represent?
Quality values (q=0 to q=1) rank the client's relative preference for each media type, guiding the server's choice.
Flash Cards
Accept vs Content-Type? — Accept is a request header stating preferred formats; Content-Type is a header describing the format actually present in the message body.
What is 406 Not Acceptable? — The response when the server cannot produce any representation matching the client's Accept headers.
What is a q value? — A quality weight (0 to 1) in Accept headers ranking the client's relative preference among media types or languages.
Why send Vary: Accept? — It tells caches the response varies by the Accept header, preventing them from serving the wrong format to a different client.