# Meetup Events Scraper (`deriverge/meetup-scraper`) Actor

Meetup events for a keyword within a radius of any city, with date, venue, RSVP count, ticket price and the hosting group's size. Searches are split by day, time of day and event type to get past the 200 results one Meetup search returns, and events off your keyword are dropped before you pay.

- **URL**: https://apify.com/deriverge/meetup-scraper.md
- **Developed by:** [deriverge s.r.o.](https://apify.com/deriverge) (community)
- **Categories:** Travel, Social media, Automation
- **Features:** Limited permissions
- **Stats:** 13 total users, 9 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 matching events

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Meetup Events Scraper

Meetup Events Scraper returns the public Meetup events that match a keyword within a radius of any point, one row per event: title, description, start and end time, venue address and coordinates, ticket price, RSVP count, and the hosting group with its size and rating. Enter a **Search keyword**, the center and a date range, and click **Start**. Only events that mention your keyword in the title, description, topics or group name are kept. Names of organizers and attendees are not collected. It costs $2.00 per 1,000 matching events on the Free plan ($1.00 on Business), and the $5 of monthly credit in Apify's Free plan covers about 2,500 matching events. A run that finds events also pays a search fee of $0.005.

### What data does it return?

| Field | Description |
|---|---|
| `eventId`, `eventUrl` | Meetup's ID of the event and the link to its page on meetup.com. |
| `title`, `description` | Title and description as the organizer wrote them; the description is in Meetup's Markdown. |
| `startsAt`, `endsAt`, `duration` | Local start and end time with the UTC offset, such as `2026-09-29T18:30:00-04:00`, and the length as an ISO 8601 duration, such as `PT2H`. |
| `eventType`, `isOnline` | `PHYSICAL`, `ONLINE` or `HYBRID`. `isOnline` is `true` for `ONLINE` only. |
| `status` | Meetup's status of the event, `ACTIVE` for an upcoming one. |
| `venueName`, `venueAddress`, `postalCode` | Venue as the organizer entered it. Online events usually carry the placeholder venue `Online event`. |
| `city`, `state`, `country` | Place of the venue, or of the hosting group when the event has no venue. The country code is lower case, such as `us`. |
| `latitude`, `longitude` | Coordinates of the venue in decimal degrees. See Limits for online events. |
| `groupName`, `groupUrlName`, `groupUrl`, `groupFoundedOn` | The hosting group, its short name in Meetup links, its page and the day it was founded. |
| `topics` | Meetup topics attached to the event, such as `UI/UX Design`. Often empty. |
| `feeAmount`, `feeCurrency` | Ticket price and currency, such as `13` and `USD`. Both are `null` for events without a fee. |
| `rsvpCount`, `capacity` | How many people have RSVPed, and the most the event accepts. `capacity` is `null` when the organizer set no limit. |
| `imageUrl` | Link to the event photo in full resolution, `null` when the event has none. |
| `groupMemberCount`, `groupRating`, `groupCategory` | Members of the hosting group, the average rating of its past events from 1 to 5 (`null` when unrated) and the category Meetup files it under, such as `Technology`. |
| `foundInSlice` | The search that found the event, such as `"tech"` for the first, unsplit search or `"tech" · in person` for a split one. |
| `scrapedAt` | When the event was read, as an ISO 8601 UTC timestamp. |

### How to scrape Meetup events

1. Enter a **Search keyword**. Meetup needs one, and broad English words such as `tech`, `yoga` or `startup` give the most events.
2. Set **Latitude** and **Longitude** of the center, New York City unless you change them, and a **Radius (miles)** from 1 to 100 (50 by default).
3. Set both **Start date** and **End date**, as `YYYY-MM-DD` or as moving dates: `today`, `tomorrow`, `yesterday` or an offset in days such as `+30`. A single date on its own is ignored.
4. Set **Maximum events** to cap the cost, and click **Start**.
5. The **Output** tab shows the events and exports them as CSV, Excel or JSON. The coverage report is the `COVERAGE_REPORT` record in the run's key-value store. From the API, send an input like this:

```json
{
  "query": "tech",
  "latitude": "51.5074",
  "longitude": "-0.1278",
  "radiusMiles": 50,
  "dateFrom": "today",
  "dateTo": "+30",
  "maxItems": 2000
}
```

### Example output

An event found by a search for `tech` around New York without dates, in a run on 11 October 2026, with the description shortened. It matched through the topic `Web Technology`.

```json
{
  "eventId": "316293021",
  "title": "Stripe developer meetup New York, October 2026 (In Person)",
  "description": "Join us on October 22nd for the Stripe New York developer meetup. This is an in-person event for anyone building with Stripe. ...",
  "startsAt": "2026-10-22T18:00:00-04:00",
  "endsAt": "2026-10-22T20:00:00-04:00",
  "duration": "PT2H",
  "eventUrl": "https://www.meetup.com/stripe-new-york/events/316293021/",
  "eventType": "PHYSICAL",
  "status": "ACTIVE",
  "isOnline": false,
  "venueName": "Stripe Office NY",
  "venueAddress": "28 Liberty St. Fl. 48  New York, NY 10005",
  "city": "New York",
  "state": "NY",
  "country": "us",
  "postalCode": "10005",
  "latitude": 40.707752,
  "longitude": -74.008705,
  "groupName": "Stripe New York",
  "groupUrlName": "stripe-new-york",
  "groupUrl": "https://www.meetup.com/stripe-new-york",
  "groupFoundedOn": "2024-11-21T05:25:38-05:00",
  "topics": [
    "Amazon Web Services",
    "SaaS (Software as a Service)",
    "Online Payments",
    "Web Development",
    "Web Technology"
  ],
  "feeAmount": null,
  "feeCurrency": null,
  "foundInSlice": "\"tech\"",
  "scrapedAt": "2026-10-11T12:38:09.568Z",
  "rsvpCount": 161,
  "capacity": 214,
  "imageUrl": "https://secure.meetupstatic.com/photos/event/a/7/e/9/highres_534582985.jpeg",
  "groupMemberCount": 926,
  "groupRating": 4.73,
  "groupCategory": "Technology"
}
```

### How much does it cost to scrape Meetup events?

| | Free plan | Starter | Scale | Business |
|---|---|---|---|---|
| 1,000 matching events | $2.00 | $1.60 | $1.30 | $1.00 |
| Search, once per run | $0.005 | $0.004 | $0.00325 | $0.0025 |

You pay for the events in the table and nothing else: compute time and proxies are included.

A run that returns 500 matching events costs $1.00 plus the $0.005 search fee on the Free plan, and $0.50 plus $0.0025 on Business. Events that do not mention the keyword are dropped before charging, and a run that finds no matching event costs nothing.

### Limits

- One Meetup search returns about 200 events at most. Without dates, the actor can only split a search into in-person and online events, so a run ends after a few hundred: `tech` around New York without dates gave 170 matching events on 26 September 2026.
- A run makes up to 400 requests to Meetup. September 2026 for `tech` in New York took 285 requests and about five minutes. In a large city, a range longer than about a month can use up the requests before every day is split, so run long ranges month by month; the coverage report lists what was left unread.
- A date range covers at most 180 days, counted from the start date. A longer range is cut there, and the log names the last day read.
- Dates are UTC days. A September run for New York began with events at 8 pm local time on 31 August and ended with events before 8 pm on 30 September.
- The keyword is matched as text, so `tech` also keeps events whose topics include `Biotechnology` or `Technology`. A keyword made only of words shorter than three letters, such as `ux` or `AI`, must appear as a whole word, and a few common abbreviations also match their long form, so `AI` keeps events under the topic `Artificial Intelligence`. In a keyword that also has a longer word, the short words are ignored.
- Meetup gives most online events the placeholder venue `Online event` with latitude `-8.521147` and longitude `179.1962`, a point in the Pacific Ocean. Use `isOnline` or `eventType` to tell them apart before you put events on a map.
- Meetup's topic index is in English. The log warns when Meetup does not know a keyword, and such a search can end without a single matching event.
- Descriptions are the organizer's own text and can contain names and profile links of speakers or hosts.
- If Meetup changes its API so that the query no longer fits, the run fails with an error.

### How it finds all events in a city

A single Meetup search stops after about 200 results and then reports that there is no next page. The actor therefore runs many narrow searches and merges the results by `eventId`:

1. A search that reaches the limit is split, first into the days of your date range, then into four six-hour windows, then into in-person and online events.
2. Searches that return 40 events or more are split the same way even below the limit, because Meetup's ranked search leaves out events that a narrower search returns.
3. Meetup sorts nearby events by how well they match the keyword and fills the rest of each page with other events. Every event is therefore checked against your keyword, and events that do not mention it in the title, description, topics or group name are dropped before charging.

In runs on 30 August 2026 for `tech` within 50 miles, covering all of September, this gave 754 matching events in New York, 849 in London and 138 in Prague. The New York run dropped 7,760 events that did not mention the keyword.

Every run writes a `COVERAGE_REPORT` record with `eventsReturned`, `eventsDiscarded`, `queryMatchRate`, `requestsMade`, `queryKnownTopics` (the topics Meetup files your keyword under, empty when Meetup does not know it) `truncatedSlices`, the searches that still reached the limit after the finest split, and `unreadSlices`, the searches left unread when the run used up its requests.

### FAQ

#### Is it legal to scrape Meetup?

The actor reads public event listings through Meetup's GraphQL endpoint, without logging in, without cookies and without a browser. Its query never asks for hosts, RSVPs, comments or member profiles, so the output describes events and groups; names appear only where an organizer wrote them into a description. You are responsible for how you use the data.

#### Why does a search need a keyword?

Meetup's event search does not work without one. To cover a whole city, run the actor with several broad keywords and merge the results by `eventId`, which stays the same for an event in every run.

#### Can I get attendee names or organizer contacts?

No. The query sent to Meetup asks only for the number of RSVPs and the size of the group, never for the people behind them, so names and contacts do not exist in the output.

#### Can I run it every week?

Yes. Save the input as a task with moving dates such as `today` and `+7`, and add a schedule; each run then covers the coming week. There is no new-only mode, so every run returns all matching events in its window.

### Related scrapers

- [Eventbrite Events Scraper](https://apify.com/deriverge/eventbrite-scraper)
- [Luma Events Scraper](https://apify.com/deriverge/luma-events-scraper)

### Support

This actor is built and maintained by deriverge s.r.o., a software company based in the Czech Republic. If a run fails or a field you need is missing, please open an issue in the **Issues** tab or write to us at info@deriverge.com. We respond in English and Czech. Runs can be scheduled in Apify Console or started from the **API** tab, which has examples for Python, JavaScript and cURL and works with Make, Zapier, n8n and the Apify MCP server. If the actor saves you time, a short review helps other people find it.

# Changelog

This Actor's version history is a separate document: https://apify.com/deriverge/meetup-scraper/changelog.md

# Actor input Schema

## `query` (type: `string`):

Keyword to search for, e.g. tech, music, yoga, startup. Meetup requires one: a broad word returns the widest set.

## `latitude` (type: `string`):

Centre of the search area. Defaults to New York City.

## `longitude` (type: `string`):

Centre of the search area. Defaults to New York City.

## `radiusMiles` (type: `integer`):

How far from the centre point to search.

## `dateFrom` (type: `string`):

First day to cover, YYYY-MM-DD. A date range is the strongest way to break through the result cap, so set it whenever you can. You can also give a moving date instead of a fixed one: today, tomorrow, yesterday, or a day offset such as +30 or -7. A saved task or a schedule then keeps covering the right days instead of going empty once the dates pass.

## `dateTo` (type: `string`):

Last day to cover, YYYY-MM-DD. You can also give a moving date instead of a fixed one: today, tomorrow, yesterday, or a day offset such as +30 or -7. A saved task or a schedule then keeps covering the right days instead of going empty once the dates pass.

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

Stop after this many events, so run cost stays predictable.

## Actor input object example

```json
{
  "query": "tech",
  "latitude": "40.7128",
  "longitude": "-74.0060",
  "radiusMiles": 50,
  "maxItems": 50
}
```

# Actor output Schema

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

Every event found, deduplicated by event ID.

## `coverage` (type: `string`):

What the run reached and what it could not, including any slice that stayed at Meetup's result ceiling after subdivision.

# 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 = {
    "query": "tech",
    "latitude": "40.7128",
    "longitude": "-74.0060",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("deriverge/meetup-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 = {
    "query": "tech",
    "latitude": "40.7128",
    "longitude": "-74.0060",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("deriverge/meetup-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 '{
  "query": "tech",
  "latitude": "40.7128",
  "longitude": "-74.0060",
  "maxItems": 50
}' |
apify call deriverge/meetup-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deriverge/meetup-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/8Sa1cqsHVX2cpthSm/builds/gaLbRpOUVyhSau0yz/openapi.json
