# Events Scraper - Luma, Meetup, Eventbrite by City (`bachiembmt/events-scraper-luma-meetup-eventbrite`) Actor

Events scraper for Luma, Meetup and Eventbrite: find public events by city or coordinates and keyword in one unified schema. Dates with timezone, venue, geo, price, organizer and attendee count. For event feeds, community research and lead generation. No login.

- **URL**: https://apify.com/bachiembmt/events-scraper-luma-meetup-eventbrite.md
- **Developed by:** [Ha Phan Thanh Hai](https://apify.com/bachiembmt) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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

## Events Scraper: Luma, Meetup & Eventbrite by city and keyword

Find **public events across Luma, Meetup and Eventbrite** by city (or lat/lng) and keyword, returned in one unified schema. No login, no API key.

### What does Events Scraper do?

- Search by city name or `lat,lng[,radiusKm]` and by keyword.
- Cover Luma, Meetup and Eventbrite in one run, or pick one with `sources`.
- Filter by date window, online-only or in-person-only.
- Get title, start/end with timezone, venue, address, geo, price range and currency, organizer, attendee count and image.
- Optionally include the event description.

### Why use it

- **Three platforms, one schema**.
- **Geo-aware**: city or coordinates with a radius.
- **Low price**: $1.50 per 1,000 events.
- **No login, cookies or proxy.**

### Use cases

- Local event feeds, newsletters and "what's on" widgets.
- Community and lead research: which tech meetups run in a city.
- Market research on ticket prices and attendance.
- Event-sponsor and speaker prospecting.
- Tracking event activity by topic across cities.

### How to use

1. Open the Actor on Apify and click **Try for free** (or call it through the API).
2. Enter **locations** and **keywords**, choose **sources** and a date window.
3. Click **Start**, then download the dataset as JSON, CSV, Excel or HTML, or read it through the API.

#### Input example

```json
{
  "locations": ["San Francisco", "London"],
  "keywords": ["ai"],
  "sources": ["luma", "meetup", "eventbrite"],
  "startDateFrom": "2026-11-01",
  "startDateTo": "2026-11-30",
  "onlineOnly": false,
  "inPersonOnly": false,
  "maxEventsPerSource": 10,
  "includeDescription": false
}
```

`locations` accepts city names (`"Austin, TX"`) or `"lat,lng"` / `"lat,lng,radiusKm"`. Keywords are whole-word matches; leave empty for all upcoming events.
`maxEventsPerSource` applies per source, location and keyword.

### Output example

```json
{"source":"meetup","eventId":"317009834","title":"The Best of Portugal Wine Tasting","url":"https://www.meetup.com/london-wine-meetup/events/317009834/",
 "startAt":"2026-11-03T17:40:00+00:00","endAt":"2026-11-03T20:30:00+00:00","timezone":"Europe/London","isOnline":false,
 "venueName":"...","address":"...","city":"London","country":"GB","lat":51.49,"lng":-0.17,"organizerName":"London Wine Meetup",
 "priceMin":40.0,"priceMax":40.0,"currency":"GBP","isFree":false,"attendeeCount":12,"imageUrl":"...","descriptionText":null,"tags":["physical"]}
```

Fields: source, eventId, title, url, startAt, endAt, timezone, isOnline, venueName, address, city, country, lat, lng, organizerName, priceMin, priceMax, currency, isFree, attendeeCount, imageUrl, descriptionText, tags.

### Pricing

Pay per event, no subscription. You pay only for what is returned:

| Event | Price per 1,000 | 1,000 | 10,000 | 100,000 |
|---|---|---|---|---|
| event | $1.50 | $1.50 | $15.00 | $150.00 |

Example: 1,000 events cost $1.50; 10,000 cost $15.00.

Platform usage (compute) is included in the event price; there is nothing else to pay for.

### Integrations & API

Run it from code with the Apify API. Replace `<APIFY_TOKEN>` with your API token.

**Python** (`pip install apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("bachiembmt/events-scraper-luma-meetup-eventbrite").call(run_input={"locations": ["San Francisco"], "keywords": ["ai"], "sources": ["luma", "meetup", "eventbrite"], "maxEventsPerSource": 10})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**cURL** (run synchronously and get dataset items)

```bash
curl -X POST "https://api.apify.com/v2/acts/bachiembmt~events-scraper-luma-meetup-eventbrite/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"locations": ["San Francisco"], "keywords": ["ai"], "sources": ["luma", "meetup", "eventbrite"], "maxEventsPerSource": 10}'
```

Works with:

- **Make** and **Zapier**: use the Apify app/module to run this Actor and pass the dataset on.
- **n8n**: use the Apify node or an HTTP Request node with the API call above.
- **Google Sheets**: export the dataset as CSV, or use the Apify integration to append rows automatically.
- **Webhooks**: trigger your own endpoint when a run finishes; combine with Apify schedules for recurring jobs.
- **AI agents**: expose the Actor as a tool through the [Apify MCP server](https://mcp.apify.com).

### FAQ

**Why 0 events for one source?**
The log shows the reason, e.g. no keyword match or no Luma city nearby. Luma covers about 90 discover cities and has no server-side keyword search.

**Do I get attendee lists?**
No. Only attendee counts where the platform shows them (Meetup RSVPs, Luma); lists are never collected.

**Which time zone do dates use?**
ISO 8601 in the event's own timezone.

**Do I need an account or API key for the source?**
No. The Actor needs no login or source API key. You only need an Apify account to run it.

**Is it legal to scrape this data?**
Public event listings only. Respect each site's terms of use; no attendee lists or personal data are collected. This is general information, not legal advice.

### Limitations

- **Luma** covers ~90 discover cities (nearest city within 80 km is used); no server-side keyword search (needs login), so keywords match title/host/calendar name within the first ~500 upcoming events. Online events are rare in city feeds.
- **Meetup**: attendee count = RSVPs; free events have no currency; online events have no venue.
- **Eventbrite**: needs a city name (not bare coordinates). Search is relevance-ranked and not a hard filter, so results are filtered to real keyword matches (may return fewer than requested). Description = public summary. Attendee counts are not public. Online-only runs use Eventbrite's location-independent online listings.
- Prices on Eventbrite are the min/max across ticket types. Attendee lists are never collected.
- Respect each site's terms of use; public data only.

# Actor input Schema

## `locations` (type: `array`):

City names ('Berlin', 'Austin, TX') or coordinates 'lat,lng' / 'lat,lng,radiusKm' (e.g. '51.5,-0.12,10'). Each location is searched separately.

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

Search terms (whole-word match, e.g. 'ai', 'python', 'wine tasting'). Leave empty to list upcoming events without a keyword.

## `sources` (type: `array`):

Which sites to search.

## `startDateFrom` (type: `string`):

YYYY-MM-DD or ISO datetime. Default: now.

## `startDateTo` (type: `string`):

YYYY-MM-DD or ISO datetime. Optional.

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

Keep only online events (Eventbrite: location-independent online listings).

## `inPersonOnly` (type: `boolean`):

Drop online events.

## `radiusKm` (type: `integer`):

Used for city names on Meetup. Coordinates with their own radius override this and are enforced on all sources.

## `maxEventsPerSource` (type: `integer`):

Limit per source, location and keyword.

## `includeDescription` (type: `boolean`):

Luma: one extra request per event. Meetup: full text. Eventbrite: public summary. Slower with Luma.

## Actor input object example

```json
{
  "locations": [
    "San Francisco"
  ],
  "keywords": [
    "ai"
  ],
  "sources": [
    "luma",
    "meetup",
    "eventbrite"
  ],
  "onlineOnly": false,
  "inPersonOnly": false,
  "radiusKm": 25,
  "maxEventsPerSource": 10,
  "includeDescription": false
}
```

# Actor output Schema

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

No description

# 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 = {
    "locations": [
        "San Francisco"
    ],
    "keywords": [
        "ai"
    ],
    "sources": [
        "luma",
        "meetup",
        "eventbrite"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bachiembmt/events-scraper-luma-meetup-eventbrite").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 = {
    "locations": ["San Francisco"],
    "keywords": ["ai"],
    "sources": [
        "luma",
        "meetup",
        "eventbrite",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("bachiembmt/events-scraper-luma-meetup-eventbrite").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 '{
  "locations": [
    "San Francisco"
  ],
  "keywords": [
    "ai"
  ],
  "sources": [
    "luma",
    "meetup",
    "eventbrite"
  ]
}' |
apify call bachiembmt/events-scraper-luma-meetup-eventbrite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bachiembmt/events-scraper-luma-meetup-eventbrite"
        }
    }
}
```

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/RQ0OiXZWZgfVdTK5G/builds/gs12ZUUnzrR9R7LQW/openapi.json
