API Documentation

Explore authentication requirements, request payloads, and response structures for every Wine Labs API endpoint.

Filter by Section

Matching

Resolve free-text wine queries into LWIN codes and Wine Labs IDs for downstream workflows.

POST/match_to_lwinMatch To LWIN

Resolve a single wine search query to LWIN codes, a Wine Labs ID and a normalized display label.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAccount identifier issued during onboarding; used for authentication and quota tracking.
querystringOptionalNoneWine name, producer, vintage, or other descriptive text to resolve. Required when `lwin` and `wl_id` are not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` and `wl_id` are not provided.
wl_idstringOptionalNoneWine Labs wine identifier. Required when `query` and `lwin` are not provided.

Response Highlights

  • `lwin7`: base 7-digit LWIN code when a match is found.
  • `lwin`: longest available LWIN including vintage or format detail.
  • `display_name`: normalized wine name suitable for customer-facing views.
  • `wl_id`: the Wine Labs ID, the canonical identifier covering 813K+ wines and spirits.
  • Returns null values for all fields when the query cannot be matched.
  • Usage limit: up to 30,000 matched rows per rolling 30 days across matching endpoints.

Wine Intelligence

Canonical wine profiles, classification, and reference data resolved from LWIN or free text.

POST/wine_infoWine Info

Retrieve canonical wine metadata including varietal, colour, and region details.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for authentication and rate limiting.
querystringOptionalNoneFree-text wine description. Required when `lwin` and `wl_id` are not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` and `wl_id` are not provided.
wl_idstringOptionalNoneWine Labs wine identifier. Required when `query` and `lwin` are not provided.

Response Highlights

  • `lwin`: resolved LWIN echoed from the resolver.
  • `result`: canonical wine profile containing name, varietal, colour, wine or spirit classification, and regional hierarchy.
  • `result.avg_beg_drink_window` / `result.avg_end_drink_window`: average drinking-window years for the resolved vintage, or null when no vintage/window is available.
  • At least one of `query`, `lwin`, or `wl_id` must be supplied.
  • Returns `result = null` when the resolver cannot map the wine to Wine Labs metadata.
POST/commodity_codesCommodity Codes

Classify wine, sparkling wine, grape must, other fermented beverages, and spirits into high-level HS and market-specific commodity code guidance.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for authentication and rate limiting.
querystringOptionalNoneFree-text product or wine description. Used with Wine Labs matching when provided.
lwinstringOptionalNoneDirect LWIN lookup for known wines.
wl_idstringOptionalNoneWine Labs wine identifier for known wines.
vintagestringOptionalNoneOptional vintage used when enriching known wine attributes.
product_type / commodity_type / hs_code_6stringOptionalNoneOptional classification hints when the product is not supplied as a known wine.
container_size_ml, abv, color, origin_country, destination_countrynumber/stringOptionalNoneOptional product attributes that improve jurisdiction-specific guidance.

Response Highlights

  • `hs_code_6`: resolved six-digit HS classification and display label.
  • `commodity_type`: Wine Labs high-level commodity category.
  • `jurisdiction_codes`: available resolved market codes, when they can be derived safely.
  • `country_code_systems[]`: market-by-market code systems, candidate patterns, and any attributes still needed for authority lookup.
  • At least one product identifier or classification hint is required.
  • Market-specific codes may be returned as candidate patterns when official authority lookup or additional product attributes are still required.

Imagery

Request cleaned bottle, front-label, and back-label assets, then track or export each delivery.

Wine Labels is self-serve at https://winelabs.ai/api/imagery-requests and uses a separate credit balance from Core, Markets, and Market Insights.

Standard fulfilled imagery costs 1 credit. A logo overlay adds 0.1 credit and a Studio background adds 0.1 credit. Processing, unavailable, and failed requests cost nothing.

Webhooks: register an HTTPS endpoint with `POST /wine_labels/webhooks` and every request that reaches `fulfilled`, `unavailable`, or `failed` is POSTed to it, so there is no need to poll `GET /wine_labels/{request_id}`. Each delivery is signed with `X-WineLabs-Signature` (`t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">` using the endpoint secret); respond with any 2xx within 10 seconds. Failed deliveries retry 8 times over about 2 days.

POST/wine_labelsRequest Wine Imagery

Request one cleaned bottle image, front label, or back label for a wine. Ready assets are returned immediately; missing assets enter the processing queue.

Branded delivery

Add a logo, a studio set, or both.

Add an overlay and/or background object to create a private finished derivative. No logo upload call is required.

"overlay": {
  "image_url": "https://cdn.example/logo.png",
  "position": "bottom_right",
  "scale": 0.2,
  "opacity": 0.95
},
"background": { "style": "luxury_studio" },
"output_size": { "width": 1600, "height": 1600 }

1 credit standard · +0.1 logo · +0.1 Studio · 0 when unavailable

YOUR LOGO
Wine bottle with a corner mark logo treatment

Corner mark

bottom_right · foreground

YOUR LOGO
Wine bottle with a diagonal watermark logo treatment

Diagonal watermark

center · 20% opacity · −24°

YOURLOGO
Wine bottle with a behind the bottle logo treatment

Behind the bottle

