# Vivino Wine Matcher API (`pulse_hub/vivino-wine-search-api`) Actor

Match messy wine product titles to Vivino wines in bulk. Get winery, vintage, rating, reviews, grapes, ABV, price, source URL, confidence, and alternatives—pay only for successful matches.

- **URL**: https://apify.com/pulse_hub/vivino-wine-search-api.md
- **Developed by:** [Vicxyz1](https://apify.com/pulse_hub) (community)
- **Categories:** E-commerce, Developer tools
- **Stats:** 4 total users, 0 monthly users, 87.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 wine results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Vivino Wine Matcher API

Match messy retailer titles, supplier descriptions, or simple wine names to structured Vivino wine records in bulk. Each successful match returns normalized identity data, vintage, ratings, pricing, a confidence score, and alternative candidates—ready for catalog enrichment or export.

This Actor is built for **wine product entity resolution**, not broad Vivino crawling. Submit up to 500 unique queries and receive one best-match dataset row for each successful result.

### From product title to structured wine

**Input**

```text
Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L
```

**Matched output from a successful Actor run**

```json
{
  "query": "Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L",
  "normalized_query": "Tenuta Luce Brunello di Montalcino 2018",
  "status": "found",
  "match_confidence": 1,
  "name": "Luce Brunello di Montalcino",
  "winery": "Tenuta Luce",
  "year": 2018,
  "grapes": "Sangiovese",
  "alcohol": "14.9",
  "score": 4.4,
  "reviews": 584,
  "url": "https://www.vivino.com/tenuta-luce-luce-brunello-di-montalcino/w/83595?year=2018",
  "avg_price": "649.99",
  "currency": "EUR"
}
```

Values such as ratings, review counts, prices, and availability may change at the source.

### Why use this Actor?

- **Handles messy catalog titles:** removes packaging, pack-count, bottle-size, and other retail noise before matching.
- **Selects one best candidate:** ranks matches using winery, wine name, grape, and vintage evidence.
- **Shows match confidence:** use `match_confidence` to review uncertain matches before importing them.
- **Returns alternatives:** strong variant candidates are preserved in `alternatives` when available.
- **Rejects obvious non-wine products:** filters beer, cider, gift sets, and similar false positives.
- **Success-only result billing:** unmatched searches and backend errors do not create billable dataset rows.
- **No separate Vivino API key:** the Actor uses a managed backend connection.

### Best-fit use cases

- Enrich retailer, distributor, marketplace, or restaurant wine catalogs.
- Normalize supplier feeds and inconsistent SKU descriptions.
- Add wine ratings, review counts, vintages, wineries, grapes, and source URLs.
- Flag uncertain matches for human review using confidence and alternatives.
- Schedule recurring enrichment jobs and export results as JSON, CSV, Excel, or XML.

### Input

Provide one or more wine names or product titles in `queries`:

```json
{
  "queries": [
    "Tenuta Luce Brunello di Montalcino 2018, 0.75L",
    "Morillon Blanc 2024 - Jeff Carrel",
    "Purcari Malbec"
  ]
}
```

| Field | Type | Required | Limit |
| --- | --- | --- | --- |
| `queries` | Array of unique strings | Yes | 500 per run |

For stronger matches, include the producer, full label name, and vintage when available. Broad intent queries such as `best merlot` or `cheap Italian wine` are not a good fit.

### Output fields

Successful matches are written to the default dataset.

| Field | Meaning |
| --- | --- |
| `query` | Original submitted product title or wine name. |
| `normalized_query` | Cleaned query used by the matching engine. |
| `status` | `found` for billable dataset records. |
| `match_confidence` | Approximate matching confidence from 0 to 1; review lower-confidence matches. |
| `matched_at` | UTC time when the match row was prepared. |
| `name`, `winery`, `year` | Matched wine identity and vintage. |
| `type`, `color` | Source-provided numeric identifiers when available. |
| `grapes`, `alcohol` | Source-provided grape/blend and ABV values. |
| `score`, `reviews` | Community rating and associated review/rating volume when available. |
| `url` | Matched Vivino source page. |
| `avg_price`, `currency` | Source/store price and ISO currency when available; otherwise `null`. |
| `alternatives` | Strong alternative variants and their match evidence when available. |

Source coverage varies by wine and market. Missing fields are returned as `null` or omitted; important matches should be reviewed before production pricing, inventory, or compliance decisions.

### Run it through the Apify API

Replace `YOUR_APIFY_TOKEN` with your Apify API token:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/pulse_hub~vivino-wine-search-api/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["Purcari Malbec","Tenuta Luce Brunello 2018 0.75L"]}'
```

You can also run the Actor from the Apify Console, official JavaScript/Python clients, schedules, webhooks, and integrations.

### Billing

This Actor uses Apify pay-per-event pricing:

- `Actor Start` is charged once per run at the price shown on the Pricing tab.
- `Wine result` is charged once for each successful match written to the default dataset.
- Unmatched queries and backend errors remain outside the default dataset and are not charged as Wine result events.

For example, 100 submitted queries with 83 successful matches produce 83 billable wine-result rows. The `RUN_SUMMARY` record reports totals, unmatched queries, and request errors.

### Limits and reliability

- Maximum 500 unique queries per run.
- Designed for batch enrichment rather than latency-sensitive interactive search.
- Matching and field availability depend on the source data available for each query.
- `match_confidence` is a matching heuristic, not a guarantee of product identity.

### Legal notice

This Actor is an independent data-enrichment tool and is not affiliated with, endorsed by, or sponsored by Vivino. Wine names, brands, wineries, and trademarks belong to their respective owners. Ensure that your use complies with applicable laws, marketplace requirements, and relevant source and downstream terms.

### Support

When reporting an issue, include the Actor run ID, a small sample of affected queries, and the corresponding output rows. This makes matching problems easier to reproduce.

# Actor input Schema

## `queries` (type: `array`):

Wine names, product titles, or search phrases to look up. Each item becomes one backend search request. Successful matches are written to the default dataset as billable Wine result events.

## Actor input object example

```json
{
  "queries": [
    "Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L",
    "Morillon Blanc 2024 - Jeff Carrel",
    "White Wine Tenuta Ulisse Pecorino Terre D' Abruzzo 13%, 6 x 0.75L",
    "Purcari Malbec"
  ]
}
```

# Actor output Schema

## `results` (type: `string`):

Successful wine result items produced by this run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L",
        "Morillon Blanc 2024 - Jeff Carrel",
        "White Wine Tenuta Ulisse Pecorino Terre D' Abruzzo 13%, 6 x 0.75L",
        "Purcari Malbec"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("pulse_hub/vivino-wine-search-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "queries": [
        "Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L",
        "Morillon Blanc 2024 - Jeff Carrel",
        "White Wine Tenuta Ulisse Pecorino Terre D' Abruzzo 13%, 6 x 0.75L",
        "Purcari Malbec",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("pulse_hub/vivino-wine-search-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Vin rosu sec Tenuta Luce Brunello di Montalcino 2018, 0.75L",
    "Morillon Blanc 2024 - Jeff Carrel",
    "White Wine Tenuta Ulisse Pecorino Terre D'\'' Abruzzo 13%, 6 x 0.75L",
    "Purcari Malbec"
  ]
}' |
apify call pulse_hub/vivino-wine-search-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,pulse_hub/vivino-wine-search-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/etV9iSGVNZUk92DOt/builds/sP00agtkyKcDpy6Nc/openapi.json
