# Eventbrite Scraper (`subimpact/eventbrite-scraper`) Actor

Scrape Eventbrite events with venue + organizer data by default. $0.002/event, usage paid by buyer. Search by city/query/category, URL mode, organizer mode, dryRun.

- **URL**: https://apify.com/subimpact/eventbrite-scraper.md
- **Developed by:** [subimpact](https://apify.com/subimpact) (community)
- **Categories:** Lead generation
- **Stats:** 3 total users, 2 monthly users, 60.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 events

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Scraper

Scrape Eventbrite events with **venue + organizer data by default** — cheaper than the market leader.

**Price:** $0.002/event, usage paid by buyer. No monthly fee.

### What it does

- **Search** events by query, city, category, price, date range, radius
- **Venue + organizer data by default** (address, website, socials) via `includeDetails` (default true)
- **Guaranteed within-run dedup** — no double charges; no double rows within a single run. A platform migration can re-push a small number of un-charged rows (up to ~50 chargeable, more in degraded runs) — they are never charged twice, and the search restarts at page 1 (duplicates count toward `maxEvents`).
- **dryRun mode** — count events before you pay
- **URL mode** — scrape specific event URLs
- **Organizer mode** — all events by an organizer ID

### Inputs

| Field | Description |
|---|---|
| `query` | Free-text search (e.g. "tech", "yoga"). Optional. |
| `places` | ONE city name or place ID. v1 supports a single place. |
| `country` | Filters place resolution (e.g. "United States"). No-op without places. |
| `category` | Eventbrite category ID (e.g. 103 = Music). |
| `price` | `free` or `paid`; omit for both. |
| `onlineOnly` | Post-filter for online events. **Mutually exclusive with places.** |
| `startDate` / `endDate` | ISO dates; end defaults to +1 year. |
| `sort` | `date` (default) or `distance`. `distance` requires `places`. |
| `radius` | km. Default 50, max 50 in v1 (required with places). |
| `eventUrls` | Event URLs to scrape directly. Series URLs return a parent stub (not charged). |
| `organizerId` | All events by an organizer. |
| `maxEvents` | Default 1000, max 10000. Counts processed rows (incl. duplicates). |
| `includeDetails` | Default true. Disable for search-only (cheaper, less data). |
| `maxTotalChargeUsd` | Bill-shock guard. Default 20.01 (10k events at $0.002). |
| `dryRun` | Count only, no charge. Still bills platform usage. |

### Output

One row per event: id, name, summary, description (details), url, start/end (local + timezone + UTC), venue name + address, city/country (with source markers), organizer name/url/website/facebook/twitter, category/subcategory/format, is\_online, is\_free (details), currency (details), status, image\_url (details), is\_series\_parent, detail\_failed (details), is\_cancelled (search rows), listed, series\_id/num\_children, search\_metadata. `is_series_parent: true` / `detail_failed: true` / `is_cancelled: true` / `listed: false` / `status: "canceled"` / `status: "draft"` mark rows that are **delivered but not charged**.

### Honest numbers

- **Per-query ceiling:** the Eventbrite search API stops at ~900 rows per query (≤18 pages), regardless of the reported object\_count. A buyer setting `maxEvents: 10000` on a broad search gets ~900 rows. **Date-sharding recovers ~4×** (measured: 4 quarterly shards = 3,218 rows vs 791 full-year) — coming as an opt-in in v1.1.
- **Delivery vs object\_count:** ~96% on narrow queries; ~7% when object\_count saturates at 10,000 (the API overstates counts on broad no-query searches — measured 892 rows for a London radius-50 drain that reported 10,000).
- **Dedup:** within-run only. Measured duplicate rates: 0.4-2.3% on narrow queries, up to 14% on broad no-query searches.
- **Series:** one row = the next upcoming occurrence. `num_children` = remaining occurrences including this row. Series occurrences are NOT expanded in v1 (v1.1 opt-in).
- **Description:** `description` equals `summary`, both capped at ~140 chars (matches the Eventbrite search UI). Full HTML body is not fetched in v1.
- **Cancellations:** search-only mode is best-effort on cancelled events (the API returns `is_cancelled` as null on search rows). With `includeDetails` (default), cancelled/draft/unlisted events are **delivered but not charged** — the row is in the dataset with its status, and you are not billed for it.
- **detail\_failed rows:** if a detail fetch fails, the row is still delivered (search data) but **not charged** when `includeDetails=true`.
- **Destination fields (on by default, `enrichDestination: false` to disable):** each event also carries `ticket_min_price`/`ticket_max_price`/`ticket_currency` (price range from ticket availability), `is_sold_out`/`has_available_tickets`/`has_bogo_tickets`, `sales_status`/`sales_start`/`sales_end`, `public_collections_count`, `saved_by_you`, `image_small_url`/`image_large_url`. One extra lightweight API call per event; failures leave the fields null and never affect charging (the verdict counts them in `destinationMissing`). Venue coordinates (`venue_latitude`/`venue_longitude`) come from the venue record.
- **Partial runs:** a WAF, rate-limit, auth, charge-cap, detail-degradation, schema-drift, non-200-page, page-cap, or checkpoint-unreadable event ends the run gracefully (SUCCEEDED) with fewer rows than requested — the run log and the KV `finalize_verdict` record (fields `truncated`/`exitReason`/`detailErrors`/`detailSkips`/`detailSkipsAuth`/`seriesKeyMissing`/`detailIdentityMissing`/`dedupSliceOverflow`/`chargeCapHit`/`detailDegraded`/`authBreak`/`checkpointReadRecovered`/`deliveredProbe`) say so. Check the log if your dataset looks short. Observable `exitReason` values include: `WafError`, `RateLimitError`, `NotAuthorizedError`, `Error`, `HTTP_<status>`, `BODY_UNPARSEABLE`, `SCHEMA_DRIFT`, `CHECKPOINT_UNREADABLE`. `seriesKeyMissing` counts rows delivered but not charged because the `is_series_parent` key was absent (schema drift). `detailIdentityMissing` counts rows delivered but not charged because the detail response lost `id`/`name`/`url` (schema drift). `dedupSliceOverflow` means the run exceeded the 20,000-ID dedup checkpoint and older IDs were dropped — a migration could re-deliver and re-charge those rows. `detailDegraded`/`authBreak` latch the two degradation exits: `detailDegraded` = the rolling detail-failure breaker OR any >20-consecutive-skip streak (see `detailSkips`/`detailSkipsAuth` for the split); `authBreak` = a >20-skip streak that was majority-auth (likely auth/CSRF break).
- **City/country:** from venue address (ISO-2 country) when details on; from the search locations chain otherwise; ~2% of rows have no geography (marked `city_source: "none"`).

### Pricing

$0.002/event, usage paid by buyer (platform auto-applies Bronze/Silver/Gold plan discounts at checkout). No secondary SKUs.

### Privacy / GDPR

Eventbrite event data is public. Organizer socials (facebook/twitter) are part of the public organizer profile. For data deletion requests, contact <privacy@subimpact.net>.

### Refunds

`detail_failed` rows are not charged. If you believe you were overcharged, contact us and we'll reconcile within 48h.

# Actor input Schema

## `query` (type: `string`):

Free-text search term (e.g. 'tech', 'yoga'). Optional — omit for all events in the place.

## `places` (type: `array`):

ONE city name (e.g. 'London') or raw place ID. v1 supports a single place. When set, radius is required (default 50 km).

## `country` (type: `string`):

Filters place resolution by country (e.g. 'United States'). No-op without places.

## `category` (type: `string`):

Eventbrite category. Optional. IDs verified against observed EventbriteCategory/\* tags in probe fixtures (Probe-8/9/12).

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

free = free events only; paid = paid events only; omit for both.

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

Post-filter for online events. Mutually exclusive with places (place-scoped search returns no online events).

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

ISO date (YYYY-MM-DD). Optional; defaults to today.

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

ISO date (YYYY-MM-DD). Optional; defaults to +1 year from startDate.

## `sort` (type: `string`):

date = by start date (default); distance = by distance from place center (requires radius).

## `radius` (type: `integer`):

Search radius in km. REQUIRED when places is set. Default 50, max 50.

## `eventUrls` (type: `array`):

List of Eventbrite event URLs to scrape directly. Series URLs return a parent stub (not charged).

## `organizerId` (type: `string`):

Scrape all events by this organizer (e.g. '120990958363').

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

Maximum number of events to process (counts processed rows incl. duplicates). Default 1000 (above measured depth ~892 for London r50). Cap 10000.

## `maxTotalChargeUsd` (type: `number`):

Bill-shock guard: stop charging once total charges reach this amount. Default 20.01 (just above 10,000 events at $0.002 — avoids the floating-point knife edge where a full-size run stops one batch early).

## `includeDetails` (type: `boolean`):

Fetch full event details (venue address, organizer, description, status). Default true.

## `enrichDestination` (type: `boolean`):

Add ticket price range, sales status/window, saved flags, public collections and image renditions per event (one extra lightweight API call per event). On by default.

## `dryRun` (type: `boolean`):

Count only, no charge. Still bills platform usage.

## Actor input object example

```json
{
  "onlineOnly": false,
  "sort": "date",
  "radius": 50,
  "maxEvents": 1000,
  "maxTotalChargeUsd": 20.01,
  "includeDetails": true,
  "enrichDestination": true,
  "dryRun": false
}
```

# Actor output Schema

## `id` (type: `string`):

No description

## `name` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `url` (type: `string`):

No description

## `start` (type: `string`):

No description

## `venue_name` (type: `string`):

No description

## `city` (type: `string`):

No description

## `country` (type: `string`):

No description

## `organizer_name` (type: `string`):

No description

## `category` (type: `string`):

No description

## `subcategory` (type: `string`):

No description

## `format` (type: `string`):

No description

## `is_online` (type: `string`):

No description

## `is_free` (type: `string`):

No description

## `status` (type: `string`):

No description

## `listed` (type: `string`):

No description

## `image_url` (type: `string`):

No description

## `series_id` (type: `string`):

No description

## `detail_failed` (type: `string`):

No description

## `is_series_parent` (type: `string`):

No description

## `is_cancelled` (type: `string`):

No description

## `ticket_min_price` (type: `string`):

Minimum ticket price in major units (e.g. 21.08), from ticket availability. Null for free/unknown.

## `ticket_max_price` (type: `string`):

Maximum ticket price in major units (e.g. 74.98), from ticket availability. Null for free/unknown.

## `ticket_currency` (type: `string`):

ISO currency of the ticket price range (e.g. GBP).

## `is_sold_out` (type: `string`):

True when the event reports sold out via ticket availability.

## `sales_status` (type: `string`):

Eventbrite sales status (e.g. on\_sale, sales\_ended, not\_on\_sale).

## `sales_start` (type: `string`):

Sales window start (local time) from event sales status.

## `sales_end` (type: `string`):

Sales window end (local time) from event sales status.

## `public_collections_count` (type: `string`):

Number of creator collections containing this event.

## `saved_by_you` (type: `string`):

Whether the fetching account saved this event (anonymous sessions: false).

## `image_small_url` (type: `string`):

Small rendition of the event image (from the destination image expand).

## `image_large_url` (type: `string`):

Large rendition of the event image (from the destination image expand).

## `venue_latitude` (type: `string`):

Venue latitude (decimal degrees).

## `venue_longitude` (type: `string`):

Venue longitude (decimal degrees).

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("subimpact/eventbrite-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("subimpact/eventbrite-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 '{}' |
apify call subimpact/eventbrite-scraper --silent --output-dataset

```

## MCP server setup

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