In HTTP content negotiation, what does the q= parameter mean in a request header such as 'Accept: text/html;q=0.8, application/json', and what value applies when you leave it out?
answer
- q = relative weight, 0–1, 3 decimals
- omitted q means 1, the maximum
- order in the list is irrelevant
- q=0 = refusal, not low priority
- preference, not a command to the server
basics
~20 sq is a relative preference weight from 0 to 1 (three decimals max). Omitted means q=1, the strongest preference; q=0 means unacceptable. So in that header application/json (q=1) is preferred over text/html (0.8). Header order carries no priority.
solid answer
~50 s`q` (quality value) is the weight a client attaches to each option in an `Accept-*` header to express **relative** preference. Range 0 to 1, at most three decimals, and **omitting it means q=1** — so in `Accept: text/html;q=0.8, application/json`, JSON outranks HTML even though HTML is listed first. Position in the list means nothing; only the weights do. `q=0` explicitly says "not acceptable". The same mechanism applies to `Accept`, `Accept-Language`, `Accept-Encoding` (and the obsolete `Accept-Charset`). Weights are preferences, not commands: the server performs selection and may combine client weights with its own quality factors, and it is permitted to serve something the client ranked low rather than fail. `q` is a parameter of the header field, not part of the media type — everything from `;q=` onward belongs to negotiation, not to the content type itself.
code
http · 1 lineGET /page HTTP/1.1\nHost: example.com\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,*/*;q=0.8\nAccept-Language: en-GB,en;q=0.9,de;q=0.5\nAccept-Encoding: gzip, deflate, brgo deeper
Know the range 0–1, that the default is 1, that q=0 means unacceptable, and that order does not matter.
Add the parsing detail (parameter of the field, three-decimal limit), the fact that the server combines client q with its own quality factors, and that the server may ignore preferences.
Talk about how your service actually parses Accept, the risk of first-match parsers, and behavioural differences between browsers (*/*;q=0.8) and API clients.
Frame it as a contract question: how much of your API's behaviour should hinge on a header the caller often does not control, and when to negotiate on the URL instead.
## What quality values are for\n\nOne URL can have several *representations*: an HTML page and a JSON document, a German and an English translation, a compressed and an uncompressed body. In server-driven negotiation the client advertises what it can use, and the server picks. Quality values are how the client says "I can take several of these, but here is how much I want each one".\n\n## Syntax\n\nA quality value is a header **parameter** written `;q=` followed by a number. Legal forms are `0`, `1`, or a decimal with **at most three digits** after the point: `q=0.8`, `q=0.001`, `q=1.0`. Values outside 0–1 or with more precision are malformed; implementations typically clamp or ignore them. Whitespace may surround the semicolon, and the parameter name is case-insensitive.\n\n```\nAccept: text/html;q=0.8, application/json\nAccept-Language: de, en;q=0.7, *;q=0.1\nAccept-Encoding: br, gzip;q=0.9, identity;q=0.1\n```\n\n## The default is 1, not 0\n\nThe single most common misreading is treating an unweighted entry as neutral or low. **An entry with no `q` has q=1**, the maximum. In `Accept: text/html;q=0.8, application/json`, the client is saying it would rather have JSON. Writing `Accept: application/json;q=0.9` when nothing else is listed does not make JSON less preferred — with only one candidate it changes nothing; weights only matter *relative to each other*.\n\n## Order does not matter\n\nHTTP list-valued header fields are unordered for the purposes of preference. `a;q=0.5, b` and `b, a;q=0.5` are identical. Some sloppy servers do first-match parsing; that is a bug in those servers, not a rule of HTTP. Real clients rely on the weights: browsers send things like `Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`, which reads as "HTML and XHTML most, generic XML slightly less, anything at all as a fallback".\n\n## q=0 is a refusal\n\nZero is not "lowest preference", it is "unacceptable". `identity;q=0` in `Accept-Encoding` means "do not send this uncompressed". A wildcard at zero, such as `*/*;q=0`, refuses everything not explicitly listed above it.\n\n## Where it applies\n\n`Accept` (media types), `Accept-Language` (language tags), `Accept-Encoding` (content codings), and the deprecated `Accept-Charset`. Each is an independent axis; a q on one says nothing about the others. `Accept-Ranges`, `Accept-Patch` and similar server-advertisement headers do **not** take q values.\n\n## What the server does with them\n\nThe weights are input, not instruction. A server computes, for each representation it can produce, a combined score from the client's weight and its own opinion of that representation's quality (a JPEG thumbnail is a worse rendition than the original PNG, for instance), and serves the winner. A server is allowed to disregard the preferences entirely and send its default rather than refuse — HTTP explicitly permits this, because a slightly-unwanted response is usually more useful to a user agent than an error. So `q` reliably expresses *what the client wants*; it never guarantees *what the client gets*.\n\n## Practical notes\n\nBecause q is a parameter of the field, code that naively splits `Accept` on commas and treats each fragment as a media type will produce `text/html;q=0.8` as a "type" and fail to match. Parse the parameter off before comparison. And remember that clients send these headers automatically: a browser's `Accept` is fixed by the browser, so an API that behaves differently for `*/*;q=0.8` than for `application/json` is behaving differently for browsers than for its own SDK.
- Does listing a media type first make it more preferred?No. Preference is carried only by the q parameter; the list is unordered. `text/html;q=0.5, application/json` prefers JSON despite HTML appearing first. Servers that pick the first entry are doing first-match parsing, which is a defect, not the specified behaviour.
- If a client sends no Accept header at all, what should the server do?Treat it as if the client accepts anything — an absent Accept header is equivalent to `*/*`. The server serves its default representation. It must not return a negotiation error just because the header is missing.
A wedding RSVP meal preference: you rank chicken 1st, fish second, and cross out the vegan option entirely. The kitchen reads your ranking, weighs it against what it can actually cook, and plates something — your ranking is input, not an order.
saying these in an interview costs you the question
- Saying an omitted q means 0, or 'neutral', rather than 1
- Claiming header order sets priority and q is only a tiebreak
- Treating q=0 as merely the lowest preference instead of an outright refusal
- Believing a high q obliges the server to send that representation
- Splitting Accept on commas and comparing 'application/json;q=0.9' as a media type