# Eventbrite Events Scraper (`dami_studio/eventbrite-events-scraper`) Actor

Name a city and get every upcoming Eventbrite event in it, one row each: title, start and end time, venue and full address, organiser, ticket price range and the link. Filter by keyword, category or date. No account, no API key, no browser.

- **URL**: https://apify.com/dami\_studio/eventbrite-events-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.92 / 1,000 event scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Eventbrite Events Scraper

Name a city and get every upcoming Eventbrite event in it, one row each: the title, the start and end time in the venue's own timezone, the venue and its full address, who is organising it, the cheapest and dearest ticket, and the link. No account, no cookies, no API key, no browser.

- Up to 10 cities in one run, each with its own share of the row budget.
- Filter by keyword, by any of Eventbrite's 21 categories, by date window, by free-only, or by online-only.
- Every row says which location was searched and what Eventbrite resolved it to, so an ambiguous city name is visible rather than silent.
- Ticket prices come back as numbers with a currency, not as a display string you have to parse.
- Empty input returns a labelled sample row, free, so you can see the shape before spending anything.

### Price

**$0.92 per 1,000 events**, plus a **$0.0005 start fee per run**.

This is a flat rate on every plan, free or paid. There are no volume tiers, no minimum spend, no subscription and no add-on fees. What you read here is what you pay on day one and on day four hundred.

| Events | Total cost |
|---|---|
| 100 | $0.0925 |
| 1,000 | $0.9205 |
| 10,000 | $9.2005 |
| 100,000 | $92.0005 |

Eventbrite stops any single search at 1,000 events, so the 10,000 and 100,000 lines above assume several runs and one start fee each.

#### What is actually charged

- **One `event-scraped` event per event row written to the dataset.** Nothing else is metered per row.
- **Free:** the sample row an empty run returns, and every diagnostic row — a blocked target, a dead URL, a search that matched nothing. Those rows all carry `"charged": false`.
- A location Eventbrite cannot place is reported and skipped. No search runs for it, so there is nothing to bill.
- Events that come back for a search but cannot be confirmed as being in the place you asked for are handed over uncharged, with the reason attached.
- Duplicate events across your locations are dropped before they are charged.
- A run that finds nothing costs the start fee and nothing more.
- Rows never leave the dataset without a charge, and are never charged without a row. The billed event is a named one, so there is no price quietly attached to `apify-default-dataset-item` — the trick that makes some scrapers bill you for their own error messages.

### Input

```json
{
  "location": [
    "London",
    "Berlin"
  ],
  "keyword": "jazz",
  "dateRange": "this_month",
  "categories": [
    "103"
  ],
  "maxItems": 200
}
```

| Field | What it does |
|---|---|
| `location` | City, region or country, one per line, up to 10. Plain names work. For an ambiguous name, paste an `eventbrite.com/d/<slug>/` browse URL or the numeric place id and the run uses exactly that place. |
| `keyword` | Optional. Narrows results the way the search box on the site does. |
| `dateRange` | One of: all upcoming, today, tomorrow, this weekend, this week, next week, this month, next month. Defaults to all upcoming. |
| `startDate` / `endDate` | Optional exact window as `YYYY-MM-DD`. Both are needed; one on its own is ignored and the `dateRange` choice is used instead. |
| `categories` | Optional. Any of Eventbrite's 21 categories. Empty means all of them. |
| `onlineOnly` | Return online events instead of events at a venue. Location becomes optional, because online events do not have one. |
| `freeOnly` | Only events Eventbrite lists as free. |
| `maxItems` | Total events across all your locations, split evenly between them. Default 50, ceiling 5,000. Keep it low while testing — you pay per row. |
| `proxyUrls` | Leave empty. Fill it in only if you want traffic to leave through proxy servers you already pay for. |

Run it with **empty input** and you get one clearly labelled sample row, free, so you can see the output shape before you spend anything.

### Output

One row per event. A real row from a real run:

