# Vivino Wine Ratings & Tasting Profile Scraper (`dataspryva/vivino-wine-ratings-and-tasting-profile-scraper`) Actor

Search Vivino wines by name, browse by type and country, look up specific vintages by ID, or pull a winery's full catalogue. Get ratings, prices, grapes, tasting notes, and food pairings for each wine.

- **URL**: https://apify.com/dataspryva/vivino-wine-ratings-and-tasting-profile-scraper.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 & Tasting Profile Scraper

Vivino is the world's largest wine community, with ratings, reviews and tasting notes for millions of bottles. This actor turns that catalogue into clean, structured records: search by name, browse by type, country, region or grape, look up exact wines by URL or ID, or page through a producer's full range.

### What this actor does

- Runs one or more free-text searches across wines, wineries, regions and grape varieties.
- Browses the catalogue with filters for wine type, country of origin, region/appellation, grape, rating range and price range.
- Accepts Vivino wine and vintage URLs as well as numeric IDs.
- Pulls a winery's catalogue, one record per wine (up to 5,000 wines per winery).
- Returns one enriched record per wine vintage in search, explore and by-ID modes, and one record per wine in winery mode, with ratings, taste profile, alcohol, description, critic scores, awards, rankings, market prices and merchant offers.
- Optionally attaches the latest community reviews.
- Omits fields Vivino does not have for a wine instead of sending empty values.

### Output per wine

**Identity and place**

- `wineId`, `vintageId` — Vivino identifiers for the wine and this vintage
- `name`, `fullName` — wine name and the full vintage name with winery and year
- `vintage` — harvest year; omitted for non-vintage wines, with `isNonVintage: true`
- `winery`, `wineryId`, `wineryUrl`
- `type`, `typeId`, `isNatural`
- `region`, `regionId`, `regionUrl`, `country`, `countryCode`
- `style`, `styleId`, `styleDescription`, `styleBlurb`, `interestingFacts`

**Taste and pairing**

- `grapes`, `grapeComposition`
- `foodPairing`
- `tasteAcidity`, `tasteTannin`, `tasteSweetness`, `tasteIntensity`, `tasteFizziness` — Vivino's 1–5 taste scores, present only for the traits it scores for that wine
- `tastingNotes` — flattened flavour keywords
- `flavorGroups` — flavour groups with counts and keyword mentions
- `body`, `bodyDescription`, `acidity`, `acidityDescription`

**Ratings and reviews**

- `rating`, `ratingsCount`, `ratingStatus` — the vintage's own rating, count and status; `rating` is present only when Vivino publishes a vintage average
- `displayRating`, `displayRatingScope` — the vintage rating, or the wine's all-vintage rating when the vintage is below Vivino's publication threshold
- `wineRating`, `wineRatingsCount` — the wine's all-vintage rating
- `reviewsCount`, `labelsCount`, `ratingsDistribution`
- `reviews` — optional latest community reviews, with rating, text, language, date, reviewer and the review's vintage year; `reviewsScope` is `wine` because Vivino exposes reviews at wine level

**Description and chemistry**

- `description` — wine-specific description
- `alcohol` — ABV percentage
- `closure`, `winemaker`

**Market**

- `price` — best current merchant offer
- `averagePrice` — Vivino's market median
- `currency`, `priceStatus`
- `offerCount`, `offers` — up to five offers with merchant, price, currency, URL, bottle type, volume and stock
- `bottleType`, `bottleVolumeMl`, `discountPercent`

**Critics and standing**

- `criticReviews` — critic name, score, score scale and date
- `awards` — competition, edition, medal, trophy, score and link
- `rankings` — global, country, region and winery rank with totals
- `topListRankings`, `drinkingWindow`

**Media and metadata**