center · filled background layer

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.
querystringOptionalNoneFree-text wine name. At least one of `query`, `lwin`, or `wl_id` is required.
lwinstringOptionalNoneLWIN identifier. At least one of `query`, `lwin`, or `wl_id` is required.
wl_idstringOptionalNoneWine Labs wine identifier. At least one of `query`, `lwin`, or `wl_id` is required.
vintagestringOptionalNoneOptional vintage. A four-digit year is required when `vintage_treatment` is `exact`.
label_typestringOptionalbottleAsset to deliver: `bottle`, `front_label`, or `back_label`.
vintage_treatmentstringOptionalexact`exact` requires the requested year to be visible, `reusable` requires no visible vintage, and `any` accepts the best validated image.
vintage_specificbooleanOptionaltrueLegacy treatment selector used only when `vintage_treatment` is omitted. `true` maps to `exact`; `false` maps to `reusable`.
client_request_idstringOptionalNoneOptional caller-supplied identifier, up to 200 characters, for reconciling the request with your system.
overlay.image_urlstring (HTTPS URL)OptionalNonePublic HTTPS URL for your PNG or logo. Wine Labs downloads and stores a validated copy, so no upload step is required.
overlay.positionstringOptionalbottom_rightPlacement: `top_left`, `top_right`, `center`, `bottom_left`, `bottom_right`, or `custom`.
overlay.layerstringOptionalforeground`foreground` places the logo over the image; `background` places it behind a transparent bottle image.
overlay.scalenumberOptional0.2Logo width as a fraction of the output width, from `0.02` to `1`.
overlay.opacitynumberOptional1Logo opacity from `0` to `1`.
overlay.rotationnumberOptional0Clockwise rotation in degrees from `-180` to `180`.
overlay.x / overlay.ynumberOptionalNoneNormalized center coordinates from `0` to `1`; both are required when `position` is `custom`.
background.stylestringOptionalNoneOptional bottle-only studio set: `luxury_studio` (warm beige), `limestone_studio`, or `rose_studio`. May be combined with a foreground logo.
output_size.width / output_size.heightintegerOptionalNoneExact output canvas in pixels. Each side must be 256–4096 px and the canvas at most 16 million pixels. Content is fitted without stretching; for example, `{ "width": 1600, "height": 1600 }`.

Response Highlights

  • `request.status`: `fulfilled`, `processing`, `unavailable`, or `failed`.
  • `request.asset_url`: canonical download URL when fulfilled.
  • `request.status_url`: API route for refreshing this request.
  • `credits`: Imagery delivery credits included, used, and remaining.
  • `dashboard_url`: signed-in request dashboard at `https://winelabs.ai/api/imagery-requests`.
  • The canonical `asset_url` is a time-limited signed URL with a hash-only object path, for example `/winelabs/cleaned-labels/hash/bf3f78c66e58.png`.
  • Refresh an expired signed URL by listing requests or fetching the request again. Do not construct delivery URLs from wine names or slugs.
  • `asset_payload` preserves source and processing metadata; use `asset_url` for delivery.
  • A standard fulfilled request uses 1 Imagery delivery credit. `overlay` adds 0.1 credit and `background` adds 0.1 credit, so using both costs 1.2 credits.
  • Custom output sizes do not add to the credit cost.
  • Branded output is a request-specific derivative. The canonical Wine Labs image is never modified.
GET/wine_labelsList Imagery Requests

List imagery requests for the authorized account, with optional status filtering and pagination.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.
statusstringOptionalNoneFilter by `processing`, `fulfilled`, `unavailable`, or `failed`.
limitintegerOptional50Page size (1-100).
offsetintegerOptional0Pagination offset (>= 0).

Response Highlights

  • `requests[]`: request records in newest-first order.
  • `credits`: current Imagery delivery-credit balance.
  • `total`, `limit`, and `offset`: pagination metadata.
  • Fulfilled records return the canonical hash-only signed URL in `request.asset_url`.
  • Use the dashboard at `https://winelabs.ai/api/imagery-requests` to upload a CSV and review the same queue visually.
GET/wine_labels/exportExport Fulfilled Imagery

Download all fulfilled imagery requests for the authorized account as a CSV file.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.

Response Highlights

  • CSV columns: `wine_display_name`, `vintage`, `label_type`, and `download_url`.
  • `download_url`: canonical time-limited signed URL with a hash-only object path.
  • Only fulfilled requests with a delivered asset are included.
  • Call the export route again whenever signed download URLs need to be refreshed.
GET/wine_labels/{request_id}Get Imagery Request

Fetch the latest status and delivery URL for one imagery request owned by the authorized account.

Path Parameters

FieldTypeRequiredDefaultDescription
request_idstring (UUID)RequiredNoneImagery request identifier returned by `POST /wine_labels`.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.

Response Highlights

  • `request`: current status, resolved wine identifiers, requested treatment, charge state, and timestamps.
  • `request.asset_url`: canonical hash-only signed download URL when fulfilled.
  • `credits`: current Imagery delivery-credit balance.
  • Returns 404 when the request does not exist or does not belong to the authorized account.
POST/wine_labels/webhooksRegister Imagery Webhook

Register an HTTPS endpoint that receives a signed POST whenever one of your imagery requests reaches a terminal status. The signing secret is returned once, in this response only.

Integration guide

Never poll for imagery again.