```json
{
  "ok": true,
  "charged": true,
  "recordType": "event",
  "searchLocation": "London",
  "locationName": "London",
  "locationSubtitle": "Greater London, United Kingdom",
  "locationId": "101750367",
  "name": "Tribute to Hans Zimmer & Film Favourites Illuminated: St Paul's Cathedral",
  "summary": "An immersive tribute to Hans Zimmer and cinema's most iconic music with a live chamber orchestra illuminated by light!",
  "startsAt": "2026-11-10T19:30:00",
  "endsAt": "2026-11-10T21:30:00",
  "timezone": "Europe/London",
  "venueName": "St. Paul's Cathedral",
  "venueAddress": "St. Paul's Cathedral, London, EC4M 8AD",
  "city": "London",
  "region": "England",
  "country": "GB",
  "latitude": 51.5138453,
  "longitude": -0.0983506,
  "organizerName": "Illuminated",
  "organizerUrl": "https://www.eventbrite.co.uk/o/illuminated-00000000000",
  "organizerFollowers": 29100,
  "minPrice": 62.97,
  "maxPrice": 125.96,
  "currency": "GBP",
  "isFree": false,
  "isSoldOut": false,
  "isOnline": false,
  "categories": [
    "Music"
  ],
  "url": "https://www.eventbrite.co.uk/e/tribute-to-hans-zimmer-film-favourites-illuminated-tickets-000000000000",
  "ticketsUrl": "https://www.eventbrite.com/checkout-external?eid=000000000000",
  "eventId": "000000000000",
  "scrapedAt": "2026-09-20T09:42:53.198Z"
}
```

#### Field notes

- `startsAt` / `endsAt` — local wall-clock time at the venue, with `timezone` beside it. They are not converted to UTC, because Eventbrite publishes the local time and the offset would be a guess on a date that crosses a clock change.
- `minPrice` / `maxPrice` — the cheapest and dearest ticket type at the moment the row was read, as numbers. A single-price event repeats the same figure in both.
- `currency` — the ISO code the organiser sells in, which is not always the country's currency — a London event priced in euros comes back as `EUR`.
- `isFree` — Eventbrite's own free flag. It is not the same as `minPrice` being 0: a paid event with a free tier has `minPrice: 0` and `isFree: false`.
- `venueName` / `venueAddress` — null on an online event. `city`, `region`, `country`, `latitude` and `longitude` are null there too.
- `organizerFollowers` — the organiser's follower count on Eventbrite, a rough proxy for how established they are.
- `categories` — the Eventbrite categories on the event. Most have one; some have none.
- `eventId` — stable. Use it as the primary key when you re-run and diff.
- `locationVerified` — only present, and only `false`, when you pinned a place by its numeric id — see the limitations.

Every real row carries `"charged": true`. Sample rows carry `"_sample": true` and diagnostic rows carry `"_diagnostic": true` with an `errorCode` you can filter on, and neither is ever billed.

### How it works

- It calls the same JSON search the Eventbrite site's own front end calls, and asks for only the parts that end up in a row. No page rendering and no headless browser, which is why it is quick and why it costs what it does.
- Each location is resolved against Eventbrite's place index first. The resolved place is echoed on every row, so you can see whether "Cambridge" meant England or Massachusetts.
- If a location cannot be resolved, the run says so and searches nothing for it. It never falls back to a worldwide search — that is the failure that quietly hands you another continent's events at full price.
- Every venue is then checked against the resolved place before the row is charged. Anything that lands implausibly far away is handed over free with the distance in the note.
- Results are paged until your row budget is reached, and event ids already seen in the run are skipped.

### What people use it for

- Building a local "what's on" feed for a newsletter or a site, refreshed on a schedule and diffed on `eventId`.
- Venue and promoter research: group the rows by `venueName` or `organizerName` and you can see who actually runs the nights in a city.
- Ticket price benchmarking before you put your own event on sale — `minPrice`, `maxPrice` and `currency` are already numbers, so the median is one formula.
- Sponsorship and partnership prospecting: filter to a category, sort by `organizerFollowers`, and you have a shortlist with the organiser's own page attached.
- Tracking whether a recurring night is still running, and at what price, without opening the site every week.

