Home/Developers/Snelstart
5 minuten

Wine Pairing API snelstart

Van nul naar een werkende wijn-spijsmatch in vijf minuten. Stuur bijvoorbeeld “gegrilde zalm met citroen en dille” en ontvang gerangschikte wijnstijlen met een matchscore van 0–100.

Bijgewerkt 16 juli 2026 · v1 API

1

Vraag een API-key aan

Maak een account in het developerportaal. Je begint met 100 gratis calls per dag, zonder creditcard.

Ga naar business.sommelierx.com en kopieer je key. Die begint met sk_live_, gevolgd door 32 hexadecimale tekens.

export SOMMELIERX_API_KEY="sk_live_..."
NiveauPer dagPer minuutScores
Free10060Matchpercentage
Starter1.000300Volledige scoreopbouw
Pro5.0001.200Volledige scoreopbouw + geavanceerde endpoints
Enterprise25.0003.000Volledige scoreopbouw + SLA
2

Kies het juiste endpoint

Kies op basis van wat je al weet. Een vrije gerechtomschrijving is meestal de snelste route.

Je hebt…EndpointNiveau
Een gerecht in gewone taalPOST /pairing/by-textFREE
Een lijst ingrediëntnamenPOST /pairing/by-textFREE
Een gerecht-IDPOST /pairing/by-meal/{mealId}FREE
Ingrediënt-ID’s, hoeveelheden en bereidingPOST /pairing/calculateFREE
Een wijnstijl en zoekt gerechtenGET /pairing/by-wine/{wineId}/mealsFREE
Een vaste selectie wijnenPOST /pairing/by-ingredients-winesPRO
Meerdere gangen en één gedeelde wijnPOST /pairing/groupPRO
Een gelegenheid, zoals BBQ of dinerPOST /pairing/by-occasionPRO
Geen ID bekend? Zoek met GET /search?q=… of stuur de gerechtnaam naar /pairing/by-text. Onbekende ingrediënten worden aan het dichtstbijzijnde bekende ingrediënt gekoppeld, zodat de pairing kan doorgaan.
3

Voer een werkend voorbeeld uit

Deze request laat SommelierX zelf de ingrediënten uit de beschrijving halen en matchen.

curl -X POST https://api.sommelierx.com/api/v1/pairing/by-text \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "gegrilde zalm met citroen en dille",
    "language": "nl"
  }'

De response bevat de herkende ingrediënten en maximaal 25 wijnstijlen, gerangschikt op match_percentage. Resultaten onder 65 worden niet getoond.

Van een wijn naar gerechten

curl https://api.sommelierx.com/api/v1/pairing/by-wine/723/meals \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY"

Eén wijn voor meerdere gangen PRO

curl -X POST https://api.sommelierx.com/api/v1/pairing/group \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mealIds": [4329, 4330, 4331], "language": "nl" }'

mealCoverage toont bij hoeveel gangen de wijn de ondergrens haalt; avgScore is het gemiddelde over de gedekte gangen.

4

Begrijp de matchscore

Free toont het matchpercentage. Starter, Pro en Enterprise tonen ook de volledige berekening.

match_percentage

0–100

De hoofdscore. Vanaf 80 is de pairing sterk; 90+ is uitzonderlijk.

basic_score

0–10

Overeenkomst in body, structuur en gewicht.

balance_score

strafwaarde

Mogelijke botsing in tannine, zuur of zoet. Nul betekent geen botsing.

aromatic_score

0–10 of null

Overeenkomst in aroma’s zoals kruidig, fruitig, rokerig en mineraal.

5

Gebruik SommelierX via MCP

Koppel de MCP-server aan een compatibele client en stel je vragen in gewone taal.

{
  "mcpServers": {
    "sommelierx": {
      "command": "npx",
      "args": ["@sommelierx/mcp-server"],
      "env": { "SOMMELIERX_API_KEY": "sk_live_..." }
    }
  }
}

De API-key is optioneel. Zonder key geldt het Free-niveau op basis van het IP-adres.

Veelvoorkomende fouten

StatusCodeBetekenis
401API_KEY_MISSINGDe Authorization-header ontbreekt.
401API_KEY_INVALIDDe key is ongeldig of bevat extra spaties.
403TIER_REQUIREDHet endpoint vereist een hoger niveau.
429RATE_LIMIT_DAILYDe daglimiet is bereikt; de resetheader geeft het nieuwe tijdstip.
429RATE_LIMIT_MINUTEDe minuutlimiet is bereikt; gebruik Retry-After.
400INVALID_INPUTDe validatie is mislukt; details benoemt de velden.

Klaar om te bouwen?

Begin zonder creditcard met 100 gratis calls per dag.

Home/Developers/Quickstart
5 minute read

Wine Pairing API Quickstart

From zero to a working wine pairing in five minutes. Send a sentence like “grilled salmon with lemon and dill” and get back ranked wine styles with a 0–100 match score. No setup, no SDK — just curl.

Updated July 16, 2026 · v1 API

