Eventim Scraper - DE Events, Dates and Tickets
Pricing
from $1.20 / 1,000 event records
Eventim Scraper - DE Events, Dates and Tickets
Scrape CTS Eventim Germany and EU event catalogue: concerts, festivals, comedy, sports, dates, venues, prices and availability. Search by city, keyword, category and date, or paste event links. Incremental monitoring with NEW, UPDATED, REAPPEARED, EXPIRED, resume and MCP export.
Pricing
from $1.20 / 1,000 event records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Eventim.de Scraper: Concerts, Festivals and Ticket Prices in Germany and the EU
Eventim.de Scraper turns the CTS Eventim catalogue, Europe's largest ticket shop, into structured event data. Get concerts, festivals, comedy, classical, sports and leisure events across Germany and the EU with dates, venues, prices in EUR and ticket availability. Search by city, keyword, category and date, or paste Eventim links for a specific event, city or venue, then export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two ways to find events. Search by city, keyword, category and date window, or paste Eventim event, city and venue links directly.
- Wide catalogue coverage. A search run walks every city and category combination you give it, not just one narrow query, and the coverage note below explains how to widen it further.
- Detail on demand. Switch on event detail reads to add the full venue address, price span and per-ticket-tier prices with availability (and the event page's own description and image), and pay the enrichment charge only for the events you actually read.
- Built for schedules. Incremental mode returns only new, updated and reappeared events on recurring runs, and can mark events that disappeared as expired (read the Max items caveat under "Resume and recurring updates" before turning that on).
- Resume support. Continue a large, interrupted pull without paying to recollect events you already have.
- Export anywhere. Download JSON, CSV or Excel, or pipe results into the apps you already use through MCP connectors.
- Fails loudly, not quietly. If the catalogue refuses every request, the run stops with a clear message instead of shipping an empty dataset that looks like "no events today".
Use Cases
- Ticket resellers and price trackers: watch
priceFrom,priceHighandticketAvailabilityacross venues and cities for pricing and stock changes. - Event discovery apps: feed concerts, festivals, comedy and sports dates into your own calendar, bot or notification tool.
- Tour and artist tracking: run a keyword search on a schedule with incremental mode to catch new tour dates as they go on sale.
- Venue and promoter research: collect venue addresses and promoter names for a city or category.
- Market research and reporting: build a dataset of event volume, categories and pricing across German cities over time.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
eventId / recordId | "00000000" |
title | "Sample Artist Live" |
eventType / eventStatus | "LiveEntertainment" / "Available" |
startDate / endDate | "2027-05-01T20:00:00+02:00" / "2027-05-01T22:30:00+02:00" |
venueName / venueCity | "Sample Arena" / "Berlin" |
venueStreet / venuePostalCode / venueRegion / venueCountry | "Sample Platz 1" / "10115" / "Berlin" / "DE" (detail mode only) |
venueUrl | Eventim venue page link (detail mode only) |
priceFrom / priceHigh | 49.9 / 99.9 |
priceCurrency | "EUR" |
priceTiers | per-ticket-tier category, price and availability (detail mode only); also exposed as priceCategories |
ticketAvailability | "in_stock" (also "out_of_stock", "sold_out") |
promoterName | "Sample Promoter GmbH" |
categories / tags | ["Concerts", "Music"] / ["TICKETDIRECT"] |
description / imageUrl | description text and image link: taken from the catalogue listing when it carries them (not every event does), with markup removed so it is plain text; with detail mode on, the event page value replaces the listing value, and when an event page cannot be read the stored value from your previous run is kept |
validFrom | ticket offer validity start (detail mode only) |
productGroupId | "g00000000" (also eventSeries.id) |
url | Eventim link to the event |
kind | "event" |
attractions | ["Sample Artist"] (performers listed on the event) |
rating | {"average": 4.5, "count": 12} |
inStock / hasRecommendation / fromPrice / fromPriceDisplay / currency | true / false / 49.9 / "49.90 EUR" / "EUR" |
eventName / eventUrl / type / status | alternate names for title / url / eventType / eventStatus |
scrapedAt | time the row was collected |
changeType | "NEW" (incremental mode only; also UPDATED, UNCHANGED, REAPPEARED, EXPIRED) |
changedFields / firstSeenAt / lastSeenAt | changed field names, first-seen and last-seen timestamps (incremental mode only) |
All text (title, description, categories) comes back in English: the actor reads Eventim's English-language catalogue pages. Prices are always in EUR.
How to Use
- Pick a mode:
search(by city, keyword, category, date) orurl(paste Eventim links). - Fill in the search filters for that mode, or paste event, city or venue links.
- Turn on Fetch event details if you need the full address and per-tier prices, set Max items, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search Berlin concerts:
{"mode": "search","cities": ["Berlin"],"categories": ["Concerts"],"maxItems": 20}
Keyword search across all cities, in a date window, tickets in stock only:
{"mode": "search","query": "Sample Artist","dateFrom": "2027-05-01","dateTo": "2027-08-31","inStockOnly": true,"maxItems": 50}
Supported link shapes (URL mode):
| Link shape | Example | Result |
|---|---|---|
| City page | https://www.eventim.de/en/city/berlin-1/ | the city's events |
City page without /en/ | https://www.eventim.de/city/berlin-1/ | the city's events |
City page with ?pnum=N | https://www.eventim.de/en/city/berlin-1/?pnum=2 | the whole city scope (page parameter ignored, warned) |
| Event page | https://www.eventim.de/en/event/bsv-eintracht-mahlsdorf-nofv-oberliga-nord-sportplatz-am-rosenhag-21994953/ | that event |
| Venue page | https://www.eventim.de/en/city/berlin-1/venue/admiralspalast-berlin-702/ | the venue's whole city scope (warned) |
| Artist, series and other pages | skipped with a warning |
URL mode with the Eventim links field left untouched now reads the three example links (city, event, venue) instead of failing with no input. Pass an explicit list to read your own links. Misspelled city or category names in search mode log a warning that nothing matched.
Paste Eventim links (event, city, venue), with full detail:
{"mode": "url","urls": ["https://www.eventim.de/en/event/sample-artist-live-berlin-00000000/","https://www.eventim.de/en/city/hamburg-2/"],"fetchDetails": true}
Recurring monitoring across three cities:
{"mode": "search","cities": ["Berlin", "Hamburg", "Munich"],"categories": ["Concerts"],"incrementalMode": true,"stateKey": "berlin-hamburg-munich-concerts","emitExpired": true,"maxItems": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/eventim-de-event-scraper").call(run_input={"mode": "search", "cities": ["Berlin"], "categories": ["Concerts"]})for event in client.dataset(run["defaultDatasetId"]).iterate_items():print(event["title"], event["startDate"], event["priceFrom"], event["priceCurrency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/eventim-de-event-scraper').call({mode: 'search', cities: ['Berlin'], categories: ['Concerts'],});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 the scope cap
Each city and category combination is one catalogue read that serves up to 50 events; the catalogue does not serve pages beyond that for a single combination. Combine cities with categories and a date window to widen coverage, since each combination is read on its own. With several combinations and a Max items cap, the cap is split evenly across them, so each city or category contributes its share rather than the run returning only the newest events globally; a low cap over many combinations can leave some headroom unused rather than concentrate it on the first combination. Set Max scopes to bound how many combinations are walked at all.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset id and the actor skips every event id already present there, so you do not pay to recollect them. This only works when the referenced dataset carries this actor's owneventIdfield on every row. Pointed at a dataset in a different shape (a hand-built dataset, or one that never went through this actor), it silently seeds nothing, logs a quiet "0 event id(s) seeded" line, and the run continues as if it were the first pull, recollecting and rebilling every event. Only point it at a run or dataset this actor produced. - Incremental mode (
incrementalMode) is for scheduled runs over the same search or link setup. Each event is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED(only withemitExpired, and never on a run that was resumed, hit the run-wide Max items total or Max scopes, or had any city, category or link fail).stateKeynames or shares the stored state. With incremental mode off, output is exactly as before. - Ignore fields when detecting changes (
ignoreFieldsForChanges, incremental mode only): field names (or dotted paths such aspriceTiers.availability) that never make an eventUPDATED. Always ignored:raw,imageUrland the added convenience fields (eventName,eventUrl,type,status,currency,fromPrice,fromPriceDisplay,inStock,hasRecommendation,attractions,venue,rating,priceCategories,eventSeries,scrapedAt), so a change in rating, attractions or venue coordinates alone never makes an eventUPDATED. Your own names and dotted paths apply to the core fields only (for examplepriceTiers.availability,tags,promoterName), not to those added fields. Adescriptionthat was empty in the stored baseline and is filled now is treated as the one-time fill, not as a change; a later edit to it readsUPDATED. Ignored fields are still returned in the output. - Using Resume and Incremental mode together in the same run: events the resume step skips (already collected in the run you resumed from) are deduplicated for that run but are not added to the incremental baseline, since they never reach the classification step. A later scheduled run without
resumeFromRunIdover the samestateKeywill not recognize them as already known, and will report and bill them again asNEW. In other words, under incremental mode the resume saving is postponed, not kept: the skipped events are paid for again on the next plain incremental run, just as they would have been had you run incremental mode without resuming. The first incremental run on any newstateKeyalways reports every event it finds asNEW, so plan for that one full-price run whichever way you start. - Expired rows are not capped by Max items. Once a run qualifies to tombstone, every event still in the tracked baseline but no longer found is returned and billed as
EXPIRED, regardless of how low Max items is set. On a monitoring campaign that tracks a large number of events, a big shift in what the scope returns can emit a correspondingly large batch ofEXPIREDrows in a single run. - Known issue: with Emit expired on, keep Max items at
0(no limit). The expiry check is only skipped when the run as a whole reaches Max items. A run can stop reading a city or category early because of its share of the cap without reaching that total: unchanged events that are suppressed still use up their scope's share, and a cap that does not divide evenly across combinations (for example 20 over 3 cities) never adds up to the total. Such a run treats every tracked event it did not get to read as gone, and returns and bills them asEXPIREDeven though they are still on sale; the next full run then bills them again asREAPPEARED. For example, with 50 tracked events that are all still listed, a run with Max items10returns 40 falseEXPIREDrows. Incremental runs with Emit expired off are not affected.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via 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 event, 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.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you have not authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto 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
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (query the catalogue) or url (paste Eventim links). |
cities | array | (empty; prefilled ["Berlin"]) | Search mode: city names, one per line. Empty searches all cities. |
query | string | (empty) | Search mode: optional keyword, an artist, event or venue name. |
categories | array | (empty, all categories) | Search mode: event categories, for example Concerts, Comedy, Classical, Sports. |
searchTerm / city | string | (empty) | API-only alternate names for query and one entry of cities. |
dateFrom | string | (empty, no lower bound) | Only events on or after this date, YYYY-MM-DD. |
dateTo | string | (empty, no upper bound) | Only events on or before this date, YYYY-MM-DD. |
inStockOnly | boolean | false | Return only events whose tickets are currently bookable. |
sort | string | DateAsc | DateAsc, DateDesc, NameAsc, NameDesc, Rating, or Recommendation. sortBy is an API-only alternate name, used when sort is left at DateAsc. |
postalCode | string | (empty) | Search mode: events around a German postal code (PLZ); the catalogue applies its own fixed radius. |
artist | string | (empty) | Search mode: artist name, appended to the keyword search (the catalogue has no separate artist filter). |
venue | array | (empty) | Search mode: exact venue names as Eventim lists them, one per line; a partial name matches nothing. |
priceMin | integer | (empty) | Search mode: from-price lower bound in euros; must not exceed priceMax. |
priceMax | integer | (empty) | Search mode: from-price upper bound in euros. |
eventSeriesIds | array | (empty) | Search mode: earlier productGroupId values, one per line; each id is its own scope. |
urls | array | three example links (one city, one event, one venue) | URL mode: Eventim event, city or venue links, one per line. With the field untouched, URL mode reads the three example links. |
fetchDetails | boolean | false | Read each event's own page for description, image, full venue address, price span and per-tier prices. Adds a per-event surcharge. |
maxItems | integer | 20 | Stop after this many events (0 = no limit). maxResults is an API-only alternate name, used when maxItems is not set or left at 20. |
maxPages | integer | 0 | Upper bound on how many city and category combinations are walked (0 = no limit). |
resumeFromRunId | string | (none) | A previous run id or dataset id to continue without recollecting its events. |
incrementalMode | boolean | false | Return only new and changed events on scheduled runs. |
stateKey | string | (none) | Name or share an incremental-mode state; derived automatically when left empty. |
emitUnchanged | boolean | false | Also return (and bill) unchanged events. |
emitExpired | boolean | false | Also return (and bill) expired events. |
ignoreFieldsForChanges | array | (none) | Incremental mode: field names or dotted paths that never make an event UPDATED (see Resume and recurring updates). |
mcpConnectors | array | (none) | Optional: send a summary of each event to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which event pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
proxyConfiguration | object | Apify Proxy | Connection settings. Apify Proxy by default; see Plan Requirement for what free plans can reach. |
Dataset views: the dataset has four saved views in the Console: Overview (core columns), Detail (venue, price tiers and description, filled in detail mode), Changes (change type and changed fields, incremental mode) and Series (the series id columns, productGroupId and eventSeries, next to each event; the rows are not grouped).
API-only alternate names: searchTerm, city, sortBy and maxResults are accepted through the API as alternate names for query, cities, sort and maxItems; they are not shown in the Console form.
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"kind": "event","recordId": "00000000","eventId": "00000000","productGroupId": "g00000000","url": "https://www.eventim.de/en/event/sample-artist-live-berlin-00000000/","title": "Sample Artist Live","startDate": "2027-05-01T20:00:00+02:00","endDate": "2027-05-01T22:30:00+02:00","eventStatus": "Available","eventType": "LiveEntertainment","venueName": "Sample Arena","venueUrl": "https://www.eventim.de/en/city/berlin-1/venue/sample-arena-1/","venueStreet": "Sample Platz 1","venueCity": "Berlin","venueRegion": "Berlin","venuePostalCode": "10115","venueCountry": "DE","priceFrom": 49.9,"priceHigh": 99.9,"priceCurrency": "EUR","priceTiers": [{ "category": "Standing", "price": 49.9, "priceCurrency": "EUR", "availability": "in_stock" },{ "category": "Seated", "price": 99.9, "priceCurrency": "EUR", "availability": "in_stock" }],"ticketAvailability": "in_stock","promoterName": "Sample Promoter GmbH","categories": ["Concerts", "Music"],"tags": ["TICKETDIRECT"],"description": "A sample show description.","imageUrl": "https://www.eventim.de/obj/media/sample-image.jpg","validFrom": "2026-11-01T10:00:00+01:00"}
Plan Requirement
The scraper reads Eventim through Apify Proxy and checks which proxy tiers your account is allowed to use as it goes. Catalogue searches start on the default connection; event detail pages (with Fetch event details on, or pasted event links) are refused by ordinary connections, so those reads escalate automatically through an alternate Apify Proxy pool, then residential and backup connections, and the first one that serves the pages is reused for the rest of the run.
- Paid Apify plan: the full ladder is available and all input options work.
- Free Apify plan: Apify free plans do not include residential proxies, and some free accounts have no Apify Proxy access at all. The run logs "Apify free plans do not include residential proxies" and continues on a backup connection, so some pages may still be unavailable. If every connection is refused the run stops with a clear message ("The proxy connection was refused for this account ... a paid plan is required") instead of returning an empty dataset. If only the backup connection was tried and it could not load the pages, the message is "No results: residential proxies are unavailable on this run". If requests simply fail, the message is "Could not load any results page ... This is a connection problem, not an empty search."
- Your own proxy URLs: requests are sent exactly as given, with no escalation.
Eventim's protection can change at any time, so availability on a given tier is observed at run time, not guaranteed.
FAQ
How much does it cost?
You pay per event returned, with the detail enrichment charged only for events whose detail page was read (Fetch event details on, or pasted event links), plus one run-start charge. The Pricing tab shows the current rates. Use Max items to cap the cost of any run, with the expired-row note below in mind for incremental monitoring runs.
Is it legal to scrape Eventim.de?
This actor collects only publicly available catalogue data (dates, venues, prices and availability). You are responsible for how you use it: follow Eventim's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Why does a search return at most 50 events per city or category?
That is the most common surprise: the catalogue serves at most 50 events for a single city and category combination and does not page deeper for it. Add more cities, categories or narrow the date window so the run covers the catalogue through more combinations instead of one large one. The "Coverage and the scope cap" note above has the details.
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, and unchanged ones are not billed unless you turn on Emit unchanged. If you also turn on Emit expired, set Max items to 0 (see the known issue above).
Why did my run fail instead of returning an empty dataset?
If every scope or pasted link is rejected, the run stops with a clear message so "no matching events" is never confused with "nothing could be read". Run it again in a few minutes. If only some cities, categories or links could be read, you still get what was found, and the run succeeds with a status message naming what was skipped.
Why did an incremental run return far more rows than Max items?
EXPIRED rows are not counted against Max items: once a run qualifies to tombstone (not resumed, run-wide Max items total or Max scopes not reached, every scope finished), it returns every tracked event no longer found, however many that is. There is also a known issue: if Max items stopped a city or category early without the run reaching its total, the events it did not read are wrongly returned as EXPIRED (and come back as REAPPEARED on the next full run). With Emit expired on, set Max items to 0. Lower genuine expiry volume by narrowing the tracked scope (fewer cities or categories per stateKey) or by leaving Emit expired off on very large monitoring campaigns.
Why didn't Resume skip events I already collected?
Two known causes. First, resumeFromRunId only recognizes rows carrying this actor's own eventId field; a dataset from any other source seeds nothing, silently. Second, combining resumeFromRunId with Incremental mode in the same run deduplicates the resumed events for that run only, without adding them to the incremental baseline, so a later scheduled run can report them as NEW again. See "Resume and recurring updates" above for details.
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 sports data?
Pair this actor with these related scrapers from the same team:
| ⚽ BookMyShow Scraper Scrape BookMyShow movies and live events by city, category or URL. Extract genres... | ⚽ Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse) Collect live and prematch betting odds from 1xBet, Melbet, Linebet and Paripulse. Give it... |
| ⚽ Globo Esporte Scraper Scrape public sports content from ge.globo.com, including news, videos, matches and feed... | ⚽ FotMob Scraper ⚽ Match Details, Stats, Lineups & Players Pull structured football data from FotMob: match details with scores, team stats, events... |
| ⚽ SofaScore Scraper ⚽ Live Scores, Stats, Players & Odds Pull structured sports data from SofaScore across football, basketball, tennis, and 20+... | ⚽ JioHotstar Scraper Scrape the JioHotstar catalog by content type or URL. Extract shows, movies, episodes... |
💬 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.