# Luma Events Scraper (lu.ma) – All Events in a City (`lokalapi/luma-events`) Actor

All public Luma (lu.ma) events in a city, not just the featured list (SF: ~450 a week instead of ~30). By city, category, keyword or calendar: time zone, venue, prices incl. JPY/KRW, tickets, organizer. No duplicates, no personal data.

- **URL**: https://apify.com/lokalapi/luma-events.md
- **Developed by:** [lokalapi Data](https://apify.com/lokalapi) (community)
- **Categories:** Travel, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 events

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

## Luma Events Scraper (lu.ma) – All Events in a City, Not Just Luma's Featured List

Get **all public events in a city from Luma (lu.ma / luma.com)** – not just the short featured list on Luma's city page. In San Francisco that is **about 450 events a week instead of about 30**. Search by **city**, **category** (AI, tech, crypto, arts, climate, wellness …), **keyword** or **Luma calendar**, filter by date, price and format, and export to JSON, CSV or Excel. Fast HTTP requests (no browser), no login, and **no personal data**: no attendees, no host profiles, no contact details.

Typical uses: event calendars and newsletters, city or industry event aggregators, market and competitor research ("which AI events happen in Singapore next month?"), sponsorship and venue scouting, and AI agents that need up-to-date event data.

### Why this Actor

- **All events in a city, not just the featured list.** Luma's city page shows a short curated list. This Actor returns every public event in the area around the city (default ±50 km, adjustable), plus the featured list. Want only the curated list? Set *City events* to *Featured only*.
- **No duplicates, and duplicates are never charged.** An event found by several inputs (two cities, a city and a category, several keywords) is saved and charged once.
- **No personal data, built for GDPR-conscious teams.** No host or speaker names, no profiles or social links, no guest lists, no user IDs. Organizers appear only as organizations. Contact details inside descriptions are removed. An automated test checks every output field.
- **Correct prices.** Amounts in currency units for every currency, including currencies without cents such as JPY and KRW (¥2,000 is `2000`, not `20`). The price range covers tickets on sale now, so an expired early bird does not show up as the lowest price.
- **Pay only for saved events:** $0.003 per event with details, $0.002 without (see Pricing).

### Compared with other Luma scrapers

Measured on Apify on 17 October 2026: the same week of events (18–24 October), all Actors started at the same time.

| Events found in one week | This Actor | Most-used Luma scraper on Apify |
|---|---|---|
| San Francisco | **454** (of 455 in total) | 30 (Luma's featured list only) |
| Singapore | **83** (of 83) | 11 |

**0 % failed or aborted runs** in all our test runs, and no duplicate events.

### What you get per event

| Field | Example |
|---|---|
| `name`, `url` | "AI Agents Builders Night", `https://luma.com/abc123` |
| `startAt`, `endAt` (UTC), `startLocal`, `timezone` | `2026-11-05T11:00:00.000Z`, `2026-11-05T19:00`, `Asia/Singapore` |
| `locationType` | `offline` (in person) or `online` |
| `city`, `region`, `country`, `countryCode` | Singapore, Singapore, Singapore, SG |
| `address`, `latitude`, `longitude`, `locationPrecision` | Street address only if the organizer made it public; otherwise city plus approximate coordinates |
| `isFree`, `priceMin`, `priceMax`, `currency` | `false`, `15`, `25`, `SGD` – price range of the tickets on sale now (as shown on Luma), in currency units (¥2000 is `2000`, $19.99 is `19.99`) |
| `ticketTypes` | Name, price, currency, flexible price, approval needed, `isAvailable` (false for expired early birds, sold-out or not yet open tickets) |
| `isSoldOut`, `spotsRemaining`, `requiresApproval`, `registrationOpen` | Ticket availability |
| `guestCount` | Number of registered guests (a count, no names) |
| `organizer` | Organization calendar: name, Luma calendar URL, website, verified. `null` for events on a person's own calendar |
| `categories`, `tags` | Luma categories (e.g. AI, Tech), calendar tags |
| `description` | Plain-text excerpt (about 300 characters), see FAQ |
| `coverImageUrl` | Link to the cover image on Luma |
| `source`, `scrapedAt` | Which input found the event, time of the run |

### How to use it

**1. Events in a city** – put one or more cities into *Cities*, e.g. `singapore`, `jakarta`, `sf`, `nyc`, `london`, `berlin`. You get **all public Luma events within ±50 km** of the city center (the map on luma.com; change it with *Radius (km)*), plus Luma's own featured list for the city, which also has online events. Set *City events* to *Featured only* if you want just that short list. Luma covers about 90 cities, listed on [luma.com/discover](https://luma.com/discover).

**2. A topic in a city** – add *Categories* such as `ai`, `tech`, `crypto`, `arts`, `climate`, `fitness`, `wellness`, `food` to get only those events in the area around each city (same radius).

**3. Keyword search** – add *Keywords* such as `hackathon` or `founders`. By default an event matches only if a keyword appears in its title or description. Choose *Luma search* for Luma's own, broader search.

**4. All events of a community or company** – put its Luma calendar into *Luma URLs*, e.g. `https://luma.com/digitalocean`. With a *From date* in the past you also get past events. Single event URLs work as well.

Example inputs:

```json
{ "cities": ["singapore", "jakarta"], "categories": ["ai", "tech"], "startDate": "+0 days", "endDate": "+30 days", "maxEvents": 200 }
```

```json
{ "cities": ["sf"], "keywords": ["hackathon"], "onlyFree": true }
```

```json
{ "urls": ["https://luma.com/digitalocean"], "startDate": "2026-01-01", "endDate": "2026-12-31" }
```

### Example output

```json
{
  "eventId": "evt-AbCdEf123456789",
  "url": "https://luma.com/abc123",
  "name": "AI Agents Builders Night",
  "startAt": "2026-11-05T11:00:00.000Z",
  "endAt": "2026-11-05T14:00:00.000Z",
  "startLocal": "2026-11-05T19:00",
  "timezone": "Asia/Singapore",
  "locationType": "offline",
  "city": "Singapore",
  "region": "Singapore",
  "country": "Singapore",
  "countryCode": "SG",
  "address": "Example Hall, 1 Example Road, Singapore 012345",
  "latitude": 1.2995,
  "longitude": 103.7876,
  "locationPrecision": "exact",
  "isFree": false,
  "priceMin": 15,
  "priceMax": 25,
  "currency": "SGD",
  "isSoldOut": false,
  "spotsRemaining": null,
  "requiresApproval": false,
  "registrationOpen": true,
  "guestCount": 86,
  "organizer": {
    "name": "Example Dev Community",
    "calendarUrl": "https://luma.com/exampledev",
    "website": "https://exampledev.org",
    "isVerified": true
  },
  "categories": ["AI", "Tech"],
  "tags": [],
  "ticketTypes": [
    { "name": "Early bird", "type": "fiat-price", "price": 15, "minPrice": null, "currency": "SGD", "isFlexiblePrice": false, "requiresApproval": false, "isAvailable": true },
    { "name": "Standard", "type": "fiat-price", "price": 25, "minPrice": null, "currency": "SGD", "isFlexiblePrice": false, "requiresApproval": false, "isAvailable": true }
  ],
  "description": "Join builders working on AI agents for an evening of short demos, lightning talks and networking. Bring a laptop if you want to show what you are working on. Food and drinks provided…",
  "descriptionIsExcerpt": true,
  "coverImageUrl": "https://images.lumacdn.com/uploads/example/cover.png",
  "lumaCity": "Singapore",
  "source": "city:singapore category:ai",
  "scrapedAt": "2026-10-13T08:00:00.000Z"
}
```

The run's key-value store also has an `OUTPUT` record: events per input source, inputs that were skipped and why (e.g. an unknown city), and the charged events.

### Pricing

Pay per event, no subscription. You pay only for events that are actually saved to your dataset:

| *Include details* | Charged per saved event | Per 1,000 events |
|---|---|---|
| **On** (default): list data + description excerpt, all ticket types, categories | $0.002 event + $0.001 details = **$0.003** | **$3** |
| **Off**: list data only (date, place, price range, organizer, availability) | **$0.002** | **$2** |

- The details charge applies only to events saved with their details. If Luma does not return the details for an event, the event is saved with list data and costs $0.002.
- Events outside your filters, duplicates (the same event found by several inputs) and inputs that find nothing are not charged. Apify adds its tiny Actor start fee ($0.00005) per run.
- The run stops before it would exceed the maximum cost per run you set in Apify (default $5 ≈ 1,666 events with details).

### Speed and reliability

- Plain HTTP requests, 256 MB memory, no browser. Measured on Apify: 500 events without details in about 5 seconds; with details (one extra request per event) about 3–4 events per second, e.g. 500 events in about 2.5 minutes.
- Requests are throttled (at most 3 in parallel, about 4 per second) and retried on temporary errors, so runs do not fail because of a single slow response.
- An invalid input (unknown city, wrong URL) is skipped with a clear message in the run status and in `OUTPUT`; the other inputs still run.

### FAQ

**No personal data – what exactly is left out?**
Attendee and guest lists, host and speaker profiles, user IDs, social media handles, e-mail addresses and phone numbers. The organizer is only included when the event belongs to an organization's Luma calendar (name, calendar URL, website). Events on a person's own calendar have `organizer: null`. Contact details that appear inside descriptions (e-mails, phone numbers, profile links, @handles) are removed. Street addresses are only returned when the organizer made them public on Luma; "guests only" addresses are not requested. `guestCount` is just a number. Luma user profile URLs are rejected as input.

**Data stays on Luma – why only a description excerpt?**
Event descriptions are the organizers' own texts. By default you get a plain-text excerpt of about 300 characters plus the event `url`, so readers find the full text, images and registration on [Luma](https://luma.com), the original source. Images are linked, never downloaded or re-hosted. If you need the full text (e.g. for search or classification), turn on *Full description text*. Make sure your use of the text is covered, for example by linking back to the event and not republishing descriptions in full.

**Where does the data come from?**
From the public pages and the public JSON data that luma.com itself loads in the browser, without login or cookies. The Actor follows Luma's robots.txt and keeps the request rate low. It is not affiliated with or endorsed by Luma. Luma's terms of use apply to how you use the data: [luma.com/terms](https://luma.com/terms).

**Why do some cities return only a few events?**
The Actor returns the public events that organizers listed on Luma in the area around the city (default ±50 km). Smaller cities simply have fewer of them (Jakarta: about 25 a month, Singapore about 235, San Francisco about 1,000). For a specific community, use its calendar URL.

**Can I get past events?**
Yes for calendars: set *From date* to a past date. City and category feeds only contain upcoming events.

**Can I use it from an AI agent?**
Yes. The Actor works with the [Apify MCP server](https://mcp.apify.com) and the Apify API. Typical agent prompt: "Find AI events in Singapore next week that are free" → `{"cities":["singapore"],"categories":["ai"],"endDate":"+7 days","onlyFree":true}`.

**Something is missing or broken?**
Open an issue on the Issues tab and include your input.

# Actor input Schema

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

Luma cities to get events from, e.g. <code>sf</code>, <code>nyc</code>, <code>london</code>, <code>singapore</code>, <code>jakarta</code>, <code>berlin</code>. Plain names like "San Francisco" or "New York" work too. Returns all public events in the area around the city (see "Radius") plus Luma's featured list for the city, or only the featured list (see "City events"). Luma covers about 90 cities; the list is on <a href="https://luma.com/discover" target="_blank">luma.com/discover</a>.

## `cityMode` (type: `string`):

<b>All events</b>: every public Luma event in the area around the city (see "Radius"), plus Luma's featured list for the city. <b>Featured only</b>: just the short list Luma shows on the city page (in San Francisco about 30 events a week instead of about 450).

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

Size of the area around each city for "All events" and for categories: Luma searches a square of ± this many km around the city center, like the map on luma.com. 50 km covers a metro area (e.g. San Francisco Bay Area); use 10–20 km for the city itself.

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

Only events of these Luma categories around each city (see "Radius"): <code>ai</code>, <code>tech</code>, <code>crypto</code>, <code>arts</code>, <code>climate</code>, <code>fitness</code>, <code>wellness</code>, <code>food</code>, <code>running</code>, <code>books</code>, <code>games</code>, <code>family</code>.

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

Search terms, e.g. <code>startup</code>, <code>hackathon</code>, <code>web3</code>. An event matches if one of the keywords appears in its title or description (see "Keyword matching").

## `keywordMatch` (type: `string`):

<b>Exact</b>: a keyword must appear in the event title or description. <b>Luma search</b>: Luma's own search, which also returns loosely related events (more results, less precise). Calendars always use exact matching.

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

Luma calendar pages (all events of a community or company, e.g. <code>https://luma.com/digitalocean</code>), single event pages, or city pages. User profile pages are not supported.

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

Earliest event start (UTC): <code>YYYY-MM-DD</code> or relative like <code>+7 days</code>. Default: today. A date in the past also returns past events of calendars.

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

Latest event start (UTC): <code>YYYY-MM-DD</code> or relative like <code>+30 days</code>. Default: 30 days after the start date.

## `locationType` (type: `string`):

In-person events only, online events only, or both.

## `onlyFree` (type: `boolean`):

Skip paid events.

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

Adds a description excerpt, all ticket types with prices and the event's categories (one extra request per event). <b>Price: on = $0.003 per saved event</b> ($0.002 event + $0.001 details), <b>off = $0.002 per saved event</b>. Only events saved to the dataset are charged. Turn off for a cheaper, faster list with date, venue, price range and organizer.

## `includeFullDescription` (type: `boolean`):

By default the description is a plain-text excerpt of about 300 characters plus the event URL, because event descriptions are the organizers' own texts. Turn on to get the full plain text, e.g. for search or classification; make sure your use of the text is covered (see FAQ). Needs "Include details".

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

Stop after this many events (1–5,000). Cost: up to maxEvents × $0.003 with details, × $0.002 without (e.g. 100 events ≤ $0.30). The run also stops before the maximum total charge you set for the run is exceeded.

## Actor input object example

```json
{
  "cities": [
    "singapore",
    "jakarta",
    "sf"
  ],
  "cityMode": "all",
  "radiusKm": 50,
  "categories": [
    "ai",
    "tech"
  ],
  "keywords": [
    "hackathon",
    "founders"
  ],
  "keywordMatch": "exact",
  "urls": [
    "https://luma.com/digitalocean"
  ],
  "startDate": "2026-11-01",
  "endDate": "+60 days",
  "locationType": "any",
  "onlyFree": false,
  "includeDetails": true,
  "includeFullDescription": false,
  "maxEvents": 50
}
```

# Actor output Schema

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

One item per public Luma event. Download as JSON, CSV or Excel.

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

Events per input source, skipped inputs with the reason, charged events and whether the run stopped at the maximum total charge.

# 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 = {
    "cities": [
        "sf"
    ],
    "maxEvents": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("lokalapi/luma-events").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 = {
    "cities": ["sf"],
    "maxEvents": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("lokalapi/luma-events").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 '{
  "cities": [
    "sf"
  ],
  "maxEvents": 50
}' |
apify call lokalapi/luma-events --silent --output-dataset

```

## MCP server setup

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

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/PBcPo2WOqWwUfIxFO/builds/8RBaE2ue9MWGtTNtO/openapi.json