Give us an HTTPS URL once and we POST the finished request object to it, signed with your secret, with retries. Four steps, then it runs itself.

  1. 1

    Register your endpoint once

    The response includes a secret starting with whsec_. Store it: it is shown only once. Public HTTPS URLs only. You can also register from the imagery dashboard, which has a “Send test” button.

    curl -X POST https://external-api.wine-labs.com/wine_labels/webhooks \
      -H "Authorization: Bearer <your api key>" \
      -H "Content-Type: application/json" \
      -d '{"url": "https://your-app.com/hooks/wine-labs", "description": "production"}'
  2. 2

    Submit requests as usual

    POST /wine_labels returns status: "processing" for anything not already in our library. Pass a client_request_id (your SKU, row id, anything) so you can match the notification back to your own record.

  3. 3

    Receive the notification

    When the request becomes fulfilled, unavailable, or failed, we POST one event to your URL. data.request is exactly what GET /wine_labels/{request_id} returns, so existing parsing code works unchanged. Download asset_url promptly, or fetch status_url for a fresh link.

    {
      "id": "076142f5-6ecb-4fa6-a3e4-1689283eb8f9",
      "event": "wine_label.fulfilled",
      "created_at": "2026-09-15T21:10:32Z",
      "attempt": 1,
      "data": {
        "request": {
          "id": "e40a2be1-07c4-4cc6-98ad-44a44a841d48",
          "client_request_id": "sku-12345",
          "status": "fulfilled",
          "wine_name": "Opus One",
          "vintage": "2019",
          "label_type": "bottle",
          "asset_url": "https://…signed download link, valid 7 days…",
          "status_url": "https://external-api.wine-labs.com/wine_labels/e40a2be1-…",
          "charged": true,
          "error_details": null
        }
      }
    }
  4. 4

    Verify it came from us

    Every delivery carries X-WineLabs-Signature: t=<unix seconds>,v1=<hex>. Compute HMAC-SHA256 with your secret over "<t>.<raw body>" and compare in constant time. Use the raw request bytes, not re-serialised JSON.

    Python

    import hmac, hashlib, time
    
    def verify(secret: str, header: str, raw_body: bytes) -> bool:
        parts = dict(p.split("=", 1) for p in header.split(","))
        if abs(time.time() - int(parts["t"])) > 300:
            return False
        message = f"{parts['t']}.".encode() + raw_body
        expected = hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
        return hmac.compare_digest(expected, parts["v1"])
    
    # header = request.headers["X-WineLabs-Signature"]
    # raw_body = the request body bytes, exactly as received

    Node

    import { createHmac, timingSafeEqual } from "node:crypto";
    
    export function verify(secret: string, header: string, rawBody: Buffer): boolean {
      const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
      if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
      const expected = createHmac("sha256", secret)
        .update(`${parts.t}.`)
        .update(rawBody)
        .digest("hex");
      return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
    }

Behaviour to know about

  • Respond with any 2xx within 10 seconds. Acknowledge first, then do the heavy work.
  • No 2xx means we retry 8 times over about 2 days (1m, 5m, 15m, 1h, 3h, 6h, 12h, 24h). Deliveries can arrive out of order or more than once, so treat them as idempotent on data.request.id.
  • If an image is later replaced after quality review, you get a new wine_label.fulfilled for the same request id with the new asset_url.
  • 30 consecutive failures pause the endpoint. GET /wine_labels/webhooks shows active, last_error, and failure counts. Re-register the URL to resume.
  • GET /wine_labels/webhooks/{endpoint_id}/deliveries lists recent deliveries with attempt counts and the last response, for debugging.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.
urlstringRequiredNonePublic HTTPS URL. Private, loopback, and link-local destinations are rejected. Redirects are not followed.
descriptionstringOptionalNoneFree-text label for your own reference (max 200 characters).
eventsstring[]OptionalallSubset of `wine_label.fulfilled`, `wine_label.unavailable`, `wine_label.failed`. Defaults to all three.

Response Highlights

  • `endpoint`: the registered endpoint (`id`, `url`, `events`, `active`, `secret_hint`, delivery health timestamps).
  • `secret`: the `whsec_…` signing secret. Store it now; it is never returned again.
  • `signing`: how the signature header is computed.
  • Delivery body: `{ "id", "event", "created_at", "attempt", "data": { "request": { … } } }` where `data.request` is exactly the `request` object from `GET /wine_labels/{request_id}`, with an absolute `status_url`.
  • Delivery headers: `X-WineLabs-Event`, `X-WineLabs-Delivery-Id`, `X-WineLabs-Timestamp`, `X-WineLabs-Signature`.
  • Verify the signature: split `X-WineLabs-Signature` into `t` and `v1`, compute HMAC-SHA256 over `"<t>.<raw body>"` with the secret, compare in constant time to `v1`, and reject timestamps older than 5 minutes.
  • Respond with any 2xx within 10 seconds; queue heavy work. Non-2xx, redirects, and timeouts are retried with backoff (1m, 5m, 15m, 1h, 3h, 6h, 12h, 24h) and abandoned after 8 attempts.
  • A request that is re-queued and re-delivered later (for example after an asset is withdrawn and replaced) sends a new `wine_label.fulfilled` event with the new `asset_url`. Use `data.request.id` and `data.request.client_request_id` to correlate.
  • An endpoint that fails 30 deliveries in a row is switched off (`active: false`); fix it and register the URL again.
  • Returns 409 when the URL is already registered or the account already has 5 active endpoints.
GET/wine_labels/webhooksList Imagery Webhooks

List the active webhook endpoints on the authorized account with their delivery health.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.

Response Highlights

  • `endpoints`: each with `id`, `url`, `description`, `events`, `active`, `secret_hint`, `consecutive_failures`, `last_success_at`, `last_failure_at`, `last_error`.
  • `max_endpoints` and `events`: the account limit and the event names that can be subscribed to.
POST/wine_labels/webhooks/{endpoint_id}/testTest Imagery Webhook

Send a signed `wine_label.test` event to one endpoint right now and report whether it accepted it.

Path Parameters

FieldTypeRequiredDefaultDescription
endpoint_idstring (UUID)RequiredNoneEndpoint identifier returned by `POST /wine_labels/webhooks`.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.

Response Highlights

  • `ok`: true when the endpoint answered 2xx.
  • `status_code` and `error`: what the endpoint returned, for debugging.
  • Test events are not recorded in the delivery log and do not affect endpoint health.
GET/wine_labels/webhooks/{endpoint_id}/deliveriesList Webhook Deliveries

Recent deliveries to one endpoint: pending, delivered, or failed, with attempt counts and the last response.

Path Parameters

FieldTypeRequiredDefaultDescription
endpoint_idstring (UUID)RequiredNoneEndpoint identifier.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.
limitintegerOptional50Page size (1–100).
offsetintegerOptional0Pagination offset.

Response Highlights

  • `deliveries`: each with `id`, `request_id`, `event`, `status`, `attempts`, `next_attempt_at`, `last_response_status`, `last_error`, `delivered_at`.
