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

Search Eventbrite by city, keyword, date, category and price, or paste event and organizer URLs. One row per event: dates with time zone, venue and coordinates, price range, sold-out and urgency signals, organizer. Optional: every ticket type, refund policy, organizer track record.

- **URL**: https://apify.com/sz022/eventbrite-events-scraper.md
- **Developed by:** [CHEN-SHU-CHEN](https://apify.com/sz022) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 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

### What is Eventbrite Events Scraper?

You want a list of events: every tech meetup in San Francisco next month, the free concerts in London this weekend, or everything one organizer has run. Eventbrite shows them twenty at a time, spread over pages, with the price, the venue and the organizer each a click away.

Give it a **city, keywords, dates, categories and a price filter**, or paste **event URLs**, **organizer URLs** or **Eventbrite search URLs**. You get **one row per event**: title, start and end with their **time zone and UTC**, online or in person, **venue with address and coordinates**, category, subcategory and format, **price range and currency**, free, **sold out**, sales window, Eventbrite's **"few tickets left" and "sales end soon" signals**, recurring-series links, and the **organizer with their follower count**. No login needed.

Turn on **details** to also get **every ticket type** (price, fee, all-in price, on sale or sold out, sales window, per-order limits), the **refund policy**, the waitlist flag, the full description, and the **organizer's track record**: exact followers, total events hosted, attendees hosted, years on Eventbrite and the verified badge.

Because it runs on Apify, you can **schedule** a weekly pull for your city, call it through the **API**, send it to Google Sheets, Make or Zapier, and export it as **CSV, Excel or JSON**.

### How to scrape Eventbrite events

1. Open the **Input** tab. Type a **Location**, such as `San Francisco, CA`, `London` or `online`.
2. Add **Keywords** if you want them, one per line. Each keyword is its own search. Leave empty to list everything in the city.
3. Pick **When**, **Categories** and **Price** if you need them, and set **Maximum events per search**.
4. Or skip the search and paste **event, organizer or search URLs**. They can be mixed with a search in one run.
5. Click **Start**. A search of 100 events takes about 15 seconds; with details on, about a minute and a half (three more pages per event, plus a few per organizer).
6. Open the **Output** tab or export the dataset. Inputs that found nothing are still listed, with a `status` and a reason.

### What data does it return?

Every event appears **once**, however many keywords, pages or organizers found it.

| Field | Notes |
|---|---|
| `status` | `ok` for an event. Rows for inputs that produced no events: `no_results`, `not_found`, `blocked`, `failed`, `parse_error`, `invalid_input`, `not_processed` |
| `inputType`, `input` | Which search or URL found the event (`search`, `searchUrl`, `eventUrl`, `organizerUrl`) |
| `eventId`, `url`, `title`, `summary` | `summary` is the short description Eventbrite shows in search. The full one comes with details |
| `startAt`, `endAt` | Local time with its UTC offset, e.g. `2026-11-04T17:00:00-08:00` |
| `startUtc`, `endUtc`, `timezone` | The same moments in UTC, and the IANA time zone |
| `startDate`, `endDate`, `hideStartDate`, `hideEndDate` | |
| `isOnline` | `true` for online events |
| `venueName`, `venueAddress`, `venueCity`, `venueRegion`, `venuePostalCode`, `venueCountry`, `venueLatitude`, `venueLongitude`, `venueId` | Null for online events |
| `neighborhood` | From search results, e.g. `Soma` |
| `category`, `subcategory`, `format` (+ `…Id`) | Eventbrite's own taxonomy, e.g. Business & Professional / Career / Meeting or Networking Event |
| `tags` | The organizer's own tags |
| `imageUrl`, `imageOriginalUrl` | |
| `priceMin`, `priceMax`, `currency`, `priceMinDisplay`, `priceMaxDisplay` | The range Eventbrite shows in search. Where Eventbrite uses all-in pricing (the US), this includes fees |
| `isFree`, `isSoldOut`, `hasAvailableTickets`, `hasBogoTickets` | |
| `salesStatus`, `salesStatusMessage`, `salesStart`, `salesEnd` | `on_sale`, `sold_out`, `sales_ended`, `not_yet_on_sale`…; dates in UTC |
| `urgencySignals`, `urgencyCategories` | Eventbrite's badges: `fewTickets`, `goingFast`, `salesEndSoon`, `earlyBird`, `popular`, `new` |
| `isPromoted` | `true` for a paid placement (only with `includePromoted` on search URLs), `false` for organic search results, null for URL and organizer inputs |
| `isRecurring`, `seriesId`, `seriesUrl`, `seriesUpcomingCount` | For events that are one date of a series |
| `organizerId`, `organizerName`, `organizerUrl`, `organizerFollowers`, `organizerWebsite`, `organizerTwitter`, `organizerFacebook` | |
| `language`, `eventStatus`, `isCancelled`, `isPrivate`, `ticketsBy`, `ticketsUrl`, `publishedAt`, `scrapedAt` | |

#### With details on (`includeTicketsAndOrganizer`)

| Field | Notes |
|---|---|
| `detailsStatus`, `detailsError` | `ok`, or why the details could not be read (the event row itself is still delivered) |
| `ticketClasses` | One object per ticket type: `name`, `category` (admission, add-on, donation), `price`, `fee`, `tax`, `allInPrice`, `currency`, `onSaleStatus` (`AVAILABLE`, `SOLD_OUT`, `UNAVAILABLE`, `NOT_YET_ON_SALE`…), `isSoldOut`, `isAvailable`, `salesStart`, `salesEnd`, `minPerOrder`, `maxPerOrder`, `isFree`, `isDonation`, `deliveryMethods` |
| `ticketClassCount`, `ticketsOnSaleCount`, `ticketsSoldOutCount`, `allInPriceMin`, `allInPriceMax` | |
| `refundPolicy`, `refundDays`, `refundsAllowed`, `refundPolicyText` | e.g. `custom`, `7`, `true`, "Refunds up to 7 days before event". `no_refunds` gives `refundsAllowed: false`; `not_defined` gives null |
| `waitlistAvailable`, `isReservedSeating`, `isExternallyTicketed`, `inventoryType`, `ageRestriction`, `doorTime`, `presentedBy`, `hasDigitalContent` | |
| `description`, `descriptionHtml` | The full event description, as text and as HTML |
| `createdAt`, `updatedAt`, `locale` | |
| `organizerFollowers` | Exact, from the organizer's profile |
| `organizerTotalEvents`, `organizerUpcomingEvents`, `organizerPastEvents` | |
| `organizerAttendeesHosted`, `organizerAttendeesHostedText` | Eventbrite only publishes this rounded (`5.9k`), so the number is `5900` and the original text sits beside it |
| `organizerHostingYears`, `organizerHostingYearsText`, `organizerVerified`, `organizerBadge`, `organizerDescription` | |

**Unknown is `null`, never `0`.** Eventbrite does not publish how many tickets are left or an event's capacity, so `capacity` is almost always null. The honest signals are `isSoldOut`, each ticket type's `onSaleStatus`, and the `fewTickets` / `goingFast` badges.

### How much does it cost to scrape Eventbrite?

You pay per event delivered, not per page or per minute.

| Event | Charged for | Price | Per 1,000 events |
|---|---|---|---|
| `event-scraped` | Each event row delivered (`status: ok`) | $0.0045 | $4.50 |
| `event-details` | Each event whose ticket types, refund policy and organizer record were read (`detailsStatus: ok`) | $0.003 | $3 |

So 1,000 events cost **$4.50**, or **$7.50 with details**. Rows for inputs that found nothing (`no_results`, `not_found`, `blocked`, `invalid_input`, `not_processed`…) are free, and so are the details of an event whose details could not be read. An event found by two searches is charged once.

#### Is it free to try?

Apify's free plan includes $5 of usage a month, which covers about 1,100 events, or about 650 with details.

#### How do I cap what a run can spend?

Set a maximum cost per run in the run options. Before reading each batch of events the Actor works out how many more rows the limit covers, with or without details, and reads no more than that. When the limit is reached it stops, and every input it did not get to is listed as `not_processed`. If a charge fails, the run stops the same way rather than keep working unbilled. A failed charge is not sent a second time, so an event is never billed twice.

#### What happens if Apify restarts a run?

Each event row is written and charged in the same step, so an event is never charged without being in your dataset. When Apify moves a run to another server, the restarted run reads back the events already in the dataset and does not deliver or charge them again; each search and organizer keeps its limit across the restart. The run also has a time budget (`timeBudgetSeconds`, and the run's own timeout): no request starts, and no retry waits, past it. Events whose details were still being read when time ran out are left out and not charged, and the inputs not reached are listed as `not_processed`.

### Input example

```json
{
  "location": "San Francisco, CA",
  "keywords": ["tech", "startup"],
  "dateFilter": "next_month",
  "price": "any",
  "maxEvents": 200,
  "urls": [
    "https://www.eventbrite.com/e/tech-networking-event-in-san-francisco-tickets-1998391270084",
    "https://www.eventbrite.com/o/the-business-minds-108731452361"
  ],
  "organizerEvents": "upcoming",
  "includeTicketsAndOrganizer": true
}
```

Locations: a city as you would write it (`Austin`, `Paris, France`, `Springfield, IL`), an Eventbrite place slug (`tx--austin`), or `online`. Eventbrite picks the best match for a bare city name, so the place it chose is written to the log; add the state or country when a name is ambiguous.

URLs: event pages (`/e/...-tickets-123`), organizer pages (`/o/...-456`) and search pages (`/d/...`) from any Eventbrite country site. A search URL is a way to use any filter Eventbrite's own search offers: set it up on eventbrite.com, copy the address, paste it here.

### Output example

One row from a run on 2026-10-18, with details on, trimmed:

```json
{
  "status": "ok",
  "inputType": "search",
  "input": "python @ online",
  "eventId": "2002225540490",
  "title": "Introduction to Python for Data Analysis",
  "startAt": "2026-11-09T14:30:00-05:00",
  "startUtc": "2026-11-09T19:30:00Z",
  "timezone": "America/Toronto",
  "isOnline": true,
  "category": "Science & Technology",
  "priceMin": 50.85,
  "priceMax": 50.85,
  "currency": "CAD",
  "isSoldOut": false,
  "salesStatus": "on_sale",
  "urgencySignals": [],
  "organizerName": "Quantitative Methods Workshop Series",
  "organizerFollowers": 188,
  "ticketClasses": [
    {
      "name": "General Admission",
      "price": 45.0,
      "fee": 0.0,
      "tax": 5.85,
      "allInPrice": 50.85,
      "currency": "CAD",
      "onSaleStatus": "AVAILABLE",
      "salesStart": "2026-09-24T13:00:00Z",
      "salesEnd": "2026-11-08T19:30:00Z",
      "minPerOrder": 1,
      "maxPerOrder": 1
    }
  ],
  "refundPolicy": "custom",
  "refundDays": 7,
  "refundPolicyText": "Refunds up to 7 days before event",
  "organizerTotalEvents": 79,
  "organizerAttendeesHosted": 1100,
  "organizerAttendeesHostedText": "1.1k",
  "organizerHostingYears": 5,
  "organizerVerified": true
}
```

### FAQ

#### Why did my keyword search return fewer events than Eventbrite says?

When a keyword has few real matches, Eventbrite's search fills the rest with unrelated events from the same city: a search for "python" in San Francisco returns a class reunion and a bluegrass night. With **Only keep events that contain the keyword** on (the default), an event is kept only if every word of the keyword is in its title, summary, category or tags, and the search stops at the first page with no matches. Turn it off to get exactly what Eventbrite shows.

#### How many events can one search return?

Eventbrite stops at 1,000 results for any one search, and so does this Actor. For more, split the search: several keywords, categories, or date ranges. Events that show up in more than one are returned once.

#### Can it get past events?

For an organizer, yes: set **Which events of an organizer** to Past or Upcoming and past. Search only covers upcoming events, as on eventbrite.com.

#### Does it need a login, cookies or an API key?

No. It reads the same public data a logged-out visitor sees, from the JSON Eventbrite's own pages load. Private and password-protected events are not visible logged out and come back `not_found`.

#### Why is an input marked blocked?

Eventbrite refused the request on every proxy session tried. The Actor uses Apify's datacenter proxy and, if Eventbrite keeps refusing it, moves the rest of the run to Apify's US residential proxy (included in the price; turn off with **Switch to residential proxy if blocked**). If inputs still come back `blocked`, run again later.

#### What can it not return?

- **Tickets remaining and capacity.** Eventbrite does not publish them. Use `isSoldOut`, `onSaleStatus` and the `fewTickets` signal instead.
- **Attendee lists and organizer email addresses.** Not public.
- **Exact attendee totals for organizers.** Eventbrite only shows them rounded (`5.9k`).
- **Refund terms when the organizer set none.** `refundPolicy` is then `not_defined` and `refundsAllowed` is null.

#### Is it legal to scrape Eventbrite?

It reads only public event pages, the same data any visitor sees, and no personal data beyond what organizers publish about their events. Check the rules that apply to you and to what you do with the data; this is not legal advice.

#### Something broke or a field looks wrong

Open an issue on the **Issues** tab with the input and the run link. Reports are answered there.

# Actor input Schema

## `location` (type: `string`):

Where to search: a city as you would type it ("San Francisco, CA", "London", "Berlin"), an Eventbrite place slug (ca--san-francisco), or "online" for online events. The place Eventbrite matched is written to the log. Leave empty if you only paste URLs below.

## `keywords` (type: `array`):

Optional. One search per keyword, such as "tech", "yoga" or "jazz". Leave empty to list all events in the location.

## `keywordMustMatch` (type: `boolean`):

When a keyword has few real matches, Eventbrite fills the rest of the results with unrelated events from the same city. On (the default), an event is kept only if every word of the keyword appears in its title, summary, category or tags, and the search stops once a page has no matches left. Turn off to get exactly what Eventbrite's search shows.

## `dateFilter` (type: `string`):

Eventbrite's own date filters, in each event's local time. Choose "Custom range" to use the two dates below.

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

First day to include, YYYY-MM-DD. Used only when When is Custom range.

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

Last day to include, YYYY-MM-DD. Used only when When is Custom range.

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

Optional. Only events in these Eventbrite categories. Several categories are combined with OR.

## `price` (type: `string`):

Free events, paid events, or both.

## `maxEvents` (type: `integer`):

Stop each keyword's search after this many events. Eventbrite itself returns at most 1,000 events for one search; split a big city into keywords, categories or dates to go further.

## `urls` (type: `array`):

Optional, and can be mixed: event pages (https://www.eventbrite.com/e/...-tickets-123), organizer pages (https://www.eventbrite.com/o/...-456) and search result pages you have set up on eventbrite.com (https://www.eventbrite.com/d/ca--san-francisco/free--events--this-weekend/). Any Eventbrite country site works.

## `organizerEvents` (type: `string`):

For organizer URLs: their upcoming events, their past events (newest first), or both.

## `maxEventsPerOrganizer` (type: `integer`):

Stop reading an organizer's events after this many.

## `includePromoted` (type: `boolean`):

Eventbrite shows a few paid placements at the top of its search pages, and they do not always match the filters. Off by default. When on, they are added from the first page of each search URL with isPromoted: true.

## `includeTicketsAndOrganizer` (type: `boolean`):

Reads three more pages per event: every ticket type with its price, fee, all-in price, on-sale status and sales window; the refund policy; the waitlist flag; the full description. Also the organizer's exact followers, total events hosted, attendees hosted, years on Eventbrite and verified badge (read once per organizer). Charged as a separate event-details event per row.

## `residentialFallback` (type: `boolean`):

If Eventbrite keeps refusing the datacenter proxy, move the rest of the run to Apify's residential proxy. Included in the price. Only applies when the proxy below is Apify Proxy.

## `timeBudgetSeconds` (type: `integer`):

Stop starting new work after this long; everything not reached is listed as not_processed. The run's own timeout is respected as well.

## `proxyConfiguration` (type: `object`):

Apify's datacenter proxy by default. Proxy URLs of your own are used as given.

## Actor input object example

```json
{
  "location": "San Francisco, CA",
  "keywords": [
    "tech"
  ],
  "keywordMustMatch": true,
  "dateFilter": "any",
  "price": "any",
  "maxEvents": 10,
  "organizerEvents": "upcoming",
  "maxEventsPerOrganizer": 100,
  "includePromoted": false,
  "includeTicketsAndOrganizer": false,
  "residentialFallback": true,
  "timeBudgetSeconds": 3300,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `events` (type: `string`):

Title, dates with time zone, venue and coordinates, category, price range, sold-out and urgency signals, organizer; with details on, every ticket type, the refund policy and the organizer's track record. Unknown values are null, never 0.

## `inputSummary` (type: `string`):

One entry per search, event URL and organizer URL: its status, how many events it delivered, and the reason when it delivered none.

# 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": "San Francisco, CA",
    "keywords": [
        "tech"
    ],
    "maxEvents": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sz022/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": "San Francisco, CA",
    "keywords": ["tech"],
    "maxEvents": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("sz022/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": "San Francisco, CA",
  "keywords": [
    "tech"
  ],
  "maxEvents": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call sz022/eventbrite-events-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sz022/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/5FGggGChmNdskUUVj/builds/DSUYekZv0cNEMnwnH/openapi.json
