Viagogo Scraper - Events, Venues, Availability & Monitoring
Pricing
from $1.80 / 1,000 event records
Viagogo Scraper - Events, Venues, Availability & Monitoring
Scrape Viagogo events by artist, production, venue, city, category, or URL. Extract event names, dates, venues, locations, availability, and links. Track NEW, UPDATED, REAPPEARED, and EXPIRED events with incremental runs, resume, and MCP export.
Pricing
from $1.80 / 1,000 event records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
5
Total users
0
Monthly active users
19 days ago
Last modified
Categories
Security
Limited permissionsShare
Viagogo Scraper: Live Event Listings & Availability Monitoring
Viagogo Scraper turns Viagogo (viagogo.com), the global event ticket marketplace, into a clean event data feed, reading directly from the same service the site's own search page reads. Search any artist, production, venue, city or category and get the live events behind it: names, dates, times, venues, cities, countries, availability and canonical links, across tens of thousands of events in 70+ countries. Paste links instead of keywords, monitor events across runs (NEW, UPDATED, REAPPEARED, EXPIRED), resume an interrupted pull, and export to JSON, CSV or Excel, or read the results through the API.
Why This Scraper?
- Real source-service data. Each search term returns the source's own served window of up to 20 events, with venue, city, country, date and time in one record, plus a curated raw snapshot so nothing upstream is dropped. City and category page links are read directly and can return far more (a category page lists about 2,000 events), bounded by Max items.
- Keyword search across the whole catalogue. Artists, productions, venues, cities and categories all work as search terms.
- Date window and sort.
startDateandendDatekeep only events inside a date range on every row the run reads (search windows, city pages and category pages), andsortBypicks the site's relevance or published-date order for search terms and for search, production and venue links (city and category pages keep their own order). - Link mode. Paste city and category links and the actor reads those pages directly for their own events; search, production and venue links are resolved by text search and kept only when they carry the link's own production path or venue id. Single-event links (
/E-<id>) name no search term and are reported as skipped, never silently dropped. - Availability monitoring. Scheduled runs classify every event as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED, with per-campaign state you can name or share.
- Global coverage. Tens of thousands of events across 70+ countries, with loud failures instead of silent empty datasets.
- MCP connector export. Send results into Notion and other connectors without changing the dataset.
Use Cases
- Ticket resale market research: track availability, event counts and listing status across artists, venues or cities to spot demand trends.
- Event discovery integrations: feed a search or alerting app with live event names, dates, venues and links for the acts your users follow.
- Fan and reseller alerting: schedule recurring runs with incremental mode to get notified only when events go on sale, change or sell out.
- Venue and category monitoring: watch a venue, city or category page's event lineup over time without rechecking it by hand.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
kind | "event" (also "match") |
recordId | "event-500001" |
eventId | "500001" |
title | "Sample Artist Live" |
url | canonical Viagogo link to the event |
dayOfWeek | "Sat" |
formattedDate / formattedTime | "Nov 07 2026" / "7:30 PM" |
formattedDateWithDayOfWeek | "Sat, Nov 07 2026" |
startDateTimeUtc | "2026-11-08T00:30:00+00:00" |
startDateTimeLocal | "2026-11-07T19:30:00" (venue-local wall clock, city-page rows) |
isDateConfirmed / isTimeConfirmed | true / true |
isTbd / isMultidayEvent / isParkingEvent | false / false / false |
venueTimeZoneOffsetHours | -5.0 |
eventState / availabilityState | 1 / 1 |
hasListings / allowPublicPurchase | true / true |
isUnderHundred | false |
venueId / venueName | 90001 / "Sample Arena" |
venueCity / venueLocation | "Sample City" / "Sample City, ST, USA" |
countryCode / countryName | "US" / "United States" |
searchKeyword | "Sample Artist" |
sourceUrl | the search term or link the record came from |
formattedDateWithoutYear, eventCountdownMessage, soldOutMessage, isFavorite, aggregateFavorites, userDistanceFromVenue, eventMetadata | extra upstream fields passed through when the source fills them |
raw | curated upstream snapshot (session tokens and UI copy stripped) |
changeType / changedFields | "NEW" / [] (incremental mode) |
firstSeenAt / lastSeenAt | ISO timestamps (incremental mode) |
With Also return production and venue matches on, you also get the search page's top production, venue and category hits: kind=match records carrying objectId, title, subtitle, url, entityType, rank and imageUrl.
The dataset has three views: Overview (events), Matches (production, venue and category hits) and Changes (incremental changeType and changedFields). A multi-term run also saves a per-term summary under the OUTPUT key of the run's key-value store.
Ticket seat-level listings (sections, rows, seat prices) live behind the source's own protected event pages and are NOT part of this dataset; the actor reads the open search lane only, which carries no pricing fields.
How to Use
- Pick a mode:
search(keywords) orurl(links). - Add your search terms (an artist, production, venue, city or category), or paste links.
- Turn on Also return production and venue matches if you also want those rows, and set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search for an artist:
{"mode": "search","queries": ["Sample Artist"],"maxItems": 20}
A wide act split across narrower terms:
{"mode": "search","queries": ["Sample Artist Atlanta", "Sample Artist Chicago", "Sample Artist Boston"],"maxItems": 60}
Supported link shapes (link mode):
| Link shape | Example | How it is read |
|---|---|---|
| City page | https://www.viagogo.com/Atlanta | Read directly: the events listed on the city page. |
| Category page | https://www.viagogo.com/Concert-Tickets | Read directly: the events listed on the category page. |
| Search link | https://www.viagogo.com/secure/search/?q=coldplay | The q term is searched. |
| Production page | https://www.viagogo.com/Concert-Tickets/Rap-and-Hip-Hop-Music/Usher-Tickets | Searched by name; only events under that production path are kept. |
| Venue page | https://www.viagogo.com/Sports-Tickets/Basketball/NBA-Tickets/_V-27372 | Searched by name; only events at that venue id are kept. |
| Event page | https://www.viagogo.com/E-150000000 | Not readable; reported as skipped with a warning. |
A production or venue link whose search returns no event of its own logs a warning and emits nothing for that link, never an unrelated hit.
Which fields each shape fills. City and category pages carry fewer fields than search rows, so those rows are thinner. Search rows fill the full table above.
| Shape | Filled | Not available |
|---|---|---|
| Search, production, venue and search-link rows | every field in the table above | none (a few fields stay empty when the source leaves them empty) |
City page (/Atlanta) | title, url, dayOfWeek, formattedDate (with year), formattedTime, startDateTimeLocal, isDateConfirmed, isTimeConfirmed; venueId on most cards; venueName, venueCity, venueLocation on sport and theater cards; startDateTimeUtc only when the source fills it | eventState, availabilityState, hasListings, countryCode, countryName, venueTimeZoneOffsetHours; venue name on concert cards grouped by venue (only the venue id is served) |
Category page (/Concert-Tickets) | title, url, startDateTimeUtc, dayOfWeek and formattedDate (derived from the UTC start, so they can differ from the venue-local day by one), isDateConfirmed, isTimeConfirmed, isTbd, eventState, hasListings, allowPublicPurchase, venueId | formattedTime, venueName, venueCity, venueLocation, countryCode, countryName, availabilityState |
The raw snapshot of every row keeps every other field the page carried.
Paste links (city, category, production, venue or search):
{"mode": "url","urlInputs": ["https://www.viagogo.com/Atlanta","https://www.viagogo.com/Concert-Tickets"],"maxItems": 0}
Recurring monitoring with expiry detection:
{"mode": "search","queries": ["Sample Artist"],"incrementalMode": true,"stateKey": "sample-artist-daily","emitExpired": true}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/viagogo-events-scraper").call(run_input={"mode": "search", "queries": ["Sample Artist"], "maxItems": 20})for event in client.dataset(run["defaultDatasetId"]).iterate_items():print(event["title"], event["venueName"], event["formattedDate"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/viagogo-events-scraper').call({ mode: 'search', queries: ['Sample Artist'], maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Coverage and Max items
A search term, search link, production link or venue link returns the source's own served window of up to 20 events, best matches first, and the source ignores every page parameter, so there is no page-by-page walk to extend a single term. City and category page links are read directly and return every event on the page (about 2,000 for a category page), bounded by Max items. With several terms or links, Max items is shared proportionally across them so a multi-term run stays balanced. Cover a wide act or a big city with several narrower terms (add a city, a venue or a tour name) rather than raising Max items on one term.
Resume and recurring updates
-
Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips events already collected there, so you don't pay twice for them in that same pull.Known gap: Resume does not combine cleanly with Incremental mode. An interrupted incremental run saves no baseline, and the resumed run skips the events the interrupted run already collected without adding them to the baseline it saves. So on the very next run (without Resume) those events are classified again (NEW, or UPDATED if they had changed) and billed a second time. Resuming therefore saves nothing on an incremental campaign: rerun an interrupted incremental run without Resume instead, which re-collects those events once and leaves a complete baseline. A different
stateKeyfor the resumed run does not help, because the scheduled campaign's own baseline still never records those events. -
Incremental mode (
incrementalMode) is for scheduled runs over the same scope. Each event is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that read every term or link, was not stopped by the run-wide Max items total, was not resumed, and had no unreadable link).stateKeynames or shares the stored state. Every output field is compared except the raw source payload, countdown and sold-out message text, favorites counts and distance-from-you values, which stay in the output but never trigger UPDATED; add more withignoreFieldsForChanges(names match at any depth). Changing that list or the output fields causes no one-time wave of UPDATED rows. One-time restart for city, category, production and venue links: city and category links used to be turned into text searches and are now read directly with a different row shape, and production and venue links used to emit the whole text-search window but now keep only the events of their own production or venue. An existing incremental campaign over any of these links therefore restarts once on a fresh baseline (its events come back as NEW once, nothing is marked EXPIRED because of the change, and the old baseline is left untouched under its old state key). This holds with or without astateKey: a named campaign that reads any of these links is stored under that key with a fixed link-format suffix, while a named campaign over search terms or search links keeps its existing baseline. Without astateKey, adding or changingstartDate,endDateorsortBylikewise starts a separate baseline (sortByonly for runs that read a search), so events outside the new range are never marked EXPIRED. With astateKey, those three filters do not change the baseline (you named it), so after changing them start a newstateKeyif you do not want out-of-range events marked EXPIRED. When a production or venue link is resolved from a search that returned events but none of them belong to that production or venue, the actor treats the link as unread: it emits nothing for it and skips EXPIRED detection for the whole run.Known gap: when Emit expired records is on, the actor pushes the whole batch of events that dropped out of your tracked baseline in one commit after a complete scan, and that batch is not limited by Max items (only the NEW, UPDATED, REAPPEARED and, if enabled, UNCHANGED rows collected during the scan are). If you track a large baseline and most of it is no longer found, a run with Max items set and Emit expired on can return, and bill, well over Max items. Size Max items with your tracked baseline in mind when Emit expired is on, not just your usual NEW/UPDATED volume.
Known gap: with several terms or links, each one gets only its share of Max items (Max items divided by the number of terms). When one term's share stops it early but the run as a whole stays under Max items (for example another term had few changes, or Max items does not divide evenly), the run is not treated as capped. With Emit expired on, the tracked events of that term that sat after the cut are then marked EXPIRED and billed even though they are still listed, and come back as REAPPEARED (billed again) on the next run. For multi-term monitoring with Emit expired on, set Max items to
0(no limit) so no term is cut short.
Send results into your apps (MCP connectors)
Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape, and it never changes the dataset.
- Authorize a connector once under Apify, Settings, API and Integrations (Notion, Linear, Airtable or Apify).
- Select it in the mcpConnectors field. If the picker is empty, you have not authorized a connector yet.
- For Notion, also set notionParentPageUrl to the URL or id of the page under which item pages are created.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keyword search) or url (links). |
queries | array | ["Coldplay"] | Search mode: one entry per term (artist, production, venue, city or category text). |
urlInputs | array | city and category example links | Link mode: city, category, search, production or venue links (see the table below). Single-event links (/E-<id>) are reported as skipped. Link mode with this field left untouched scrapes the two default example links (/Atlanta, /Concert-Tickets). Before, the field had no default (an omitted field gave no links) and only the Console prefill was a single production link. |
urls | array | (none) | Alias for urlInputs, accepted under the name other Apify actors use for URL mode. |
startDate | string | (none) | Keep only events starting on or after this date (YYYY-MM-DD). Compared by UTC start for search and category rows and by venue-local date for city-page rows; events with no known start time are kept. |
endDate | string | (none) | Keep only events starting on or before this date (YYYY-MM-DD). Same rule: UTC start for search and category rows, venue-local date for city-page rows; events with no known start time are kept. |
sortBy | string | relevance | relevance or published order of the served window. Applies to search terms and to search, production and venue links; city and category pages keep their own order. |
maxItems | integer | 20 | Stop after this many records (0 = no limit). Shared proportionally across search terms or links. |
includeMatches | boolean | false | Also emit the search page's top production, venue and category matches, marked kind=match. |
resumeFromRunId | string | (none) | Continue one interrupted run, skipping records already collected there. |
incrementalMode | boolean | false | Recurring monitoring with change detection. |
stateKey | string | (none) | Name or share an incremental-mode monitoring campaign. |
emitUnchanged | boolean | false | Also return (and bill) UNCHANGED records. |
emitExpired | boolean | false | Also return (and bill) EXPIRED records after a complete scan. |
ignoreFieldsForChanges | array | (none) | Incremental mode only: extra field names (any depth) that never trigger UPDATED. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
proxyConfiguration | object | Apify Proxy | Proxy & connection settings. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"kind": "event","recordId": "event-500001","eventId": "500001","url": "https://www.viagogo.com/Concert-Tickets/Sample-Category/Sample-Artist-Tickets/E-500001","title": "Sample Artist Live","dayOfWeek": "Sat","formattedDate": "Nov 07 2026","formattedTime": "7:30 PM","formattedDateWithDayOfWeek": "Sat, Nov 07 2026","startDateTimeUtc": "2026-11-08T00:30:00+00:00","isDateConfirmed": true,"isTimeConfirmed": true,"isTbd": false,"isMultidayEvent": false,"isParkingEvent": false,"venueTimeZoneOffsetHours": -5.0,"eventState": 1,"availabilityState": 1,"hasListings": true,"allowPublicPurchase": true,"isUnderHundred": false,"venueId": 90001,"venueName": "Sample Arena","venueCity": "Sample City","venueLocation": "Sample City, ST, USA","countryCode": "US","countryName": "United States","searchKeyword": "Sample Artist","raw": { "note": "curated upstream event object, session tokens and UI copy stripped" },"changeType": "NEW","changedFields": [],"firstSeenAt": "2026-01-01T00:00:00+00:00","lastSeenAt": "2026-01-01T00:00:00+00:00"}
Plan Requirement
A paid Apify plan with proxy access is required. Viagogo refuses ordinary datacenter connections on its search, production and venue pages, and plain residential connections are refused there too, so the actor walks its own connection ladder (Apify Proxy, then Apify residential where your plan has it, then backup residential and datacenter pools, then a pooled alternate connection) and stays on whichever one is actually served. City and category pages are open and are read directly. Search, production and venue reads can be slow and may fail in busy windows: the run then fails with a clear message instead of returning an empty dataset. On a plan without proxy access the run stops within seconds and says so. Viagogo is a public ticket marketplace; automated reading may sit outside the source's terms of use, so keep volumes reasonable and respect the source's terms.
FAQ
How much does it cost?
You pay a start event per run plus the event record charge for each record returned in the dataset (and each returned incremental row). The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Viagogo?
This actor collects only publicly available event listing data from Viagogo's own search service. You are responsible for how you use it: follow Viagogo's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Can I get only new or changed events on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only NEW, UPDATED and REAPPEARED events (plus EXPIRED ones if you turn on Emit expired), and unchanged ones are not billed unless you turn on Emit unchanged.
Why did a wide search term return fewer events than I expected?
The source serves one window of up to 20 events per search term, search link, production link or venue link and ignores page parameters, so there is no page-by-page walk to extend a single term's results (city and category page links are read in full instead). Split a wide act or a big city across several narrower terms (add a city, a venue or a tour name) instead of raising Max items on one term.
Why did a monitoring run with Max items set return far more rows than Max items?
Emit expired records pushes the whole batch of events that dropped out of your tracked baseline in one commit after a complete scan, and that batch is not limited by Max items (only the rows collected during the scan are). If you track a large baseline and most of it is no longer found, a run with Emit expired on can return, and bill, well over Max items. Set Max items with your baseline size in mind when Emit expired is on. With several terms, also set Max items to 0: a term cut short by its share of Max items can otherwise have still-listed events marked EXPIRED (see the Resume and recurring updates tips).
Why did my run fail instead of returning an empty dataset?
If the site refuses every request on every available connection, including the backup pools and the pooled alternate connection, the run stops with a clear message ("Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."; on a free plan it says residential proxies are unavailable and asks you to upgrade or supply your own proxy URLs) so "no events for this term" is never confused with "nothing could be read". Run it again in a few minutes. If your plan does not include proxy access, the run stops within seconds and says a paid plan is required. If only some terms or links could be read, you still get what was found from the others. Runs that bring their own proxy connections keep exactly the connection they configured.
Can I get seat-level prices and sections?
No. Section, row and seat-level pricing lives behind the source's own protected event pages, which this actor does not read; it reads the open search results only, which carry no pricing fields.
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.
๐ More scrapers you might like
Pair this actor with these related scrapers from the same team:
| ๐งฉ Songkick Scraper Scrape Songkick concert and event calendars: upcoming and past dates, venues, cities... | ๐งฉ Ticketmaster Scraper Discover and scrape Ticketmaster events across the US, UK, Australia and Canada. Search... |
| โฝ Eventim Scraper Scrape CTS Eventim Germany and EU event catalogue: concerts, festivals, comedy, sports... | โ๏ธ Pollstar Scraper Scrape Pollstar upcoming concerts and tour dates: play date, venue with full address and... |
| ๐ SeatGeek Scraper Scrape SeatGeek events with ticket price ranges (lowest, highest, average, median)... | ๐งฉ Fever Scraper Scrape Fever events by city, category, keyword or URL. Extract from-prices, venues, dates... |
๐ 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.