- `imageUrl`, `labelImageUrl`, `bottleImageUrl`
- `wineUrl`, `vintageUrl`, `sourceUrl` — canonical Vivino URLs
- `recordType` (`wine`) and `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search`, `explore`, `byWineId` or `winery` |
| `searchQueries` | array | `["barolo"]` | One or more wine searches for `search` mode |
| `wineIds` | array | `["171525306"]` | Wine/vintage IDs or Vivino URLs for `byWineId`; accepts plain IDs, `/w/<id>`, `/wines/<id>`, `/vintages/<id>` and full Vivino URLs |
| `winery` | string | – | Winery ID, slug or URL for `winery` mode |
| `wineType` | select | (any) | Red, White, Sparkling, Rose, Dessert or Fortified |
| `country` | select | (any) | Country of origin; 146 wine-producing countries |
| `region` | string | – | Region/appellation name, slug or Vivino region URL |
| `grape` | string | – | Grape name, slug or Vivino grape URL |
| `minRating` / `maxRating` | number | – | Rating range on Vivino's 0–5 scale |
| `minPrice` / `maxPrice` | number | – | Price range in USD |
| `orderBy` | select | `ratings_count` | `ratings_count`, `ratings_average`, `price` or `relevance` |
| `order` | select | `desc` | `desc` or `asc` |
| `includeReviews` | boolean | `false` | Attach latest community reviews |
| `maxReviewsPerWine` | integer | `10` | Reviews per wine when enabled (1–50) |
| `maxItems` | integer | `50` | Maximum wine records to return (1–2,500) |

#### Example: search for a wine

```json
{
  "mode": "search",
  "searchQueries": ["barolo", "chablis"],
  "maxItems": 20
}
```

#### Example: top-rated Italian reds under $100

```json
{
  "mode": "explore",
  "wineType": "1",
  "country": "it",
  "minRating": 4.2,
  "maxPrice": 100,
  "orderBy": "ratings_average",
  "maxItems": 100
}
```

#### Example: a region and a grape

```json
{
  "mode": "explore",
  "region": "napa-valley",
  "grape": "cabernet-sauvignon",
  "minRating": 4.0,
  "maxItems": 50
}
```

#### Example: exact wines by URL or ID

```json
{
  "mode": "byWineId",
  "wineIds": [
    "https://www.vivino.com/en/barolo-monprivato/w/1274818?year=2021",
    "171525306"
  ],
  "includeReviews": true,
  "maxReviewsPerWine": 5
}
```

#### Example: a winery catalogue

```json
{
  "mode": "winery",
  "winery": "michele-chiarlo",
  "maxItems": 50
}
```

### Use cases

- Build a wine list with ratings, taste profiles and food pairings.
- Compare prices and merchant offers for a shortlist or a region.
- Track a winery's range and its vintage ratings over time.
- Enrich an e-commerce catalogue with grapes, alcohol, descriptions and images.
- Analyse critic scores, awards and value across a region or grape.
- Power a recommendation engine with structured taste and flavour data.

### FAQ

**Is this affiliated with Vivino?**
No. This actor reads Vivino's public wine pages and is not operated by or connected to Vivino.

**Do I need a Vivino account, cookie or API key?**
No. Every mode works without logging in.

**How many wines can I get in one run?**
Up to 2,500 records per run (`maxItems` is capped at 2,500). Vivino exposes at most 50 pages of 50 results per search or explore query, so split broad queries by country, region, type or price across runs to reach more wines. Winery mode follows the producer's catalogue page by page, up to 5,000 wines.

**How do I find a wine's ID or URL?**
Open the wine on Vivino and copy its URL, or run `search`/`explore` first — each result includes `wineUrl` and `vintageId`. `wineIds` accepts full URLs, `/w/<id>`, `/vintages/<id>` and plain numeric IDs. A plain numeric ID is treated as a vintage ID first (the original behaviour); use a `/w/<id>` URL to look up a wine ID unambiguously.

**Why is `rating` missing for some wines?**
Vivino does not publish a vintage average until it has enough ratings. Use `displayRating` for a ready-to-use score and read `displayRatingScope`: `vintage` means it is this bottle's score; `wine` means it is the wine's all-vintage score. `ratingStatus` shows `BelowThreshold` when the vintage average is not published.

**Are prices always available?**
Prices and offers are for the US market and require a merchant listing. When no offer exists, `price` is omitted and `priceStatus` is `no_offer`. `averagePrice` is Vivino's market median and may be present even when no single offer is.

**Are the reviews for the vintage I selected?**
Vivino exposes reviews at wine level, not vintage level. The optional `reviews` list contains the latest reviews across the wine's vintages; each review includes its own `vintageYear`, and `reviewsScope` is `wine`.

**Why do some wines have no description, alcohol, critic score or award?**
Vivino does not have that data for every wine. Those fields are left out rather than sent as empty values. Taste traits are also conditional: for example, tannin is scored for reds and fizziness for sparkling wines.