DELETE/wine_labels/webhooks/{endpoint_id}Delete Imagery Webhook

Stop sending to an endpoint. Pending deliveries to it are dropped; the delivery history stays readable.

Path Parameters

FieldTypeRequiredDefaultDescription
endpoint_idstring (UUID)RequiredNoneEndpoint identifier.

Query Parameters

FieldTypeRequiredDefaultDescription
user_idstring (UUID)OptionalNoneAccount identifier. Optional when the request uses an authorized `Authorization` header.

Response Highlights

  • `deleted`: true.
  • `endpoint_id`: the endpoint that was removed.
  • Registering the same URL again issues a new secret.

Market Data

Pricing snapshots and merchant availability for resolved wines.

POST/price_statsPrice Stats

Retrieve the latest aggregated pricing statistics for a wine in a target region.

Request Body

FieldTypeRequiredDefaultDescription
querystringOptionalNoneFree-text wine description. Required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` is not provided.
regionstringOptionalworldTarget region alias. Supported values: world, europe, north america, south america, africa, asia, oceania.
currencystringOptionalUSDOptional output currency (uppercased) used for price conversion.
user_idstring (UUID)RequiredNoneAccount identifier issued during onboarding; used for authentication and quota tracking.

Response Highlights

  • `vintage`: vintage tied to the returned snapshot.
  • `region`: normalized region label from the request.
  • `lwin`: resolved LWIN when present.
  • `results[]`: array of pricing metrics (created_at, date, median_value, min, p25, p75, max, count, count_outliers, winelabs_price).
  • Returns an empty `results` array when no recent pricing is available for the selected wine and region.
  • Usage limit: up to 150,000 requests per rolling 30 days across Market Data endpoints.
POST/historical_price_statsHistorical Price Stats

Retrieve the historical time series of aggregated pricing statistics for a wine — one row per date (roughly the last 14 months) instead of the single latest snapshot returned by `/price_stats`.

Request Body

FieldTypeRequiredDefaultDescription
querystringOptionalNoneFree-text wine description. Required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` is not provided.
regionstringOptionalworldTarget region alias. Supported values: world, europe, north america, south america, africa, asia, oceania.
currencystringOptionalUSDOptional output currency (uppercased) used for price conversion.
user_idstring (UUID)RequiredNoneAccount identifier issued during onboarding; used for authentication and quota tracking.

Response Highlights

  • `vintage`: vintage tied to the returned series.
  • `region`: normalized region label from the request.
  • `lwin`: resolved LWIN when present.
  • `results[]`: time series ordered by date — one entry per date (created_at, date, median_value, average, min, p25, p75, max, count, count_outliers, winelabs_price), covering roughly the last 14 months.
  • Same request shape as `/price_stats`; `/price_stats` returns the latest snapshot while `/historical_price_stats` returns the full dated history.
  • Returns an empty `results` array when no historical pricing is available for the selected wine and region.
  • Usage limit: up to 150,000 requests per rolling 30 days across Market Data endpoints.
POST/listingsListings

Retrieve active merchant offers with optional geography and packaging filters.

Request Body

