# Content Negotiation API
> HTTP content negotiation as an API. The parse endpoint reads an Accept, Accept-Language, Accept-Encoding or Accept-Charset header — with quality (q) values and parameters — into a clean list ranked by the client's preference. The negotiate endpoint takes that header plus the list of values your server can actually serve and returns the single best match, along with the full ranked result and the entry that matched each candidate. It applies the correct rules for each kind: media-type type and subtype wildcards (text/*, */*), RFC 4647 language-range matching (a request for en matches your en-US, and en-US falls back to en), and exact matching with a * wildcard for encodings and charsets — and a q=0 entry correctly rejects a value. Everything runs locally and deterministically, so it is instant and private. Ideal for i18n middleware and locale selection, API versioning by media type, response-format and compression selection, CDNs, proxies and edge functions. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 3 endpoints. This negotiates HTTP headers; to validate or decompose a single BCP-47 language tag use a BCP-47 API.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/negotiate-api/..."
```

## Pricing
- **Free** (Free) — 2,335 calls/Mo, 2 req/s
- **Starter** ($4/Mo) — 11,850 calls/Mo, 8 req/s
- **Pro** ($24/Mo) — 169,500 calls/Mo, 20 req/s
- **Mega** ($62/Mo) — 890,000 calls/Mo, 50 req/s

## Endpoints

### Negotiate

#### `GET /v1/negotiate` — Negotiate the best match

**Parameters:**
- `header` (query, required, string) — The Accept-style header Example: `en-US,en;q=0.9,fr;q=0.5`
- `supported` (query, required, string) — Values you can serve (list or comma/space separated) Example: `fr,en,de`
- `type` (query, optional, string) — language (default), mediatype, encoding, charset or generic Example: `language`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/negotiate-api/v1/negotiate?header=en-US%2Cen%3Bq%3D0.9%2Cfr%3Bq%3D0.5&supported=fr%2Cen%2Cde&type=language"
```

**Response:**
```json
{
    "data": {
        "best": "en",
        "type": "language",
        "matches": [
            {
                "value": "en",
                "quality": 1,
                "matched_by": "en-US"
            },
            {
                "value": "fr",
                "quality": 0.5,
                "matched_by": "fr"
            },
            {
                "value": "de",
                "quality": 0,
                "matched_by": null
            }
        ],
        "acceptable": true,
        "best_quality": 1
    },
    "meta": {
        "timestamp": "2026-06-03T09:25:04.239Z",
        "request_id": "eef6fe82-3295-4168-9dae-38e047bb6c56"
    },
    "status": "ok",
    "message": "Negotiate the best match",
    "success": true
}
```

#### `GET /v1/parse` — Parse an Accept header

**Parameters:**
- `header` (query, required, string) — An Accept-style header value Example: `en-US,en;q=0.9,fr;q=0.5`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/negotiate-api/v1/parse?header=en-US%2Cen%3Bq%3D0.9%2Cfr%3Bq%3D0.5"
```

**Response:**
```json
{
    "data": {
        "count": 3,
        "accepted": [
            {
                "value": "en-US",
                "quality": 1
            },
            {
                "value": "en",
                "quality": 0.9
            },
            {
                "value": "fr",
                "quality": 0.5
            }
        ]
    },
    "meta": {
        "timestamp": "2026-06-03T09:25:04.350Z",
        "request_id": "cd534777-af73-4ad1-8e93-ac660d3946e2"
    },
    "status": "ok",
    "message": "Parse an Accept header",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/negotiate-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Content Negotiation API",
        "notes": "Languages use RFC 4647 prefix matching; media types honour type and subtype wildcards. When nothing is acceptable, best is null. This negotiates HTTP headers — to validate or decompose a single BCP-47 language tag use a BCP-47 API. Nothing is stored.",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/parse",
                "params": {
                    "header": "an Accept-style header value (required)"
                },
                "returns": "the accepted values ranked by quality"
            },
            {
                "path": "/v1/negotiate",
                "params": {
                    "type": "language (default), mediatype, encoding, charset or generic",
                    "header": "the Accept-style header (required)",
                    "supported": "the values you can serve — list or comma/space separated (required)"
                },
                "returns": "the best match and the full ranked result"
            },
            {
                "path": "/v1/meta",
                "params": [],
                "returns": "this document"
            }
        ],
        "description": "HTTP content negotiation. The parse endpoint reads an Accept, Accept-Language, Accept-Encoding or Accept-Charset header — with quality (q) values and parameters — into a clean list ranked by preference. The negotiate endpoint takes that hea
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/negotiate-api
OpenAPI spec: https://www.oanor.com/api/negotiate-api/openapi.json
