Quick answer
Meetup has no public, callable API — every group, event-listing, and event-detail page ships its data as a server-rendered Apollo GraphQL cache buried inside <script id="__NEXT_DATA__">. Reading it isn't a matter of grabbing one JSON key: the cache is a normalized store of {"__ref": "Type:id"} pointers, and the query keys that hold your data change shape on every single page load. The Meetup Group Scraper resolves that cache correctly — organizer identity, venue geo, RSVP counts, past and upcoming events — for $0.002 per result plus a $0.005 run-start charge, $2.005 for 1,000 events.
The cache key you need isn't fixed — you have to pattern-match for it 🔑
Apollo's normalized cache doesn't store events under a clean, static key. It stores it under something like events({"filter":{"status":["UPCOMING"]},"sort":"ASC"}) — the full serialized query variables baked directly into the key string, which differ from page to page and even between a group's upcoming-events connection and its past-events connection on the same page. An exact-key lookup breaks the moment Meetup changes an unrelated query parameter upstream.
The parser doesn't look for an exact key. It scans the cache object for any key starting with events( and containing "sort":"ASC" for upcoming events, or "sort":"DESC" for past events — prefix-plus-substring matching instead of an exact match. That distinction matters because the same Group entity also carries unrelated one-off connections (probe queries with "first":1 and no sort argument at all) that would otherwise get mistaken for the real events list.
A first-page read is quietly incomplete — so we detect that and fetch a second page 🎯
Here's the trap that would ship wrong data silently: the group and search-listing pages both include enough of each Event entity to look complete — title, date, venue name — but neither one carries the venue's lat/lon coordinates, and search-origin events don't resolve an organizer at all from the listing page alone. Only the event-detail page's Venue entity carries coordinates.
If the parser just extracted whatever the first page gave it, every row from a /find/ search would ship with a populated-looking venue_name right next to a null venue_lat/venue_lon — technically not wrong, but silently incomplete in a way nothing about the response would flag. Instead, a needs_detail_hop() check runs per event: it hops to the event-detail page whenever endTime is missing, whenever a present venue lacks coordinates, or whenever neither the event's own hosts nor the group's organizer resolve an identity. Group-URL-origin events with venue and organizer already resolved skip the extra hop entirely — the cost only lands where the data genuinely requires it.
What we handle for you 🛡️
-
We rotate browser fingerprints —
curl-cffiimpersonation across Chrome, Firefox, and Safari TLS profiles. - We rotate residential proxies through Apify Proxy — fresh session and exit IP on every block.
-
We retry with exponential backoff on
408 / 429 / 5xx, up to 5 attempts per page, honoringRetry-After. - We resolve the Apollo cache correctly — prefix-plus-substring key matching instead of a brittle exact-key lookup that breaks on unrelated upstream changes.
- We detect incomplete first-page reads and issue a second, targeted fetch only when venue coordinates or organizer identity are genuinely missing.
- You pay only for results that land. No data, no charge, beyond the small run-start fee.
Full output schema 📦
Twenty-two fields per event:
| Field | Type | Notes |
|---|---|---|
event_id |
string | Meetup Event.id
|
event_url |
string | Canonical event URL |
event_name |
string | Event title |
group_name / group_url
|
string | Hosting group |
organizer_name |
string | null | Resolved via detail-hop when the listing page doesn't carry it |
date_time_start / date_time_end
|
string | null | ISO-8601 |
timezone |
string | null | IANA timezone |
is_online |
bool | True for online-only events |
venue_name / venue_address / venue_city / venue_state / venue_country
|
string | null | Null when the event is online or the venue is hidden |
venue_lat / venue_lon
|
float | null | Only ever populated via the event-detail page |
rsvp_count |
int | Aggregate count — never individual attendee identities |
max_tickets |
int | null | Capacity, if set |
is_free |
bool | True when no fee is configured |
fee_amount / fee_currency
|
float | string | null | Ticket fee, when present |
matched_via |
string |
group_url or location_topic_search
|
scraped_at |
string | ISO-8601 UTC timestamp |
Who this is for
B2B event-lead prospecting — organizer identity and RSVP count as a warm-signal filter before outreach.
Community and ecosystem research — re-run against known group URLs over time to track a niche's activity trend.
Sponsorship and field-marketing sizing — audit a community's event cadence and typical RSVP volume before committing sponsorship budget.
Competitive community analysis — compare event frequency and attendance across groups in the same space.
Frequently asked questions
Does this scrape individual RSVP identities?
No. rsvp_count is an aggregate number only — this Actor never emits individual attendee names or PII.
Why do some rows need an extra request and others don't?
Group-URL-origin events often already carry a resolved organizer and venue coordinates from the listing page. Search-origin events, and any event missing endTime or venue coordinates, trigger one targeted detail-page fetch to fill the gap — the extra cost is scoped to exactly the events that need it.
Why is Meetup's data structured as a GraphQL cache instead of a normal API?
Meetup renders every page server-side with Next.js and embeds the Apollo cache used to hydrate the React app client-side. There's no separately callable public REST or GraphQL endpoint — the cache inside the HTML response is the only data surface.
Do I need a Meetup login?
No. All four source surfaces — group page, group events, event detail, and /find/ search — return complete data unauthenticated.
What does 5,000 events cost?
$10.005 — 5,000 × $0.002, plus the $0.005 run-start charge.
Try it
Live on the Apify Store: Meetup Group Scraper.
Feed it group URLs — or a location and topic — and get back structured event rows with organizer, venue geo, and RSVP data resolved correctly, not silently incomplete. Pay-per-event, no subscription.
Built by Devil Scrapes — we build scrapers for the targets that fight back.
Top comments (0)