FieldTypeRequiredDefaultDescription
querystringOptionalNoneFree-text wine description. Required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` is not provided.
user_idstring (UUID)RequiredNoneAccount identifier issued during onboarding; used for authentication and quota tracking.
currencystringOptionalUSDISO currency code used for price conversion.
regionstringOptionalworldContinent-level geography filter. Supported values: world, europe, north america, south america, africa, asia, oceania, australia (alias for oceania). Maps to a continent filter when explicit `continents` / `countries` are not provided.
only_trusted_merchantsbooleanOptionalfalseFilter to merchants designated as trusted partners.
continentsarray<string>Optional[]Restrict listings to the provided continents.
countriesarray<string>Optional[]Restrict listings to the provided countries. Accepts full names (e.g. "France") or ISO alpha-2/alpha-3 codes (e.g. "FR", "FRA"). Note: use "UK" or "GB" for the United Kingdom.
standardized_formatsarray<string>Optional[]Filter by internal format labels (alias: `formats`). Allowed values: bottle, half-bottle, magnum, double-magnum.
vintagesarray<string>Optional[]Filter to specific vintages.
min_offer_volumenumberOptionalNoneMinimum pack size filter (1–99). When absent and an 18-digit LWIN is provided, inferred from the LWIN case-size segment.
max_offer_volumenumberOptionalNoneMaximum pack size filter (1–99). When absent and an 18-digit LWIN is provided, inferred from the LWIN case-size segment.
limitnumberOptional20Page size (1–20).
offsetnumberOptional0Pagination offset (>= 0).

Response Highlights

  • `lwin`: resolved LWIN used for the search.
  • `limit`, `offset`, `count`, `has_more`: pagination metadata.
  • `results[]`: array of merchant offers including pricing, merchant contact details, formats, and analytics flags.
  • Either `query` or `lwin` must be supplied.
  • Extended LWINs auto-infer filters when explicit values are absent: 16+ digits can set `standardized_formats`; 18 digits can set `min_offer_volume` / `max_offer_volume`.
  • Use `has_more` with `offset` to iterate through additional listings.
  • Usage limit: up to 150,000 requests per rolling 30 days across Market Data endpoints.
POST/pricing_flow_pricePricing Flow Price

Execute your configured pricing flow (lowest priority when unspecified) using existing authorizations and credits; configure flows via Pricing Flow Builder.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier for pricing flows.
querystringOptionalNoneFree-text wine description; required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup; required when `query` is not provided.
vintagestringOptionalNoneOptional vintage to guide resolution and routing.
formatstringOptionalNoneBottle format hint used to route pricing logic.
conditionstringOptionalNoneBottle condition hint forwarded to the flow.
pack_sizenumberOptionalNonePack size (alias `packSize`) used for packaging adjustments.
currencystringOptionalUSDTarget currency for FX conversion; does not filter pricing sources.
flow_idstringOptionalNoneSpecific pricing flow to run; defaults to the lowest-priority flow when omitted.

Response Highlights

  • `flow_id`: pricing flow identifier executed for the request.
  • `price`, `bottle_price`, `adjusted_price`, `currency`: returned pricing with packaging adjustments when applicable.
  • `data_source`, `aggregation`: source and aggregation used to derive the price.
  • `applied_modifiers`, `path`: modifiers and routing path applied within the flow.
  • `resolved_lwin`, `resolved_vintage`: resolved wine context.
  • `confidence_score`, `record_count`: diagnostics for the derived price.
  • `format_detected`, `case_size_detected`: detected packaging cues from the request.
  • `trace`: per-node execution details including router matches and intermediate prices.
  • Provide either `query` or `lwin` to resolve the wine; flows return 404 when no wine or price can be derived.
  • Currency input only converts returned values; it never filters underlying records.
  • When `flow_id` is provided that specific flow is used; otherwise the user's lowest-priority pricing flow runs.
POST/shop_detailsShop Details

Retrieve detailed information about a retailer/shop by ID, or search for shops by name.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for authentication and rate limiting.
retailer_idnumberOptionalNoneThe retailer ID to look up. Required when not using search mode.
querystringOptionalNoneSearch query for shop names (minimum 3 characters). When provided, activates search mode.
limitnumberOptional10Maximum results returned in search mode.
offsetnumberOptional0Pagination offset for search mode.

Response Highlights

  • `retailer_id`: unique retailer identifier.
  • `shop_type`: type of shop (merchant, grocery, wine_shop).
  • `shop_name`: name of the shop/retailer.
  • `shop_country`: country where the shop is located.
  • `shop_state`: state/region where the shop is located.
  • `offers_count`: number of wine offers available from this retailer.
  • `shop_price_rating`: price competitiveness rating (higher = better prices).
  • `shop_diversity_rating`: inventory diversity rating (higher = more diverse selection).
  • In search mode: returns `results[]` array of shop details.
  • Either `retailer_id` or `query` must be provided.
POST/restaurant_detailsRestaurant Details

Find a restaurant by name and get its `restaurant_id`, or look up one restaurant by `restaurant_id`. Use the id with Restaurant Listings to pull that restaurant's wine list.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for authentication and rate limiting.
restaurant_idnumberOptionalNoneRestaurant identifier to look up. Returns one restaurant with full details. Required when `query` is not provided.
querystringOptionalNoneRestaurant name to search for (minimum 3 characters, for example `French Laundry`). Activates search mode. Required when `restaurant_id` is not provided.
citystringOptionalNoneNarrows a `query` to restaurants whose address contains this city.
statestringOptionalNoneNarrows a `query` by state or region.
countrystringOptionalNoneNarrows a `query` by country (`US`, `USA` and `United States` are treated the same).
michelin_starsnumberOptionalNoneNarrows a `query` to restaurants with exactly this many Michelin stars.
limitnumberOptional10Maximum results returned in search mode (1-20).
offsetnumberOptional0Pagination offset for search mode (0-200).

Response Highlights

  • Search mode returns `results[]`, each with only:
  • `restaurant_id`: identifier to pass to Restaurant Listings or back to this endpoint.
  • `restaurant_address`: address, to tell restaurants with the same name apart.
  • `has_wine_list`: whether Wine Labs holds a wine list for this restaurant.
  • Lookup by `restaurant_id` returns one object with `restaurant_id`, `restaurant_name`, `restaurant_address`, `restaurant_country`, `restaurant_state`, `restaurant_phone`, `restaurant_website`, `restaurant_lat`, `restaurant_lng`, `offers_count`, `michelin_stars`, `has_wine_list`, `winelist_last_checked_at`.
  • Either `restaurant_id` or `query` must be provided. `city`, `state`, `country` and `michelin_stars` only narrow a `query`; they cannot be used on their own.
  • Search results are ordered by the number of wine list offers we hold, then Michelin stars, then name.
  • Uses the general details rate limits (a fraction of your market data quota).
POST/restaurant_listingsRestaurant Listings

Restaurant wine list offers, scoped to one restaurant (`restaurant_id`), one wine (`lwin` or `wl_id`), or a geography (city, state, or coordinates), with optional distance sorting from a coordinate pair.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for authentication and rate limiting.
restaurant_idnumberOptionalNoneReturn the wine list of one restaurant. Get the id from Restaurant Details. Sufficient on its own.
lwinstringOptionalNoneLWIN of one wine. Returns the restaurants that list that wine. An LWIN11 also filters the vintage. Sufficient on its own.
wl_idstringOptionalNoneWine Labs wine identifier. Same behaviour as `lwin`. Sufficient on its own.
citystringOptionalNoneCity name used to match restaurant addresses (for example, `New York` or `Paris`).
statestringOptionalNoneState filter for restaurant location. Accepts a 2-letter abbreviation or recognized full state name (for example, `CA` or `California`).
latnumberOptionalNoneLatitude of the search origin point. Must be provided together with `lng`.
lngnumberOptionalNoneLongitude of the search origin point. Must be provided together with `lat`.
max_distance_milesnumberOptional50Maximum search radius in miles when `lat`/`lng` are provided.
max_resultsnumberOptional20Page size (1-20). Use `offset` to page through a longer list.
offsetnumberOptional0Pagination offset. The response sets `has_more` when another page exists.
vintagearray<string>OptionalNoneOptional vintage filter (e.g., ["2015", "2016"]).
formatarray<string>OptionalNoneOptional bottle format filter (e.g., ["750ml", "1500ml"]).
countryarray<string>OptionalNoneOptional country filter for restaurant location.
continentarray<string>OptionalNoneOptional continent filter for restaurant location.
currencystringOptionalUSDOutput currency for wine price conversion.
include_unmatchedbooleanOptionaltrueSet to `false` to drop list lines we could not match to a Wine Labs wine.

Response Highlights

  • `city`, `state`, `lat`, `lng`: echoed filters when provided.
  • `currency`: applied currency for prices.
  • `has_more`: whether another page exists at `offset + max_results`.
  • `results[]`: array of restaurant listings, each containing:
  • `restaurant_id`, `restaurant_name`, `restaurant_address`, `restaurant_country`, `restaurant_state`: restaurant identification.
  • `distance_miles`: distance from search origin when coordinates are provided.
  • `wine_name`, `wine_vintage`, `wine_price`, `wine_format`: wine listing details as printed on the list.
  • `wine_list_file_url`, `last_check_at`: the source wine list and when we last read it.
  • `is_outlier`: set when the price is far from the market for that wine.
  • Requires `markets` authorization. Uses the same rate limits as other market data endpoints.
  • At least one of `restaurant_id`, `lwin`, `wl_id`, `city`, `state`, or a full `lat`/`lng` pair is required.
  • Typical flow: call Restaurant Details with a name to get `restaurant_id`, then call this endpoint with that id.
  • `lat` and `lng` must be supplied together. When coordinates are provided, results are filtered and sorted by distance.

Auctions & Exchange

Self-serve and custom transaction datasets for auctions and exchange venues.

Auctions and exchange endpoints are available on self-serve plans, with custom access available for bespoke scopes, limits, and integrations.

Use the API pricing page for instant checkout, or contact us if you need a custom venue mix or higher-throughput package.

POST/auctionsAuctions

Access historical auction results from the supported self-serve auction dataset or your custom authorized scopes.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for plan-based authentication and quota tracking.
auction_provider_idsarray<number>Optional[]Filter results to specific auction providers.
querystringOptionalNoneFree-text wine description; optional when providing identifiers.
lwinstringOptionalNoneDirect LWIN filter.
vintagestringOptionalNoneVintage filter.
lot_idstringOptionalNoneInternal Wine Labs lot identifier.
auction_lot_idstringOptionalNoneProvider-specific lot identifier.
auction_idstring | numberOptionalNoneAuction event identifier.
sold_date_fromdate (YYYY-MM-DD)OptionalNoneInclusive lower bound for sold date.
sold_date_todate (YYYY-MM-DD)OptionalNoneInclusive upper bound for sold date.
limitnumberOptional10Page size (1–100).
offsetnumberOptional0Pagination offset (>= 0).
sort_bystringOptionalsold_dateSort options: sold_date, auction_date, hammer_price_usd, realised_price_usd, bottle_price_usd, auction_id.
sort_directionstringOptionaldescSort direction: asc or desc.

Response Highlights

  • `limit`, `offset`, `count`, `total_available`: pagination metadata.
  • `results[]`: auction lots with provider info, hammer prices (native and USD), bottle price, currency, and resolved wine identifiers.
  • Self-serve auction plans include the supported auction-provider dataset with no provider-level conditions applied.
  • Usage limits depend on your active auction subscription and renew each billing cycle.
  • Custom plans are available when you need bespoke scopes, limits, or integration support.
POST/exchange/orderbookExchange Orderbook

Retrieve current bids and offers from the supported self-serve exchange venues or your custom authorized sources.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for plan-based authentication and quota tracking.
querystringOptionalNoneFree-text wine description; optional when identifiers are provided.
lwinstringOptionalNoneDirect LWIN filter.
vintagestringOptionalNoneVintage filter.
sourcesarray<string>Optional[]Restrict results to specific exchange sources.
bid_askstringOptionalNoneUse "BID" or "ASK" to return only bids or asks.
formatstringOptionalNoneBottle format filter.
conditionstringOptionalNoneCondition filter.
packagingstringOptionalNonePackaging filter.
duty_codestringOptionalNoneDuty status filter (e.g., IB, DP).
currency_codestringOptionalNoneOptional target currency for FX conversion; does not filter order book rows by currency.
limitnumberOptional10Page size (1–100).
offsetnumberOptional0Pagination offset (>= 0).
sort_bystringOptionalpriceSort options: price, source, bid_ask, volume, currency_code.
sort_directionstringOptionalascSort direction: asc or desc.

Response Highlights

  • `limit`, `offset`, `count`, `total_available`: pagination metadata.
  • `results[]`: order book entries with provider identifiers, wine details, side (bid/ask), volume, price, currency, condition, packaging, duty status, and display name.
  • Currency inputs convert returned prices only; they never filter which orders are returned.
  • Self-serve exchange plans include `bordeaux_index`, `winebourse`, `cru_world_wine`, `cultx`, `cult_wines`, `vinovest`, `bbx`, and `arvest_wine`.
  • Transactions API includes auctions, exchange trades, and exchange order book under one shared allowance. All exchanges except Liv-ex are included. Legacy Exchange Endpoints subscriptions retain their original split allowances.
  • Custom plans are available if you need additional venues, custom scopes, or higher throughput.
POST/exchange/tradesExchange Trades

Retrieve historical executed trades from the supported self-serve exchange venues or your custom authorized sources.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for plan-based authentication and quota tracking.
querystringOptionalNoneFree-text wine description; optional when identifiers are provided.
lwinstringOptionalNoneDirect LWIN filter.
vintagestringOptionalNoneVintage filter.
sourcesarray<string>Optional[]Restrict results to specific exchange sources.
formatstringOptionalNoneBottle format filter.
conditionstringOptionalNoneCondition filter.
packagingstringOptionalNonePackaging filter.
duty_codestringOptionalNoneDuty status filter (e.g., IB, DP).
currency_codestringOptionalNoneOptional target currency for FX conversion; does not filter trades by currency.
traded_at_fromISO 8601 datetimeOptionalNoneInclusive lower bound for trade timestamp.
traded_at_toISO 8601 datetimeOptionalNoneInclusive upper bound for trade timestamp.
limitnumberOptional100Page size (1–100).
offsetnumberOptional0Pagination offset (>= 0).
sort_bystringOptionaltraded_atSort options: traded_at, price, source, volume.
sort_directionstringOptionaldescSort direction: asc or desc.

Response Highlights

  • `limit`, `offset`, `count`, `total_available`: pagination metadata.
  • `results[]`: executed trades with trade identifiers, provider context, wine identifiers, price, currency, volume, condition, packaging, duty status, and execution timestamp.
  • Self-serve exchange plans include `bordeaux_index`, `winebourse`, `cru_world_wine`, `cultx`, `cult_wines`, `vinovest`, `bbx`, and `arvest_wine`.
  • Transactions API includes auctions, exchange trades, and exchange order book under one shared allowance. All exchanges except Liv-ex are included. Legacy Exchange Endpoints subscriptions retain their original split allowances.
  • Use `traded_at_from` and `traded_at_to` to constrain the time horizon of results.
  • Custom plans are available if you need additional venues, custom scopes, or higher throughput.
POST/transactionsTransactions

Retrieve historical transaction data across the auction and exchange scopes available to your self-serve or custom access package.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier used for plan-based authentication and quota tracking.
auction_provider_idsarray<number>Optional[]Optional auction-provider filter for transaction feeds that include auction venues.
querystringOptionalNoneFree-text wine description; optional when identifiers are provided.
lwinstringOptionalNoneDirect LWIN filter.
lwinsarray<string>Optional[]Batch list of LWIN values when requesting multiple wines in one call.
vintagestringOptionalNoneVintage filter.
queriesarray<string>Optional[]Batch list of free-text wine queries when requesting multiple wines in one call.
sourcesarray<string>Optional[]Restrict results to specific exchange sources.
formatstringOptionalNoneBottle format filter.
conditionstringOptionalNoneCondition filter.
packagingstringOptionalNonePackaging filter.
duty_codestringOptionalNoneDuty status filter (e.g., IB, DP).
currency_codestringOptionalNoneOptional target currency for FX conversion; does not filter trades by currency.
traded_at_fromISO 8601 datetimeOptionalNoneInclusive lower bound for trade timestamp.
traded_at_toISO 8601 datetimeOptionalNoneInclusive upper bound for trade timestamp.
limitnumberOptional100Page size (1–100).
offsetnumberOptional0Pagination offset (>= 0).
sort_bystringOptionaltraded_atSort options: traded_at, price, source, volume.
sort_directionstringOptionaldescSort direction: asc or desc.

Response Highlights

  • `limit`, `offset`, `count`, `total_available`: pagination metadata.
  • `results[]`: executed trades with trade identifiers, provider context, wine identifiers, price, currency, volume, condition, packaging, duty status, and execution timestamp.
  • Transactions access follows the same self-serve and custom authorization rules as the auctions and exchange endpoints above.
  • Transactions API shares one monthly allowance across auctions, exchange trades, and exchange order book. The combined /transactions endpoint counts once per wine, without billing its internal auction and trade calls again. Batch requests count per wine. All auction houses and exchanges except Liv-ex are included.
  • Use `query`/`lwin` for a single wine request, or `queries`/`lwins` for multi-wine batch style requests.
  • Use `traded_at_from` and `traded_at_to` to constrain the time horizon of results.

Market Insights

Authorized historical pricing and alerting for market participants.

Market insights endpoints require a custom contract and explicit authorization from Wine Labs.

Contact us to configure access to specific venues, providers, and data scopes before integrating.

POST/price_historyPrice History

Return aggregated price history for a resolved wine with client-friendly caching and currency conversion.

Request Body

FieldTypeRequiredDefaultDescription
querystringOptionalNoneFree-text wine description. Required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` is not provided.
user_idstring (UUID)RequiredNoneAuthorized user identifier (accepts `user_id` or `userId`) required for market_insights access.
regionstringOptionalworldRegion alias. Supported values: world, europe, north america, south america, africa, asia, oceania, uk, united kingdom, continental europe.
vintagestringOptionalALLVintage filter; use ALL to include every vintage.
currencystringOptionalUSDOutput currency (uppercased) for price conversion.
start_datestring (YYYY-MM-DD)OptionalNoneInclusive start date filter; rejected when the format is invalid or if it is later than `end_date`.
end_datestring (YYYY-MM-DD)OptionalNoneInclusive end date filter; validated against `start_date` and forwarded to the SQL query.
limitnumberOptional10Rows per page (clamped 1–100), ordered by newest date first.
offsetnumberOptional0Pagination offset (>= 0).

