# Vivino Wine Ratings Scraper (`automation-lab/vivino-wine-ratings-reviews`) Actor

Extract public Vivino vintage-level wine ratings, rating counts, review counts, and wine identity from supplied wine URLs. No search or full review text.

- **URL**: https://apify.com/automation-lab/vivino-wine-ratings-reviews.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.84 / 1,000 item extracteds

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 Ratings Scraper

Fetch **Vivino wine ratings** and review counts for supplied public wine *vintage* URLs. Each dataset row identifies one wine and vintage, its displayed aggregate rating, rating count, review count, and normalized source URL. Use the output as a snapshot for catalog reputation checks; schedule repeat runs and compare datasets in your own system to detect change.

This Actor accepts URLs, not search terms. It does not collect full reviews, discover wines by keyword, or send alerts.

### Who is it for?

Wine catalog managers can reconcile public ratings with their product listings. Merchants and analysts can compare displayed counts across vintages of an existing catalog. Data teams can export regular snapshots into a spreadsheet or warehouse and calculate their own changes over time.

### Why use a vintage-specific extractor?

A Vivino wine page can show both wine-level (all-years) and vintage-level totals. This Actor checks the requested wine ID and `year`, reads the vintage's own statistics, and rejects incomplete responses rather than silently returning all-years totals. Duplicate URLs for the same normalized vintage yield only one row.

### What does it extract?

| Field | Meaning |
| --- | --- |
| `wineId`, `vintageId` | Vivino identifiers for the wine and specific vintage |
| `wineName`, `wineryName` | Public wine and producer names |
| `vintageYear` | Requested year confirmed against the returned vintage |
| `rating` | Displayed vintage aggregate rating, or `null` if Vivino suppresses it |
| `ratingsCount`, `reviewsCount` | Vintage-specific public counts; **not** individual review records |
| `canonicalUrl` | Normalized Vivino URL retaining `?year=YYYY` |
| `scrapedAt` | UTC timestamp when this row was extracted |

### How do I get started?

1. Open a public Vivino wine vintage page and copy its URL, including `?year=YYYY`.
2. Paste one or more URLs into **Wine vintage URLs**. Set **Maximum vintages** to cap distinct rows.
3. Run the Actor and open the default dataset's **Vintage rating summaries** view.
4. Export CSV/JSON/Excel from Apify, or connect the dataset to your own catalog. To monitor changes, schedule this input to run periodically and compare saved snapshots yourself.

### Input parameters

`startUrls` is a required, nonempty list of public `vivino.com` or `www.vivino.com` wine URLs in `/en/<slug>/w/<numeric-id>?year=YYYY` format (a two-letter locale prefix is also supported). The year must be 1900–2099. Query parameters other than `year` are removed. Unsupported URLs and non-vintage pages fail validation rather than producing misleading results.

`maxItems` defaults to 10 and must be an integer from 1 to 10,000. The Actor processes at most that many **distinct supplied URLs** in input order. It does not search or paginate Vivino.

```json
{
  "startUrls": [
    {"url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024"},
    {"url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2023"}
  ],
  "maxItems": 2
}
```

### Output example

A locally observed 2024 vintage returned this shape; counts and ratings may change on Vivino:

```json
{
  "wineId": 1127731,
  "vintageId": 179467428,
  "wineName": "Lugana",
  "wineryName": "S. Cristina",
  "vintageYear": 2024,
  "rating": 4.1,
  "ratingsCount": 849,
  "reviewsCount": 182,
  "canonicalUrl": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024",
  "scrapedAt": "2026-09-27T07:44:17.274Z"
}
```

### How much does it cost to extract Vivino vintage ratings?

The Actor charges one `start` event per run and one `item` event per successfully exported vintage. Invalid or incomplete rows are not charged as items. The current one-time start fee is **$0.0045**. Per exported item the current BRONZE rate is **$0.003068**, SILVER **$0.002393**, and GOLD/PLATINUM/DIAMOND **$0.0018408**; FREE is **$0.0035282**. These are Apify monthly Store spend tiers, not volume discounts within one run. At BRONZE, a successful run with 1, 5, or 25 rows is estimated at $0.007568, $0.01984, or $0.08120 respectively (start plus item events). Actual charges depend on delivered rows and your active tier; consult the Actor's Pricing tab before scheduling. Infrastructure and any Apify plan fees are separate. Every scheduled run incurs its own start event.

### Integrations and recurring checks

Schedule an Apify Task with a stable URL list. Save each run's dataset with its timestamp, join on `wineId` and `vintageYear`, and calculate changes to `rating`, `ratingsCount`, and `reviewsCount` in your spreadsheet or database. Apify integrations or a webhook can deliver each completed dataset to your pipeline. This Actor does not store historical comparisons or notify you of changes itself.

