Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers avatar

Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers

Pricing

from $1.20 / 1,000 wine results

Go to Apify Store
Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers

Vivino Wine Scraper $1.2💰 Ratings, Prices, Reviews & Offers

From $1.2/1K. Scrape Vivino.com for wine ratings, prices, taste profiles, food pairings, grapes, and reviews. Search by wine names or URLs, or discover wines by type, price, rating, country, and grape. Returns 50+ fields, including multi-merchant offers and value scores.

Pricing

from $1.20 / 1,000 wine results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

5

Total users

1

Monthly active users

2 days ago

Last modified

Share

Vivino Scraper: Wine Ratings, Prices and Tasting Notes

Vivino Scraper turns Vivino into structured wine data you can pull on demand. Look up wines by name or paste Vivino links, or skip the list entirely and discover wines by type, price, rating, origin country and grape with full sorting. Records carry ratings, multi merchant prices, Vivino's value and competitiveness scores where Vivino lists offers, plus a taste profile by default and optional reviews, then export to JSON, CSV or Excel, or read the results straight through the API.

Why This Scraper?

  • Two ways to find wines. Paste an exact list of names and/or Vivino URLs (one record each), or set filters and a sort order and let the actor walk the catalog for you.
  • 50+ fields per wine, including a full taste profile, multi merchant price offers, and Vivino's value and competitiveness scores.
  • Real discovery filters and sort. Wine type, minimum rating, price range, origin country and grape, sorted by rating, price, popularity or biggest discount first.
  • Enrichment on demand. Taste profile (acidity, tannins, sweetness, intensity, flavor notes) is fetched by default and can be turned off; user reviews are off by default and can be turned on. Any wine that gets either adds one combined enrichment charge, not two.
  • Market aware. Choose the pricing country and currency, and echo a ship-to country on every record.
  • Resume and recurring updates. One interrupted run resumes automatically, and Incremental mode returns only new and updated wines by default on every scheduled run.
  • Resilient connections. A refused request is retried on a different connection automatically, and repeated refusals escalate to a more reliable connection for the rest of the run, no extra setup needed.

Use Cases

  • Wine shops and marketplaces: track competitor pricing, discounts and merchant offers for the wines you carry.
  • Wine apps and recommendation engines: build a searchable catalog with ratings, taste profiles and food pairings.
  • Price and deal monitoring: schedule Incremental mode against a watch list and get only the wines whose price, rating or availability changed.
  • Sommeliers and content teams: pull tasting notes, food pairings and reviews to write wine guides and shelf talkers.
  • Market research and data science: build historical rating and pricing datasets across countries and currencies.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