Response Highlights

  • `history[]`: reverse-chronological price history data with converted prices.
  • `regions`: static list of available region aliases for selection.
  • Requires market_insights authorization plus either `query` or `lwin`; unresolved wines return 404.
  • `start_date`/`end_date` are parsed and logged with the request metadata, and rejected when invalid or when `start_date` is later than `end_date`.
POST/trade_signalsTrade Signals

Return price movement alerts for a wine with optional geography, format, and change-type filters.

Request Body

FieldTypeRequiredDefaultDescription
querystringOptionalNoneFree-text wine description. Required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup. Required when `query` is not provided.
userIdstring (UUID)RequiredNoneAuthorized user identifier required for market_insights access.
regionstringOptionalworldContinent-level geography filter; overrides `continents` when provided. Supported values: world, europe, north america, south america, africa, asia, oceania.
currencystringOptionalUSDOutput currency (uppercased) for price conversion.
onlyTrustedMerchantsbooleanOptionalfalseFilter results to trusted merchants only.
continentsarray<string>OptionalNoneGeographic filter applied when `region` is not set.
countriesarray<string>OptionalNoneRestrict results to the provided countries. Accepts full names (e.g. "France") or ISO alpha-2/alpha-3 codes (e.g. "FR", "FRA"). Note: use "UK" or "GB" for the United Kingdom.
formatsarray<string>OptionalNoneStandardized format filters (e.g., bottle sizes).
vintagesarray<string>OptionalNoneFilter to specific vintages.
changeTypesarray<string>Optional["removed"]Types of changes to surface (e.g., removed, increased, decreased).
sincestringOptionalNoneLower bound timestamp for detected changes.
lastOnlybooleanOptionaltrueReturn only the latest signal per location when true.
limitnumberOptional10Rows per page (clamped 1–10).
offsetnumberOptional0Pagination offset (>= 0).
minPercentChangenumberOptional3Minimum percent change threshold; defaults to 3 when unset or non-finite.