### Reading the output

A run writes three kinds of row and they are easy to tell apart.

- **Real rows** carry `"charged": true` and `"recordType": "event"`. One billed event each.
- **The sample row** carries `"_sample": true`. There is exactly one, it only appears when the input named no location and did not ask for online events, and it is free.
- **Diagnostic rows** carry `"_diagnostic": true` and an `errorCode` you can switch on. `LOCATION_NOT_FOUND` means a name could not be placed and nothing was searched for it. `LOCATION_MISMATCH` means an event came back that could not be confirmed as being where you asked; it is listed with its distance and was not billed. `NO_RESULTS` means the search ran and matched nothing. `NETWORK` means Eventbrite could not be reached. `TIME_BUDGET` means the run ran out of time before reaching a location. None of them is ever charged.

If you only want the data, filter on `charged == true`. That count always equals the number of events you were billed for, so the dataset is its own invoice.

### Ambiguous place names

Plenty of city names are not unique, and Eventbrite's place index has all of them. Type `Cambridge` and you may get Cambridgeshire, Cambridge in Massachusetts or Cambridge in England. Type `New York` and you may get the state rather than the city.

Two things follow. First, every row carries `locationName` and `locationSubtitle` — the place that was actually searched — so you can see immediately which one you got, and the run log lists the runner-up matches. Second, if you want a specific one, do not fight the name: open the place on Eventbrite and paste its browse URL (`https://www.eventbrite.com/d/ny--new-york/all-events/`), or pass the numeric place id on its own. Either pins the search exactly.

### Limitations

- Eventbrite stops any single search at 1,000 events, whatever you ask for. A city with more than that needs to be split by category or by date window. The row budget you set is honoured; the 1,000 is Eventbrite's and cannot be paged past.
- Only what the public listing shows. There is no attendee data, no sales figures, no ticket inventory, no organiser email and no joining of an organiser to anything outside Eventbrite.
- Organisers are frequently named individuals. The organiser name and page are taken straight from the public listing and nothing is enriched, looked up elsewhere or inferred.
- Ticket prices are the range Eventbrite advertises at read time. They move, tiers sell out, and an event can show 0 to 0 when the organiser has not opened sales yet.
- Every run needs a location or the online-only box ticked. There is deliberately no worldwide keyword search, because a search with no place returns a global feed that looks exactly like a successful city search.
- The location check is a sanity check, not a boundary. It keeps another continent out; it does not promise every row sits inside a municipal border. Events in the surrounding metro area are included, because Eventbrite counts them as that city and so do the people going to them.
- When you pin a place by its numeric id, the location check stands down and rows carry `locationVerified: false`. Eventbrite has no way to look a place up by id, so there is nothing to check the rows against. Pinning by browse URL or by name keeps the check on.
- Start and end times are local to the venue and are not converted to UTC.
- Recurring events are returned as Eventbrite lists them, which is usually one row for the series rather than one per date.
- Cancelled and private events are excluded by Eventbrite's own search, so they will not appear even if you know they exist.
- The hard ceilings are 10 locations and 5,000 rows per run. Bigger jobs split across runs.

### Questions

**What do I get for one row?**

One event: title, summary, start and end time plus timezone, venue name and full address, city, region, country, latitude and longitude, organiser name, organiser page and follower count, minimum and maximum ticket price with currency, free and sold-out flags, online flag, categories, the event link, the ticket link and the event id.

**Do I need an Eventbrite account or an API key?**

No. Nothing is logged in and no key is used. The run reads the same public listing data the site serves to anyone browsing it.

**What happens if I misspell a city?**

You get one uncharged diagnostic row saying the name could not be placed, and the run moves on to your other locations. Nothing is searched and nothing is billed for it. It will never quietly give you events from somewhere else instead.