**Can I search by grape or region instead of wine name?**
Yes. Use the `grape` and `region` filters, or put a grape/region name in `searchQueries`. Filters resolve names, slugs and Vivino URLs. A region filter matches the region you pass; to cover a broad area, run its appellations or sub-regions separately.

**How fresh is the data?**
Each run reads the current Vivino catalogue, including live ratings, prices and offers.

# Actor input Schema

## `mode` (type: `string`):

What to fetch. `search` runs one or more free-text queries; `explore` browses with filters; `byWineId` resolves wine/vintage URLs or IDs; `winery` pages through a producer's catalogue.

## `searchQueries` (type: `array`):

One or more free-text wine searches (mode=search). Searches match wine, winery, region and grape names. Example: `barolo`, `chateau petrus`, `napa valley cabernet`.

## `wineIds` (type: `array`):

Vivino wine/vintage IDs or URLs (mode=byWineId). Accepts 171525306, https://www.vivino.com/w/1167880?year=2022, /vintages/171525306 and /wines/171525306.

## `winery` (type: `string`):

Winery to scrape (mode=winery). Accepts 1945, michele-chiarlo, or a Vivino winery URL.

## `wineType` (type: `string`):

Filter by wine type. Applies to search, explore and winery.

## `country` (type: `string`):

Filter wines by country of origin (ISO 2-letter code). Leave empty for all countries.

## `region` (type: `string`):

Optional region filter, e.g. `Barolo`, `napa-valley`, or a Vivino region URL. Combine with Country when a name is ambiguous.

## `grape` (type: `string`):

Optional grape filter, e.g. `Nebbiolo`, `pinot-noir`, or a Vivino grape URL.

## `minRating` (type: `number`):

Only wines whose displayed rating is at or above this value (0-5).

## `maxRating` (type: `number`):

Only wines whose displayed rating is at or below this value (0-5). Applied after fetching.

## `minPrice` (type: `number`):

Only wines with a current offer at or above this price.

## `maxPrice` (type: `number`):

Only wines with a current offer at or below this price. Leave empty for no cap.

## `orderBy` (type: `string`):

How Vivino orders search and explore results.

## `order` (type: `string`):

Descending (highest first) or ascending (lowest first).

## `includeReviews` (type: `boolean`):

Attach the latest wine-level Vivino reviews to each record. Reviews span all vintages; each review keeps its own year.

## `maxReviewsPerWine` (type: `integer`):

How many latest reviews to attach when Include reviews is on (1-50).

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

Maximum wine records to emit. Vivino exposes at most 2,500 rows per search/explore query; split broad queries into narrower filters for more.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "barolo"
  ],
  "wineIds": [
    "171525306"
  ],
  "wineType": "",
  "country": "",
  "orderBy": "ratings_count",
  "order": "desc",
  "includeReviews": false,
  "maxReviewsPerWine": 10,
  "maxItems": 2
}
```

# Actor output Schema

## `wines` (type: `string`):

Dataset containing all scraped Vivino wine records.

# 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 = {
    "mode": "search",
    "searchQueries": [
        "barolo"
    ],
    "wineIds": [
        "171525306"
    ],
    "wineType": "",
    "country": "",
    "orderBy": "ratings_count",
    "order": "desc",
    "includeReviews": false,
    "maxReviewsPerWine": 10,
    "maxItems": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/vivino-wine-ratings-and-tasting-profile-scraper").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 = {
    "mode": "search",
    "searchQueries": ["barolo"],
    "wineIds": ["171525306"],
    "wineType": "",
    "country": "",
    "orderBy": "ratings_count",
    "order": "desc",
    "includeReviews": False,
    "maxReviewsPerWine": 10,
    "maxItems": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/vivino-wine-ratings-and-tasting-profile-scraper").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 '{
  "mode": "search",
  "searchQueries": [
    "barolo"
  ],
  "wineIds": [
    "171525306"
  ],
  "wineType": "",
  "country": "",
  "orderBy": "ratings_count",
  "order": "desc",
  "includeReviews": false,
  "maxReviewsPerWine": 10,
  "maxItems": 2
}' |
apify call dataspryva/vivino-wine-ratings-and-tasting-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/vivino-wine-ratings-and-tasting-profile-scraper"
        }
    }
}
```

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/g1kkodoLYUEZBw5Kk/builds/EKzBGehbk29hlDAtj/openapi.json