Response Highlights

  • `data[]`: trade signal entries with merchant and location metadata.
  • Requires market_insights authorization plus either `query` or `lwin`; unresolved wines return 404.

Custom Feed

Aggregated reporting for custom uploads using existing authentication and credits.

POST/custom_feed/transactionsCustom Transactions

Fetch aggregated custom transactions using existing authentication and credits.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier for the custom feed dataset.
agg_levelstringOptionalvintageAggregation level; allowed values: vintage, format, volume.
currencystringOptionalNoneOptional target currency for FX conversion only; it does not filter the results.
page_limitnumberOptional50 (max 500)Rows per page; clamped between 1 and 500.
page_offsetnumberOptional0Pagination offset (>= 0).
querystringOptionalNoneFree-text wine description used when resolving without `lwin`.
lwinstringOptionalNoneDirect LWIN filter; optional when `query` is provided.
wine_searchstringOptionalNoneSearch string applied to stored wine names.
sort_colstringOptionalNoneOptional sort column for the aggregation.
vintagesarray<string>OptionalNoneFilter to specific vintages.
formatsarray<number>OptionalNoneFilter to bottle formats by milliliter value.
volumesarray<number>OptionalNoneFilter to specific volumes.

Response Highlights

  • `limit`, `offset`, `count`: pagination metadata echoed from the service.
  • `results[]`: aggregated custom transaction rows.
  • `results[]` fields include `id`, `created_at`, `upload_id`, `wine_name`, `vintage`, `format`, `volume`, `raw_format`, `bottle_price`, `price`, `matching_attempted`, `offer_type`, `condition`, `packaging`, `quantity`, `ordered_at`, `source_id`, `user_id`, `currency_code`, `expiration_date`, `source_name`, `email_address`.
  • Currency input converts returned prices only; it never filters the underlying custom rows.