### Call it through the Apify API

Use your own Apify API token. Replace the token variable before calling; the synchronous endpoint returns a dataset after the run finishes and may time out on large inputs.

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~vivino-wine-ratings-reviews/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"startUrls":[{"url":"https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024"}],"maxItems":1}'
```

JavaScript with `apify-client`:

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/vivino-wine-ratings-reviews').call({
  startUrls: [{ url: 'https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024' }],
  maxItems: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python with `apify-client`:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/vivino-wine-ratings-reviews').call(run_input={
    'startUrls': [{'url': 'https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024'}],
    'maxItems': 1,
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

### Use with an MCP client

Connect the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/vivino-wine-ratings-reviews"
```

Claude Desktop, Cursor, and VS Code can connect an HTTP MCP server with this configuration (use each client's HTTP MCP settings; JSON keys may differ by client):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/vivino-wine-ratings-reviews"}}}
```

Example prompts showing MCP usage:

- “Using the connected Apify MCP tool, run automation-lab/vivino-wine-ratings-reviews for https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024 and show the vintage rating and counts.”
- “Using the connected Apify MCP tool, run this Actor for my supplied 2023 and 2024 vintage URLs and compare the returned rows.”

Ask the connected client to run the Actor for specific supplied URLs, then summarize the dataset. The MCP server does not add keyword search or historical change detection.

### Limits and failure behavior

This Actor reads the publicly returned Vivino page state directly without a proxy. Vivino may change its page shape or block automated traffic; a failed or incomplete vintage stops the run with an error rather than emitting a partial summary. Temporary network errors and selected HTTP errors are retried up to three attempts. Large batches are processed sequentially and may hit the run timeout; start with small sets. A rating of `null` means Vivino has not exposed a valid aggregate for the vintage, not zero stars.

### Legality and responsible data handling

Supply only public pages you have a legitimate reason to access. Check Vivino's terms and applicable law before automated collection, particularly for large-scale or frequent runs. The Actor stores output in your run's Apify dataset under your platform retention settings. It does not need Vivino credentials or collect individual review text; do not put personal information or secrets in input URLs. The Actor does not use AI or send inputs or source content to an AI provider. It uses Apify for execution, logs, charge metering, and dataset storage; it fetches supplied public pages from Vivino. No independent long-lived cache is created. Input, output and logs remain in Apify storage under your account's retention settings; delete run storages using Apify's controls when no longer needed. This Actor is independent and is not affiliated with or endorsed by Vivino.

### Troubleshooting

**The input is rejected:** Check that each link has a numeric wine ID under `/w/` and includes the actual `?year=YYYY` query. Homepage, search, and wine URLs without a year are unsupported.

**The run fails with incomplete vintage statistics:** Verify the page displays that vintage in a normal browser. If the vintage has disappeared or Vivino changed its response, retry a known public vintage and check the run log; do not replace missing vintage counts with the all-years totals.

**Where is my CSV?** Open the run's default dataset and choose Export → CSV. Each successful row is one vintage.

### FAQ

**Does it extract individual reviews or search Vivino by keyword?** No. It exports aggregate vintage ratings and counts only for URLs supplied by you.

**Can I compare different years?** Yes: supply a separate URL for each available vintage year and join rows by `wineId`; no automatic comparison record is created.

**Are the values permanent?** No. They reflect what Vivino returned when the Actor ran; preserve historical datasets if you need change tracking.

### Related Actors

For a broader Vivino data workflow, compare this narrowly scoped URL-and-vintage summary Actor with other available products. We do not claim to provide Vivino search, full reviews, or marketplace inventory in this Actor.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/vivino-wine-ratings-reviews/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Public Vivino wine URLs with ?year=YYYY; each distinct vintage yields one summary.

## `maxItems` (type: `integer`):

Stop after this many distinct supplied vintage URLs.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024"
    }
  ],
  "maxItems": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset with wine and vintage identities and aggregate counts.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024"
        }
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/vivino-wine-ratings-reviews").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 = {
    "startUrls": [{ "url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024" }],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/vivino-wine-ratings-reviews").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 '{
  "startUrls": [
    {
      "url": "https://www.vivino.com/en/it-s-cristina-lugana-lugana-white-wine-v/w/1127731?year=2024"
    }
  ],
  "maxItems": 10
}' |
apify call automation-lab/vivino-wine-ratings-reviews --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/vivino-wine-ratings-reviews"
        }
    }
}
```

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/U2xJL54grmeBw19nM/builds/ObdGVasHxuu6hshPv/openapi.json
