Luma Cli Lightweight
Pricing
from $10.00 / 1,000 results
Luma Cli Lightweight
Under maintenanceLightweight playwright based on Luma Scrapper. Optimized for agents and project modularity on Local and VPS environments.
Pricing
from $10.00 / 1,000 results
Rating
0.0
(0)
Developer
New Fish
Actor stats
0
Bookmarked
1
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
luma-cli
A lightweight CLI tool for scraping event data and guest profiles from lu.ma.
Setup
Requires Node.js >= 18.3 and a cloned copy of this repo.
git clone git@github.com:profishional/luma-cli.gitcd luma-clinpm installnpx playwright install chromiumnpm link
npm link makes the luma command available globally. Do not move the directory after linking — the global command symlinks to this location.
Authentication
Some commands require a saved login session. Run this once per machine:
$luma auth
A browser window opens. Log in to lu.ma, then close the window. Your session is saved to luma-auth.json (gitignored, never committed).
Re-run luma auth if you see Auth session expired.
Commands
luma event <url> # Scrape event info (no auth required)luma guests <url> # Scrape guest listluma scrape <url> # Scrape event info + guests in one sessionluma profile <url> # Scrape user profile (name, bio, stats, socials)luma hosted-events <profile-url> # Scrape hosted events from a profileluma calendar <url> # List events on a calendar (lu.ma/superteam) or location/community page (lu.ma/Lisbon).[--period future|past|all] # Default: all. Use future for upcoming-only (much faster on big calendars).# Auth optional; admins also see private events on calendars they own.luma past-events [--status going|all] # Scrape your past attended events (default: going)luma upcoming [--status going|all] # Scrape your upcoming events (default: going)luma chats # List all your chatsluma chat-messages <partial-name> # Get messages from a chat by partial name[--limit <n>] # Max messages to return (default: all)
All commands output JSON to stdout. Progress is printed to stderr.
Examples
luma event https://lu.ma/[slug]luma guests https://lu.ma/[slug]luma scrape https://lu.ma/[slug]luma profile https://luma.com/user/[name]luma hosted-events https://luma.com/user/[name]luma calendar https://luma.com/[calendar-slug]luma calendar https://luma.com/[calendar-slug] --period future # upcoming-only (skip past)luma calendar https://luma.com/Lisbon --period future # location/community pageluma past-eventsluma past-events --status allluma chatsluma chat-messages "cursor"luma chat-messages "cursor" --limit 50
Pipe to jq for filtering:
luma guests https://lu.ma/bf01c9oe | jq '.guests[].name'luma scrape https://lu.ma/bf01c9oe | jq '.event.title'luma past-events | jq '.events[] | select(.attendees > 100)'luma calendar https://luma.com/[slug] | jq '. as $d | $d.events[] | select(.user_api_id != $d.calendar.personal_user_api_id) | {title, url, user_api_id}' # events whose creator differs from the calendar owner (ownership audit)luma chats | jq '.chats[] | select(.unread)'luma chat-messages "cursor" --limit 10 | jq '.messages[] | {author, authorUrl}'
Output Shapes
// luma event <url>{ title, location, datetime, description, guestCount }// datetime: "2026-03-21T10:00" (event's local timezone, minute precision)// guestCount: total attendees on the event// luma guests <url>{stats: {count, // guests actually returned (≤ 10 when source="featured")with_socials,guestCount, // total attendees on the event (from SSR)url, fetchedAt,source // "api" = full list (user must be going) | "featured" = 10 max},guests: [{name, url, api_id, username, bio, avatar_url, is_verified, timezone,socials: { instagram, twitter, tiktok, linkedin, youtube, website }}]}// luma scrape <url>{event: { title, location, datetime, description, guestCount },stats: { count, with_socials, guestCount, url, fetchedAt, source },guests: [{ name, url, api_id, username, bio, avatar_url, is_verified, timezone, socials: { ... } }]}// luma profile <url>{name,bio, // bio text, null if empty/unsetstats: { hosted, attended, together },socials: { instagram, twitter, tiktok, linkedin, youtube, website }}// luma hosted-events <profile-url>{stats: { count, url, fetchedAt },events: [{title, url, datetime, end_datetime, location,api_id, cover_url, event_type, location_type, calendar_api_id}]}// datetime/end_datetime are in the event's timezone, minute precision.//// Scope: this command returns events where the target user is a primary host// on a publicly-listable event — the same set lu.ma itself shows in the "View// All" modal on that profile. It does NOT include:// - private/unlisted events (even when you're the host, logged in as yourself)// - events on a calendar you admin but were created by someone else// - events where you're a co-host on someone else's calendar// The `event_hosted_count` badge on a Luma profile can be higher than this list// for those reasons — that counter is inflated server-side and the modal shows// fewer rows too. For calendar-scoped coverage (including private events on// calendars you admin), use `luma calendar <calendar-url>`.// luma past-events [--status going|all]// luma upcoming [--status going|all]{stats: { count, statusFilter, url, fetchedAt },events: [{title, url, datetime, end_datetime, location, attendees, status,api_id, cover_url, event_type, location_type, visibility,calendar_api_id, user_api_id,hosts: [{ name, url, api_id, username }] // minimal — use `luma profile <url>` to expand one}]}// datetime/end_datetime: minute precision in the event's timezone// attendees: exact guest_count from the event (not estimated)// status: "Going" | "Invited" | "Waitlist" | "Pending" | "Declined" | null// With --status going, only "Going" events are returned.// visibility: "public" | "private" | "unlisted"// user_api_id: the account that created the event (useful for ownership audits)// luma calendar <url> [--period future|past|all]//// Two URL types are supported. The output has either `calendar` or `place` —// never both — depending on which the URL points at://// 1) Calendar pages (lu.ma/superteam, lu.ma/breakpoint):{calendar: {name, slug, api_id, description_short,access_level, // "public" | "private" | ...personal_user_api_id, // the user who "owns" the calendar (null for non-personal calendars)avatar_url, cover_image_url,instagram_handle, twitter_handle, linkedin_handle, website},stats: { count, period, url, fetchedAt },events: [{title, url, datetime, end_datetime, location, attendees, status,api_id, cover_url, event_type, location_type, visibility,calendar_api_id, user_api_id,hosts: [{ name, url, api_id, username }]}]}// Anonymous access returns only public events. A logged-in calendar admin also// sees private/unlisted events on that calendar.// `user_api_id` is the data-quality hook: events where this differs from// `calendar.personal_user_api_id` were created under someone's personal account// rather than the calendar account.//// 2) Location / community discover pages (lu.ma/Lisbon, lu.ma/SF, …):{place: {name, slug, api_id, // api_id starts with "discplace-"description, timezone, event_count,geo_continent, geo_continent_name,avatar_url, cover_image_url},stats: { count, period, url, fetchedAt },events: [ /* same shape as above */ ]}// Discover pages are fully public — auth makes no difference.// `--period future` is the common case here ("what's coming up in Lisbon?")// and avoids fetching the past-events backlog.// luma chats{stats: { count, myUserId, fetchedAt },chats: [{name, eventUrl, // event URL for group chats, null for DMsapi_id, type, // type: "group" | "direct"participants,lastMessage, lastMessageAt, unread}]}// luma chat-messages <partial-name> [--limit <n>]{stats: { count, query },name, eventUrl, // event URL if group chat, null for DMsmessages: [{author, // "me" or display nameauthorUrl, // "https://lu.ma/<username>" or "https://lu.ma/user/<id>", null for selftext,timestamp // "2026-04-16T10:21"}]}
On a New Machine
git clone git@github.com:profishional/luma-cli.gitcd luma-clinpm installnpx playwright install chromiumnpm linkluma auth
Notes
luma-auth.jsonstores your login session — treat it like a password, never commit it- Data is sourced from lu.ma's internal API and the page's
__NEXT_DATA__SSR payload, not DOM scraping — so output fields are typed and less likely to break on redesigns. The browser (Playwright + Chromium) is still needed to carry the session cookies into the API calls. - A 1.5s delay is added between paginated requests to avoid hammering their servers
- Guest lists: ~100 per API page. A 1000-guest event takes ~15–30s. If you're not going to the event, only the 10
featured_guestsfrom the page SSR are available (stats.source: "featured");stats.guestCountstill reports the true total. - Past/upcoming/hosted events: ~50 per API page. A user with 300+ past events takes ~20–40s. Private events the user can't see publicly are filtered out by lu.ma server-side.
luma calendarruns without auth for public calendars and location/community discover pages (e.g., lu.ma/Lisbon). For calendars you admin, passluma-auth.json(automatic when the file exists) to also see private/unlisted events. On big calendars (Superteam has ~1700 past events) prefer--period future— it skips the past fetch entirely and finishes in seconds instead of minutes.
Apify Actor Pricing
Custom pay-per-event charges configured in Apify Console. Price increases require 14-day notice and can only change once per month. Decreases are instant.
Adding a new charge event —
main.mjscallsActor.charge({ eventName: ... }). Every event name used there must exist in the Apify Console monetization panel before the actor runs, otherwise the run fails at the firstActor.chargecall. When you add a new command that charges a new event (e.g.,calendar-eventwas added with thecalendarcommand), remember to add the row in the Apify Console too.
| Event name | Charged when | Per | Price |
|---|---|---|---|
event-info | event or scrape command | 1 per run | $0.01 |
guest | guests or scrape command | 1 per guest | $0.03 |
profile | profile command | 1 per run | $0.02 |
hosted-event | hosted-events command | 1 per event | $0.01 |
calendar-event | calendar command | 1 per event | $0.01 |
past-event | past-events command | 1 per event | $0.01 |
upcoming-event | upcoming command | 1 per event | $0.01 |
chat | chats command | 1 per chat | $0.01 |
chat-message | chat-messages command | 1 per run | $0.01 |
apify-actor-start | any run | 1 per start (scales with RAM) | $0.005 |
apify-default-dataset-item is disabled — charging is handled by custom events above.
Primary event: guest

