# Content Negotiation and the Accept Header — API Design and Versioning

Source: https://www.geekswithgeeks.com/en/api-design/ver-content-negotiation

> Let clients state preferred formats or versions with q-values and respond accordingly.

## The client states preferences

With **content negotiation** the client lists acceptable representations in the `Accept` header, each with an optional quality value `q` from 0 to 1 (default 1), and the server picks the best match it supports or answers **`406 Not Acceptable`** (or falls back to a default). The same mechanism can select a **version** through a vendor media type such as `application/vnd.example.v2+json`. Always include a `Vary: Accept` header on responses that depend on it so caches store separate copies, and document what happens when no preference is sent.

## Parsing Accept with q-values, run

I ran this plain-Python example. The highest-quality media type comes first: the v2 vendor type (q=0.9), then plain JSON (0.5), then the wildcard (0.1).

```python
import hmac, hashlib, json, time, bisect

def parse_accept(h):
    items = []
    for part in h.split(","):
        bits = part.strip().split(";"); q = 1.0
        for b in bits[1:]:
            if b.strip().startswith("q="): q = float(b.strip()[2:])
        items.append((q, bits[0].strip()))
    return [m for q, m in sorted(items, key=lambda x: -x[0])]
print(parse_accept("application/vnd.example.v2+json;q=0.9, application/json;q=0.5, */*;q=0.1"))

```

Output:

```
['application/vnd.example.v2+json', 'application/json', '*/*']
```

## Set a safe default

If a client sends no version, serve a stable, documented default (often the oldest supported version) rather than the newest, so existing integrations do not change under them.

**Quiz:** Which header should be added when the response depends on Accept?

- [x] Vary: Accept
- [ ] Content-Length: 0
- [ ] Retry-After
- [ ] Location

*Answer:* Vary: Accept. Vary tells caches the response differs by the Accept header, avoiding the wrong copy being served.