POST/custom_feed/price_listCustom Price List

Fetch aggregated custom offers/price lists using existing authentication and credits.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier for the custom feed dataset.
agg_levelstringOptionalvintageAggregation level; allowed values: vintage, format, volume.
currencystringOptionalNoneOptional target currency for FX conversion only; it does not filter the results.
page_limitnumberOptional50 (max 500)Rows per page; clamped between 1 and 500.
page_offsetnumberOptional0Pagination offset (>= 0).
querystringOptionalNoneFree-text wine description used when resolving without `lwin`.
lwinstringOptionalNoneDirect LWIN filter; optional when `query` is provided.
wine_searchstringOptionalNoneSearch string applied to stored wine names.
sort_colstringOptionalNoneOptional sort column for the aggregation.
vintagesarray<string>OptionalNoneFilter to specific vintages.
formatsarray<number>OptionalNoneFilter to bottle formats by milliliter value.
volumesarray<number>OptionalNoneFilter to specific volumes.

Response Highlights

  • `limit`, `offset`, `count`: pagination metadata echoed from the service.
  • `results[]`: aggregated custom price list rows.
  • `results[]` fields include `id`, `created_at`, `upload_id`, `wine_name`, `vintage`, `format`, `volume`, `raw_format`, `bottle_price`, `price`, `matching_attempted`, `source_id`, `user_id`, `currency_code`, `expiration_date`, `source_name`, `email_address`.
  • Currency input converts returned prices only; it never filters the underlying custom rows.
POST/pricing_flow_pricePricing Flow Price

Execute the user’s pricing flow (lowest priority when unspecified) using existing authorizations and credits; configure flows via Pricing Flow Builder.

Request Body

FieldTypeRequiredDefaultDescription
user_idstring (UUID)RequiredNoneAuthorized user identifier for pricing flows.
querystringOptionalNoneFree-text wine description; required when `lwin` is not provided.
lwinstringOptionalNoneDirect LWIN lookup; required when `query` is not provided.
vintagestringOptionalNoneOptional vintage to guide resolution and routing.
formatstringOptionalNoneBottle format hint used to route pricing logic.
conditionstringOptionalNoneBottle condition hint forwarded to the flow.
pack_sizenumberOptionalNonePack size (alias `packSize`) used for packaging adjustments.
currencystringOptionalUSDTarget currency for FX conversion; does not filter pricing sources.
flow_idstringOptionalNoneSpecific pricing flow to run; defaults to the lowest-priority flow when omitted.

Response Highlights

  • `flow_id`: pricing flow identifier executed for the request.
  • `price`, `bottle_price`, `adjusted_price`, `currency`: returned pricing with packaging adjustments when applicable.
  • `data_source`, `aggregation`: source and aggregation used to derive the price.
  • `applied_modifiers`, `path`: modifiers and routing path applied within the flow.
  • `resolved_lwin`, `resolved_vintage`: resolved wine context.
  • `confidence_score`, `record_count`: diagnostics for the derived price.
  • `format_detected`, `case_size_detected`: detected packaging cues from the request.
  • `trace`: per-node execution details including router matches and intermediate prices.
  • Provide either `query` or `lwin` to resolve the wine; flows return 404 when no wine or price can be derived.
  • Currency input only converts returned values; it never filters underlying records.
  • When `flow_id` is provided that specific flow is used; otherwise the user’s lowest-priority pricing flow runs.