# Luma Events Scraper API (lu.ma) (`dami_studio/luma-events-scraper`) Actor

Scrape lu.ma events by city, community calendar, category or event URL. Returns name, start and end time with timezone, venue or online link, host, cover image, ticket price or free flag, sold-out status and guest count. Clean JSON, no login and no API key.

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

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Luma Events Scraper API (lu.ma)

Pulls public events off **lu.ma** and hands them back as flat JSON rows: what the event is called,
when it starts and ends (in its own timezone), where it is, who is hosting, what a ticket costs and
how many people have signed up.

Point it at a city, a community calendar, a category, or a single event link.

**$2.125 per 1,000 events** ($0.002125 each), plus $0.001 each time a run starts. Flat rate — no
volume tiers, no plan gates, and you pay only for events actually returned. See
[Pricing](#pricing) for the honest full picture, including a cheaper competitor.

***

### What you get

One row per event. From a real 300-event run across 10 cities (29 seconds, 33 different towns, 5 countries):

```json
{
  "eventId": "evt-zmiNTm0S1Vw0tYU",
  "slug": "beta-fdnw",
  "url": "https://lu.ma/beta-fdnw",
  "name": "Snowflake X Beta Fund X Evermind Agent & Token Economy Hackathon",
  "startAt": "2026-08-07T16:00:00.000Z",
  "endAt": "2026-08-08T01:00:00.000Z",
  "timezone": "America/Los_Angeles",
  "startAtLocal": "2026-08-07 09:00",
  "endAtLocal": "2026-08-07 18:00",
  "durationMinutes": 540,
  "locationType": "offline",
  "isOnline": false,
  "venueName": null,
  "addressFull": null,
  "city": "Menlo Park",
  "cityState": "Menlo Park, CA",
  "region": "California",
  "country": "United States",
  "countryCode": "US",
  "latitude": 37.4867899,
  "longitude": -122.1764731,
  "addressIsHidden": true,
  "hostName": "Beta University",
  "hostCount": 5,
  "hosts": [{ "name": "Beta University", "username": "betauniversity", "twitter": "UofBeta", "linkedin": "/school/university-of-beta", "website": "https://www.betauniversity.org/" }],
  "calendarName": "Beta University Events",
  "calendarUrl": "https://lu.ma/Beta-events",
  "coverImageUrl": "https://images.lumacdn.com/uploads/ag/7b2256b3-...png",
  "isFree": true,
  "price": null,
  "priceCurrency": null,
  "isSoldOut": false,
  "spotsRemaining": null,
  "requiresApproval": true,
  "registrationStatus": "open",
  "guestCount": 676,
  "ticketCount": 676,
  "visibility": "public",
  "scrapedAt": "2026-08-07T22:07:14.001Z"
}
```

Paid events fill in the price. Three real rows from the same run:

| Event | Price | Starts |
|---|---|---|
| How to Build a Regenerative Future for Humanity & Nature | $15 USD | 2026-08-12 17:30 |
| Does America Have a Housing Crisis? Looking Beyond the Headlines | $27 USD | 2026-08-12 19:00 |
| Matrescence: How Motherhood Rewires the Brain | $27 USD | 2026-08-12 19:00 |

Turn on **Fetch the full description and ticket tiers** and each row also gets `description` (the
event write-up as plain text), `categories` (Luma's own tags, e.g. `["AI","Crypto"]`) and
`ticketTypes` (every tier with its price and how many are registered).

***

### Input

| Field | What it does |
|---|---|
| `startUrls` | Any lu.ma links. Event pages (`https://lu.ma/beta-fdnw`), city pages (`https://lu.ma/sf`), community calendars (`https://lu.ma/Beta-events`), category pages (`https://lu.ma/ai`). Bare slugs work too. |
| `cities` | Discover cities by slug (`sf`, `nyc`, `london`, `berlin`, `tokyo`, `bengaluru`) or plain name (`San Francisco`). Luma runs discover pages for 87 cities. |
| `searchQuery` | Keyword filter applied to every city and calendar feed, e.g. `hackathon`. |
| `category` | `tech`, `ai`, `crypto`, `climate`, `food`, `arts`, `fitness`, `wellness`. Global feed only. |
| `period` | `future` (default) or `past`. Only affects community calendars. |
| `includeDetails` | Adds description, category tags and ticket tiers. One extra request per event. |
| `maxItems` | Hard cap on rows. You pay per row returned. |

Two ways to start:

```json
{ "cities": ["sf", "nyc"], "maxItems": 100 }
```

```json
{ "startUrls": ["https://lu.ma/Beta-events"], "period": "past", "maxItems": 50 }
```

***

### What this does NOT do

Read this part before you buy.

- **A city feed is not an archive.** Luma's discover page only serves upcoming events, and it runs
  out. San Francisco returned 82, New York 70, London 52, Berlin 16 on the day we tested. If you
  want thousands of rows, list more cities — not a bigger `maxItems`.
- **Past events only work on community calendars.** Set `period: "past"` and pass a calendar URL.
  There is no past-events feed for a city.
- **About a third of street addresses are hidden by the organiser.** Luma lets hosts reveal the
  exact venue only to approved guests. 194 of 300 rows in our test run had a venue name; the other 106 had
  `addressIsHidden: true` with only the city and an approximate coordinate. We report the flag
  rather than guessing.
- **No guest lists.** `guestCount` is the number Luma shows publicly. Individual attendee names,
  emails and profiles are not scraped.
- **No private, unlisted or password-gated events.** If you cannot see it logged out, neither can
  this actor.
- **The category filter is global, not per-city.** Luma ignores a category when a city is also set,
  so `category` works on its own and the results skew to whatever region the request exits from.
- **Online-only events are rare here.** Every one of our 300 test rows was `offline`. Luma's city
  feeds are, by definition, geographic.

***

### Pricing

**$2.125 per 1,000 events** — $0.002125 per event returned — plus **$0.001 each time a run starts**.
Flat rate: no volume tiers, no plan gates, no minimum.

Sample rows, diagnostic rows, blocked requests and empty runs are never charged. A run with no
input returns one clearly labelled `_sample` row and costs you the start fee only. `includeDetails`
adds one request per event but does not change the price, so descriptions, category tags and full
ticket tiers cost the same $0.002125 per row.

**Where that sits on this store.** This is *not* the cheapest Luma scraper listed:
`matyascimbulka/luma-event-scraper` (50 monthly users) charges $0.03 per 1,000 on its lowest tier.
What you get for the difference is the row shown above — UTC and event-local start/end times with
the IANA timezone, geocoded coordinates plus an explicit `addressIsHidden` flag, every host with
their social links, ticket tiers with currency handled correctly for zero-decimal currencies, and
public guest counts. If raw price per row is your only criterion, go and read every listing's
pricing tab. We would rather tell you that than pretend.

***

### FAQ

**What is the Luma API and can I use it for free?**
Lu.ma has an official API, but it is scoped to calendars you own and needs a Luma Plus plan and an
API key. There is no public endpoint for browsing other people's events. This actor reads the same
public data the website shows a logged-out visitor.

**How do I scrape all events in a city from lu.ma?**
Put the city slug in `cities` — `sf`, `nyc`, `london`, `berlin`, `tokyo`, `singapore`, `bengaluru`,
`la` and 79 others. You will get everything Luma currently lists as upcoming there, typically
50–90 events.

**Can I get Luma event attendee or guest data?**
You get the public `guestCount` and `ticketCount` per event. You do not get individual attendees.
Names and emails of registrants are private to the organiser and this actor does not touch them.

**Does it return ticket prices?**
Yes. `isFree` is always set. Paid events carry `price`, `priceCurrency`, `priceMax` (when tiers
vary), `isSoldOut` and `spotsRemaining`. With `includeDetails` on you also get every ticket tier by
name. `price` is in whole currency units and the conversion respects zero-decimal currencies, so a
2,500 yen ticket comes back as `2500 JPY`, not `25`. Our last run returned USD, GBP, EUR, JPY and
SGD prices side by side.

**Why is `price` null when `isFree` is true but `priceMax` has a number?**
That is Luma's "Free – £15" pattern: the entry tier is free and there are optional paid tiers. The
row is telling you the cheapest ticket costs nothing and the dearest costs `priceMax`.

**Can I monitor a specific community's calendar?**
Yes — paste the calendar page, e.g. `https://lu.ma/Beta-events`. Schedule the run daily and diff on
`eventId`. Calendars are the only source that also exposes past events.

**What timezone are the dates in?**
`startAt` and `endAt` are UTC ISO-8601. `timezone` is the event's IANA zone, and `startAtLocal` /
`endAtLocal` are already converted to it, so you do not have to do the maths.

**Does it need a proxy or a login?**
No. No Luma account, no cookies, no API key. The actor brings its own egress.

**How fast is it?**
300 events across 10 cities finished in 29 seconds. A single event URL takes about 3 seconds.

**Which fields are empty and why?**
`venueName` / `addressFull` are null when the organiser hides the address (35% of our test run) —
`addressIsHidden` tells you which. `description`, `categories` and `ticketTypes` are null unless you
switch on `includeDetails`.

***

### Notes

Built and maintained by Dami Studio. If Luma changes something and rows stop coming back, the actor
returns a diagnostic row explaining what broke instead of silently charging you for nothing.

# Actor input Schema

## `startUrls` (type: `array`):

Paste any lu.ma link, one per line. Event pages (https://lu.ma/beta-fdnw), city pages (https://lu.ma/sf), community calendars (https://lu.ma/Beta-events) and category pages (https://lu.ma/ai) are all understood. A bare slug works too.

## `cities` (type: `array`):

Luma discover cities to pull upcoming events from. Use the slug (sf, nyc, london, berlin, tokyo, bengaluru) or the plain name ("San Francisco"). Luma runs discover pages for 87 cities.

## `searchQuery` (type: `string`):

Optional keyword. Applied to every city and calendar feed above, for example "hackathon", "founders", "yoga".

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

Optional Luma category. Only applies to the global feed (use it without cities); Luma ignores a category filter on a city page.

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

Hard cap on rows returned across every target (1-5000). You are charged per event returned. A single city's discover feed holds roughly 70-90 upcoming events, so add more cities for bigger runs.

## `period` (type: `string`):

Only affects community calendar pages. Luma city feeds are always upcoming-only.

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

Off by default. When on, the actor makes one extra request per event to add the event description, Luma's own category tags and every ticket tier with its price. Slower, and the per-event price is unchanged.

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

Optional. The actor already uses its own egress; leave this alone unless you need to exit from a specific network.

## Actor input object example

```json
{
  "startUrls": [
    "https://lu.ma/sf"
  ],
  "cities": [],
  "category": "",
  "maxItems": 50,
  "period": "future",
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {
    "startUrls": [
        "https://lu.ma/sf"
    ],
    "cities": [],
    "searchQuery": "",
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/luma-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 = {
    "startUrls": ["https://lu.ma/sf"],
    "cities": [],
    "searchQuery": "",
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/luma-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 '{
  "startUrls": [
    "https://lu.ma/sf"
  ],
  "cities": [],
  "searchQuery": "",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call dami_studio/luma-events-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/luma-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/0FST4w3ofcuwjCgMC/builds/VEhiIO0cv5w3gQItG/openapi.json