What you will do

  1. Get an API key — 60 seconds
  2. Pick the right endpoint — decision tree
  3. Run three working examples — copy, paste, done
  4. Understand the score — what the numbers mean
  5. Use it in Claude Desktop — one-line MCP config
1

Get an API key

Sign up on the developer portal. You get 100 free calls per day, no credit card required.

Go to business.sommelierx.com, create an account, and copy your key. It starts with sk_live_ followed by 32 hex characters.

Export it as an environment variable so you can use it across the rest of this guide:

export SOMMELIERX_API_KEY="sk_live_..."
Tiers at a glance. FREE: 100 calls/day and 60/minute. STARTER: 1,000/day and 300/minute. PRO: 5,000/day and 1,200/minute. ENTERPRISE: 25,000/day and 3,000/minute. STARTER and above include the full score breakdown; PRO unlocks the advanced pairing endpoints.
2

Pick the right endpoint

Most pairing tasks fit into one of eight patterns. Find your input on the left, use the endpoint on the right.

I have… Use this endpoint Tier
A sentence: “grilled salmon with dill” POST /pairing/by-text FREE
A list of ingredient names: ["salmon", "dill"] POST /pairing/by-text
(use the ingredients array, skips the AI step)
FREE
A meal ID from our catalog POST /pairing/by-meal/{mealId} FREE
Ingredient IDs with amount and preparation POST /pairing/calculate FREE
A wine type ID (find dishes for it) GET /pairing/by-wine/{wineId}/meals FREE
A specific shortlist of wines to score POST /pairing/by-ingredients-wines PRO
Multiple courses, one wine to share POST /pairing/group PRO
An occasion tag (BBQ, romantic dinner, …) POST /pairing/by-occasion PRO
Don’t know the meal or wine ID? Use GET /search?q=… to look them up, or just send the dish name to /pairing/by-text — the API resolves ingredient names against the database for you.
3

Three working examples

Each block below is a complete request with a representative response shape from api.sommelierx.com. Copy, paste, run.

Example A — Pair from a free-text dish

The simplest entry point: send a sentence in any language. The API extracts ingredients, resolves them to database IDs, and returns ranked wine styles.

curl -X POST https://api.sommelierx.com/api/v1/pairing/by-text \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "grilled salmon with lemon and dill",
    "language": "en"
  }'

Response (PRO tier, top 2 of 25 results shown):

{
  "data": {
    "resolved_ingredients": [
      { "input": "salmon", "matched": true, "ingredient": { "id": 6144, "name": "Salmon" } },
      { "input": "lemon",  "matched": true, "ingredient": { "id": 3656, "name": "Lemon"  } },
      { "input": "dill",   "matched": true, "ingredient": { "id": 3792, "name": "Dill"   } }
    ],
    "pairing_results": [
      {
        "metaWineId": 723,
        "name": "Semillon-Sauvignon New World Top",
        "type":   { "id": 4, "name": "White dry", "color": "white" },
        "region": "New World",
        "grapes": ["Sauvignon Blanc", "Sémillon"],
        "score": {
          "match_percentage": 88,
          "basic_score":      9,
          "balance_score":    0,
          "aromatic_score":   9
        },
        "priceSegment": "top",
        "whyText": "Sauvignon Blanc's herbaceous intensity amplifies dill's anise notes while Sémillon's waxy texture matches salmon's richness."
      },
      {
        "metaWineId": 1034,
        "name": "Arinto and Fernão Pires Portugal Basic",
        "type":   { "id": 4, "name": "White dry", "color": "white" },
        "region": "Portugal",
        "grapes": ["Arinto", "Fernão Pires", "Sauvignon Blanc", "Viognier"],
        "score": {
          "match_percentage": 88,
          "basic_score":      9,
          "balance_score":    0,
          "aromatic_score":   9
        },
        "priceSegment": "basic"
      }
    ]
  },
  "meta": {
    "tier": "pro",
    "calls_remaining_today": 4998,
    "rate_limit_reset": "2026-04-17T00:00:00.000Z"
  }
}

What you get back. Up to 25 wine styles ranked by match_percentage, filtered to a minimum of 65/100. Each result includes the wine’s name, color, region, grapes, a price segment hint (basic / middle / top), and on PRO tier a one-sentence whyText explaining the match.


Example B — Pair to a meal in our catalog

If you already have a meal ID from GET /meals or GET /search, skip the natural-language step.

curl -X POST https://api.sommelierx.com/api/v1/pairing/by-meal/5572 \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "language": "en" }'

Response (meal 5572 = “Salmon sashimi”, top result shown):

{
  "data": {
    "mealId": 5572,
    "results": [
      {
        "metaWineId": 790,
        "name": "Chardonnay Southern Europe Middle",
        "type":   { "id": 4, "name": "White dry", "color": "white" },
        "region": "Southern Europe",
        "grapes": ["Chardonnay"],
        "glassType": { "id": 4, "name": "Burgundy White" },
        "score": {
          "match_percentage": 87,
          "basic_score":      9,
          "balance_score":    0,
          "aromatic_score":   9
        },
        "priceSegment": "middle",
        "whyText": "Southern Europe's warm-climate Chardonnay's mineral backbone amplifies the salmon's natural oils while respecting its pristine texture."
      }
    ]
  },
  "meta": {
    "tier": "pro",
    "calls_remaining_today": 4997,
    "rate_limit_reset": "2026-04-17T00:00:00.000Z"
  }
}