wineId1234567
vintageId89012345
name"Sample Winery Reserve Red 2019"
winery"Sample Winery"
vintage2019
wine_type"Red"
region"Sample Region"
country"France"
country_code"fr"
appellation"Sample Appellation"
grape_varieties["Cabernet Sauvignon", "Merlot"]
average_rating4.3
ratings_count1200
price49.9
currency"EUR"
merchant_urlVivino checkout link for the matched merchant offer
vfm_score / vfm_category4.1 / "great" (Vivino's value-for-money score and label)
is_naturalfalse
image_url"https://images.vivino.com/thumbs/000000000_pb_x960.png"
food_pairings["Beef", "Lamb", "Game"]
descriptionStyle description text
taste_profile{ body, acidity, tannins, sweetness, fizziness, intensity, flavor_notes, flavor_groups } (when enabled)
reviews[ { rating, note, language, user_name, created_at } ] (when enabled)
prices[ { amount, currency, merchant_url, discount_percent } ], every merchant offer for this vintage
vivino_url"https://www.vivino.com/sample-winery-reserve-red/w/1234567"

Every record also carries the wine's overall, all-vintage rating separately from this vintage's rating (wine_average_rating, wine_ratings_count), the full pricing detail behind the headline price (discounted_from, discount_percent, discount_amount, is_on_sale, bottle_volume_ml), Vivino's competitiveness score and tier (cmp_score, cmp_tier), a larger label image (label_image_url), winery identity and status (winery_id, winery_seo_name, winery_status), region identity (region_id, region_name_en), style copy (style_name, body_description, acidity_description, varietal_name, regional_name, interesting_facts, blurb), Vivino's own wine rank (vivino_rank), and provenance fields describing how the row was produced rather than the wine itself (matchScore, isAlternative, requested_vintage, searchQuery, shipTo, inputSource, scrapedAt). Three fields, alcohol, lwin and lwin_canonical, are reserved for data not yet populated and are currently always empty.

How to Use

  1. Pick a Mode: lookup (exact wines by name or URL) or discovery (find wines by filter and sort).
  2. In lookup mode, list wine names and/or Vivino URLs. In discovery mode, set your filters and sort order instead.
  3. Turn on taste profile and/or reviews if you want them, set the market country and currency, and set Max wines to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Look up wines by name:

{
"mode": "lookup",
"wines": ["Opus One 2019", "Dom Pérignon", "Cloudy Bay Sauvignon Blanc"],
"countryCode": "US",
"currencyCode": "USD"
}

Look up wines by URL, with taste profile and reviews:

{
"mode": "lookup",
"wines": [
"https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978",
"https://www.vivino.com/chateau-margaux-premier-grand-cru-classe/w/1127795?year=2015"
],
"includeTasteProfile": true,
"includeReviews": true,
"maxReviewsPerWine": 20
}

Discover top rated French reds between 50 and 150, sorted by rating:

{
"mode": "discovery",
"wineTypes": ["Red"],
"originCountries": ["fr"],
"minRating": 4,
"priceMin": 50,
"priceMax": 150,
"sortBy": "rating_desc",
"countryCode": "US",
"currencyCode": "USD",
"maxItems": 50
}

Recurring monitoring of a watch list (schedule this daily):

{
"mode": "lookup",
"wines": ["https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978?year=2022"],
"incrementalMode": true,
"stateKey": "my-watchlist"
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/vivino-wine-data-scraper").call(run_input={"mode": "lookup", "wines": ["Opus One 2019"]})
for wine in client.dataset(run["defaultDatasetId"]).iterate_items():
print(wine["name"], wine["average_rating"], wine["price"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/vivino-wine-data-scraper').call({ mode: 'lookup', wines: ['Opus One 2019'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume and recurring updates

There are two different things here, pick the one that matches what you're doing:

NeedUse
A run stopped and should continueresumeFromRunId (or the automatic same-run checkpoint, no input needed)
Run the same wine list or discovery filters on a schedule and receive only changesincrementalMode
Keep separate monitoring campaigns for similar searchesdistinct stateKey values
Run a normal full snapshotleave both off

Resume (resumeFromRunId) continues one specific interrupted or previous run: paste a run ID or dataset ID and this run skips wines already collected there, returning only the remaining new ones. An automatic same-run checkpoint also protects against platform migrations, so a run that is restarted by the platform continues from where it left off with no extra input.

Incremental mode (incrementalMode) is for a schedule, for example daily: the actor remembers the previous run of the same wine list or discovery filters by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW and UPDATED wines by default; unchanged wines are suppressed and not billed. REAPPEARED only appears after an earlier run with emitExpired on and a complete scan tombstoned the wine as gone. Turn on emitUnchanged or emitExpired only when you also want those rows returned, and billed for. State is isolated per wine list, discovery filter set and enrichment setup automatically; set stateKey to name or deliberately share a monitoring campaign.

Every record returned in incremental mode also carries:

FieldDescription
changeTypeNEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED
changedFieldsTop-level fields that changed since last seen; non-empty only for UPDATED
firstSeenAtWhen this wine was first observed by this monitoring campaign
lastSeenAtWhen this wine was last observed

REAPPEARED and EXPIRED are not everyday outcomes. EXPIRED is only produced once a run has completely scanned its tracked wines or filters, meaning nothing was capped by maxItems, no resumeFromRunId was used, and every list entry or catalog page was actually reached. A capped run, a resumed run, or a run where even one wine could not be resolved leaves EXPIRED detection switched off for that run, so a wine that was merely unreachable this time is never wrongly reported as gone. REAPPEARED only follows an earlier run that genuinely marked a wine EXPIRED.

Read this before you schedule a discovery run: Vivino's answers vary per request

Vivino tailors what it returns to where the request appears to come from, and that location is not guaranteed to be identical from one run to the next. Two things follow, both measured on this actor across several back to back identical runs of a small discovery walk minutes apart:

  1. The discovery result set itself can move. Repeated identical runs can return different sets of wines.
  2. A wine that does appear on two runs can come back as a different vintage from a different merchant, reported UPDATED with changedFields naming price and identity fields together, then flip back on a later run.

So a scheduled discovery run can report, and bill, a real share of NEW and UPDATED rows every time. That is variance in what Vivino serves, not a fault in change detection: the actor is correctly reporting that the record it just received is not the record it stored.

For stable, low noise scheduled monitoring:

  • Prefer lookup mode over discovery mode. Give an explicit wine list, and ideally paste Vivino URLs carrying a ?year=, which pins the vintage and removes most of the churn above.
  • Set countryCode and currencyCode explicitly and keep them identical on every run of a campaign.
  • Choose the Residential connection option and pin its country to that same countryCode, so requests stay inside one market instead of moving between markets.
  • Read changedFields before acting on a row. A row whose changedFields names vintage, vintageId or name is a different vintage of the same wine, not a change to the wine you were watching.
  • Leave emitUnchanged off, the default, so wines that genuinely did not move are neither returned nor billed.

Send results into your apps (MCP connectors)

Optionally pipe each record into the apps you already use, through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each wine, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify, Settings, API & Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. If the picker is empty, you haven't authorized a connector yet.
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringlookuplookup: scrape the exact wines you list. discovery: find wines by filter and sort.
winesarraynone (prefill: ["Dom Pérignon", "Opus One 2019", "https://www.vivino.com/cloudy-bay-sauvignon-blanc/w/18978"])Lookup mode: mixed list of wine names and Vivino URLs, one record each.
searchModestringautoVintage handling for name lookups: auto, name_and_vintage, name_only.
matchingModestringbasicbasic takes the top match. advanced also surfaces one alternative candidate, a normal row that counts toward Max wines, gets the same enrichment, and is billed the same as any other row.
wineTypesarray[] (all types)Discovery filter: Red, White, Sparkling, Rosé, Dessert, Fortified.
minRatingintegernoneDiscovery filter: minimum Vivino average rating (1 to 5).
priceMinintegernoneDiscovery filter: lowest price in the selected currency.
priceMaxintegernoneDiscovery filter: highest price in the selected currency.
originCountriesarray[] (all)Discovery filter by wine origin, ISO alpha-2 codes, e.g. fr, it, us.
grapesarray[] (all)Discovery filter by Vivino grape IDs.
sortBystringrelevancerelevance, rating_desc, rating_asc, price_asc, price_desc, popularity, discount_desc.
countryCodestringFRMarket country for pricing and availability, ISO alpha-2.
currencyCodestringEURCurrency for prices, ISO 4217.
shipTostringnoneOptional ship-to country, echoed on each record.
includeTasteProfilebooleantrueFetch acidity, tannins, sweetness, fizziness, intensity and flavor notes (body is currently always empty).
includeReviewsbooleanfalseFetch user reviews per wine. Increases run time and cost.
maxReviewsPerWineinteger10Maximum reviews per wine when reviews are enabled (1 to 100).
maxItemsinteger20Caps the total wine records returned. Set 0 for unlimited.
maxPagesintegernone (unlimited, walks every result page)Discovery mode only: optional bound on pages walked. The run still stops at Max wines.
proxyobjectApify Proxy (default group)Connection settings. Choose Residential for higher reliability on large or frequent runs.
mcpConnectorsarraynoneOptional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstringnoneNotion connector only: page under which records are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.
resumeFromRunIdstringnoneContinue one specific previous run or dataset: wines already collected there are skipped, so this run only appends new ones.
incrementalModebooleanfalseDaily or recurring monitoring of the same wine list or discovery filters. Returns only new and updated wines on later runs by default; reappeared wines only after an earlier emitExpired run has marked one gone.
stateKeystringnoneOptional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return wines unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have.
emitExpiredbooleanfalseIncremental mode only. Also return wines from a previous run no longer found, marked EXPIRED, once a run has fully scanned the tracked wines or filters. Adds and bills extra synthetic rows.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"wineId": 1234567,
"vintageId": 89012345,
"name": "Sample Winery Reserve Red 2019",
"winery": "Sample Winery",
"vintage": 2019,
"wine_type": "Red",
"region": "Sample Region",
"country": "France",
"country_code": "fr",
"grape_varieties": ["Cabernet Sauvignon", "Merlot"],
"average_rating": 4.3,
"ratings_count": 1200,
"price": 49.9,
"currency": "EUR",
"vfm_category": "great",
"is_natural": false,
"food_pairings": ["Beef", "Lamb"],
"taste_profile": {
"body": null,
"acidity": 3.1,
"tannins": 3.8,
"sweetness": 1.6,
"fizziness": null,
"intensity": 3.7,
"flavor_notes": ["black fruit", "oak", "leather"]
},
"reviews": [
{ "rating": 4.5, "note": "Sample review text.", "language": "en", "user_name": "reviewer", "created_at": "2026-01-01T00:00:00.000Z" }
],
"vivino_url": "https://www.vivino.com/sample-winery-reserve-red/w/1234567",
"scrapedAt": "2026-01-01T00:00:00.000Z",
"inputSource": "search"
}

Plan Requirement

The default connection setting works without any extra configuration, and the actor automatically switches to a different connection when a request is refused. For large or frequent discovery runs, choosing the Residential option under Connection gives the most consistent pricing and match results.

FAQ

How much does it cost?

You pay per record returned, plus one combined enrichment charge for any wine that gets taste profile (on by default) or reviews (off by default). The Pricing tab shows the current rates. Use Max wines to cap the cost of any run.

This actor collects only publicly available wine data. You are responsible for how you use it: follow Vivino's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Ratings and prices are generally facts, but labels, photos and review text may be subject to third-party rights.

Can I get only new or changed wines on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated wines by default, plus reappeared wines once an earlier run with Emit expired on has marked one gone, and unchanged ones are not billed. Lookup mode with pinned-vintage URLs gives the most stable results; see "Read this before you schedule a discovery run" above if you're scheduling discovery mode.

Why does a scheduled discovery run keep reporting changes even when nothing looks different?

Vivino answers from the location a request appears to come from, so a discovery walk run minutes apart can return a different set of wines, or quote the same wine as a different vintage from a different merchant. That reads as UPDATED because the record genuinely differs from what was stored, not because change detection is wrong. Pin your market with countryCode/currencyCode and a Residential connection, or switch to lookup mode with ?year= URLs, to reduce it.

Why did my run fail instead of returning an empty dataset?

A run fails only when it cannot even get started correctly, for example an invalid resumeFromRunId that cannot be resolved, or combining incrementalMode with resumeFromRunId once that campaign already has saved state. A wine that simply could not be matched, or a discovery page that could not be fetched, does not fail the run: it is skipped, logged, and reported in the run's status message and log, while every other wine is still returned.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

🔗 Want more wine and drinks data?

Pair this actor with these related scrapers from the same team:

🍷 Wine-Searcher Scraper
Look up wines on wine-searcher.com by name, URL, or LWIN code. Returns 30+ fields...
🍷 Dan Murphy’s Scraper
Scrape Dan Murphy’s products by category, keyword, or specials. Extract 45+ fields...
🍷 Untappd Beer, Brewery and Check-in Scraper
Scrape Untappd beers, breweries, venues and check-ins by keyword, brewery, Top Rated...
🥦 ResQ Club Scraper
Scrape ResQ Club surplus food offers in Finland, Sweden and Estonia: name, price, current...
🥦 Coles AU Scraper
Scrape Coles.com.au grocery products and customer reviews. Search by keyword, browse...
🥦 FoodHero Scraper
Scrape FoodHero surplus grocery deals across Canada by area, store or offer ID. Extract...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.