**Why did some events come back marked as not charged?**

Because they could not be confirmed as being in the place you asked for. Eventbrite occasionally returns an outlier, and rather than bill you for it the run hands it over free with the distance in the note, so you can decide whether you want it.

**Can I get more than 1,000 events from one city?**

Not in one search — that is Eventbrite's own ceiling. Split the city by category, or by date window, and run those separately. Each search gets its own 1,000.

**Will the run fail if something goes wrong?**

No. A blocked, empty or unreachable target produces an uncharged diagnostic row explaining what happened and the run still finishes as succeeded. A failed run would still bill the start fee, which would mean paying to be told something went wrong.

**Can I run this on a schedule?**

Yes. Nothing is held between runs, so the same input is safe to repeat. Diff on `eventId` to see what is new since last time.

**How do I get exactly the rows I paid for?**

Filter the dataset on `"charged": true`. Sample and diagnostic rows are always `false`, and the number of charged rows always equals the number of billed events.

# Actor input Schema

## `location` (type: `array`):

The city, region or country to search. One per line, up to 10 per run. Plain names work ("London", "Austin", "Berlin"). If a name is ambiguous, paste an eventbrite.com/d/<slug>/ browse URL or the numeric place id instead and the run will use exactly that place. A name Eventbrite cannot place is reported and skipped - it is never quietly turned into a worldwide search.

## `keyword` (type: `string`):

Narrow the results to events matching a word or phrase, the same way the search box on the site does. Leave it empty for everything in the place.

## `dateRange` (type: `string`):

Which events to include. "All upcoming" is everything from today onwards. The shorter windows follow Eventbrite's own calendar, so "This weekend" means the coming Saturday and Sunday where the events are, not where you are.

## `startDate` (type: `string`):

An exact start date as YYYY-MM-DD. Fill in both this and the end date to use your own window instead of the "When" choice above. One on its own is ignored.

## `endDate` (type: `string`):

An exact end date as YYYY-MM-DD. Only used when the From date is filled in too.

## `categories` (type: `array`):

Limit the run to Eventbrite's own categories. Pick as many as you like; leave it empty for all of them.

## `onlineOnly` (type: `boolean`):

Return online events rather than events at a venue. Ticking this makes the location optional - online events do not have one.

## `freeOnly` (type: `boolean`):

Return only events Eventbrite lists as free.

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

Total events to return across all your locations. The budget is split evenly between them, so three cities and 300 rows gives you 100 of each. Eventbrite itself stops any one search at 1,000 events, so asking for more than 1,000 per location returns 1,000. Keep it low while you are testing - you pay per row.

## `proxyUrls` (type: `array`):

Leave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.

## Actor input object example

```json
{
  "location": [
    "London"
  ],
  "dateRange": "current_future",
  "maxItems": 50
}
```

# Actor output Schema

## `results` (type: `string`):

Every row in the default dataset: name, startsAt, endsAt, timezone, venueName, venueAddress, city, region, country, organizerName, organizerUrl, minPrice, maxPrice, currency, isFree, isOnline, url, eventId. An empty, blocked or unmatched run returns a single uncharged row explaining what happened instead.

# 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 = {
    "location": [
        "London"
    ],
    "keyword": "",
    "dateRange": "current_future",
    "startDate": "",
    "endDate": "",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/eventbrite-events-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 = {
    "location": ["London"],
    "keyword": "",
    "dateRange": "current_future",
    "startDate": "",
    "endDate": "",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/eventbrite-events-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 '{
  "location": [
    "London"
  ],
  "keyword": "",
  "dateRange": "current_future",
  "startDate": "",
  "endDate": "",
  "maxItems": 50
}' |
apify call dami_studio/eventbrite-events-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/eventbrite-events-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/e7lAcyo2TKiWgfgkB/builds/6P49g63yAPr3ee1Sf/openapi.json