Example C — One wine across three courses PRO

Dinner party with a chicken starter, a vegetable main, and a steak? /pairing/group finds wines that score well across every meal, not just the average.

curl -X POST https://api.sommelierx.com/api/v1/pairing/group \
  -H "Authorization: Bearer $SOMMELIERX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mealIds": [4329, 4330, 4331],
    "language": "en"
  }'

Response (top wine shown):

{
  "data": {
    "meals": [
      { "id": 4329, "name": "Fried chicken with beurre blanc and leaf spinach" },
      { "id": 4330, "name": "Puff pastry tartlet with vegetables" },
      { "id": 4331, "name": "Fried Angus rib-eye with Café de Paris" }
    ],
    "wines": [
      {
        "metaWineId": 1152,
        "name": "Bobal Spain Basic",
        "type":   { "id": 10, "name": "Red dry", "color": "red" },
        "region": "Spain",
        "priceSegment": "basic",
        "avgScore":     75,
        "mealCoverage": 3,
        "totalMeals":   3,
        "perMealScores": [
          { "mealId": 4329, "mealName": "Fried chicken with beurre blanc and leaf spinach", "score": 74 },
          { "mealId": 4330, "mealName": "Puff pastry tartlet with vegetables",              "score": 75 },
          { "mealId": 4331, "mealName": "Fried Angus rib-eye with Café de Paris",           "score": 75 }
        ]
      }
    ]
  },
  "meta": {
    "tier": "pro",
    "calls_remaining_today": 4992,
    "rate_limit_reset": "2026-04-17T00:00:00.000Z"
  }
}

Read this carefully. mealCoverage = how many of the supplied meals scored above the threshold. avgScore = average across covered meals. A wine with mealCoverage: 2 may have a higher average than one with mealCoverage: 3 — sort by whichever matters more for your use case.

4

Understand the score

Every pairing returns a score object. On FREE tier you get match_percentage only. STARTER, PRO and ENTERPRISE also expose the three components that produced it.

match_percentage

integer 0–100

The headline number. Anything below 65 is filtered out. 80+ is a confident pairing; 90+ is exceptional.

basic_score

integer 0–10

Body, structure, and weight match. Does the wine have enough density to stand up to the dish without overwhelming it?

balance_score

integer (penalty)

Tannin/acid/sweetness clash penalty. Positive values reduce the final score by 0.5x; negative values reduce it by 1x. Lower (or zero) is better.

aromatic_score

integer 0–10 or null

Flavor-profile resonance — herbal, fruit, smoke, mineral. null means the algorithm didn’t use aromatic data for this pairing.

How they combine.

// 1. Average the basic and aromatic scores (or use basic only if aromatic is null)
final = aromatic_score !== null
  ? (basic_score + aromatic_score) / 2
  : basic_score

// 2. Apply the balance penalty
final = balance_score > 0
  ? final - (0.5 * balance_score)
  : final - (-1 * balance_score)

// 3. Scale to 0-100
match_percentage = Math.ceil(final * 10)
Why some wines score 0 on balance. balance_score: 0 means no clash — the wine’s tannin, acidity, and sweetness all sit comfortably with the dish. That’s a good thing: the final match is the average of basic and aromatic, with no penalty.
5

Use it in Claude Desktop, Cursor, or Windsurf

If you don’t want to write code, drop the SommelierX MCP server into any MCP-compatible client and ask in plain English.

Add this to your client’s MCP config (e.g. Claude Desktop’s claude_desktop_config.json):

{
  "mcpServers": {
    "sommelierx": {
      "command": "npx",
      "args": ["@sommelierx/mcp-server"],
      "env": {
        "SOMMELIERX_API_KEY": "sk_live_..."
      }
    }
  }
}

Restart your client and ask things like:

  • “What wine pairs with grilled lamb and rosemary?”
  • “I have a Barolo. What should I cook?”
  • “Suggest one wine for a three-course dinner: oysters, duck, chocolate cake.”

The SOMMELIERX_API_KEY env var is optional — without it you get the same FREE tier limits, just keyed to your IP.

What’s next

Errors you may hit

StatusCodeWhat it means
401API_KEY_MISSINGNo Authorization header. Pass Bearer sk_live_....
401API_KEY_INVALIDKey is malformed or doesn’t exist. Check for stray whitespace.
403TIER_REQUIREDYou called a PRO endpoint on a FREE key. The response includes upgrade_url.
429RATE_LIMIT_DAILYDaily quota exhausted. The X-RateLimit-Reset header tells you when it resets.
429RATE_LIMIT_MINUTEPer-minute burst exceeded (60/min FREE, 300/min STARTER, 1,200/min PRO, 3,000/min ENTERPRISE). Add a Retry-After backoff.
400INVALID_INPUTValidation failed. The details array lists the offending fields.

Ready to build?

Free key in under a minute. No credit card. 100 calls per day to start.