# Events Finder - Luma, Eventbrite & Meetup Tech Events (`luis.pinto/events-finder`) Actor

Discover and rank tech, AI, and founder events across Luma, Eventbrite, and Meetup. LLM scores each event against your intent prompt and dedupes across scheduled runs. Export data, run via API, schedule and monitor runs, or integrate with other tools.

- **URL**: https://apify.com/luis.pinto/events-finder.md
- **Developed by:** [Luis Pinto](https://apify.com/luis.pinto) (community)
- **Categories:** Lead generation, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.70 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Events Finder: Luma, Eventbrite & Meetup tech events

Discover, score, and dedupe tech, AI, and founder events across Luma, Eventbrite, and Meetup, ranked against your prompt.

### What does Events Finder do?

Events Finder is an Apify Actor that scrapes Luma, Eventbrite, and Meetup in parallel, unifies the results, and uses an LLM to score each event against your prompt and persona. A persistent dedup store skips anything seen in earlier runs, so scheduled runs never re-emit the same meetup.

- Scans Luma, Eventbrite, and Meetup in one run
- LLM-scored relevance via OpenRouter
- New-only emission across scheduled runs
- Multi-city: Lisbon, Berlin, San Francisco, New York, London, and more
- Pipes into Notion, Slack, Google Calendar, Zapier, and any Model Context Protocol (MCP) client
- Soft-fail per source: if one site breaks, the others still produce results

Recommendation: start with 1 city, 2 categories, and a tight prompt.

### What data can you extract?

Events Finder returns one unified record per event.

| Event data | Logistics | Relevance |
|---|---|---|
| Title and description | Start and end datetime | Score 0-100 |
| Organizer | City and venue | Match reasons (bullets) |
| Image URL | Online vs in-person | Tags |
| Event URL | Price and currency | Attendee estimate |
| Source platform | Time zone | First-seen timestamp |

Recommendation: pipe `score` and `matchReasons` into Notion or Slack.

### Can you use Events Finder to scrape Luma, Eventbrite, and Meetup?

Yes. All three platforms are scraped in one run and merged into one dataset. Each source is wrapped in a soft-fail handler: if Luma blocks the scraper, Eventbrite and Meetup still produce results, and the failing source emits an error item with `errorType`, `reason`, and `fix`.

Recommendation: keep all three sources enabled to maximize coverage.

### How does Events Finder work?

1. You provide cities, categories, a date range, and a prompt.
2. Events Finder scrapes Luma, Eventbrite, and Meetup in parallel.
3. Raw events are unified into one record shape with a stable ID.
4. The OpenRouter Apify Actor scores each event 0-100.
5. Events below `minScore` or already in the dedup store are skipped.
6. The dataset is sorted by score and optionally appended to Notion.

Recommendation: run once manually to tune `minScore`.

### Why use Events Finder?

| Feature | Other event aggregators | Events Finder |
|---|---|---|
| Platform coverage | One site at a time | Luma, Eventbrite, Meetup in one run |
| Deduplication | Manual tracking | Persistent dedup store |
| Relevance filtering | Keyword search | LLM scores your prompt |
| Personalization | Same digest for all | Persona + prompt per profile |
| Multi-city watch | Switch tabs | One run, many cities |
| Integrations | Email digest only | Notion, Slack, Zapier, MCP |
| Cost | Paid subscription | Pay-per-event, under USD 0.05 per run |

Recommendation: replace a weekly newsletter with a daily Events Finder schedule.

### What can you do with data after scraping?

- **Weekly digest**: pipe new high-score events into a Slack channel.
- **Notion event radar**: feed a Notion database ranked by score.
- **GTM event sourcing**: find meetups where your ICP gathers, then plan sponsorship outreach.
- **Travel networking**: trigger a one-shot run before each work trip.
- **Community curation**: power a public events page for your meetup.

Run hourly for fast-moving cities, daily for most users, weekly for stable categories. Use a different `dedupStoreName` per profile so schedules do not cross-contaminate.

Recommendation: start with one daily schedule per city, then split by category.

### How to use Events Finder

1. Log in to Apify Console.
2. Open the Events Finder Actor in Apify Store.
3. Fill in **Cities**, **Categories**, and your **Intent prompt**.
4. Optionally set **Date from** and **Date to** (defaults: today, +30 days).
5. Click **Start**. The first run takes 1 to 3 minutes.
6. Open the **Dataset** tab to see events sorted by relevance score.
7. To watch continuously, create a **Schedule** and connect Slack, Notion, or a webhook.

Recommendation: bookmark the first successful run, then duplicate per persona.

### How much will Events Finder cost?

Pay-per-event on the Apify platform plus a small OpenRouter LLM cost. A daily run with `maxEventsPerSource: 50` (up to 150 events scored) costs under USD 0.05. To cut cost, lower `maxEventsPerSource` to 10, keep `openai/gpt-4o-mini`, and pass your own `openRouterApiKey`.

Recommendation: check the **Pricing** tab before hourly runs.

### Input

| Field | Required | Default | Notes |
|---|---|---|---|
| `cities` | yes | `["Lisbon"]` | English city names |
| `categories` | yes | `["AI/ML"]` | Multi-select from 9 categories |
| `prompt` | yes | (none) | Free-text intent description |
| `persona` | no | `Generalist` | Founder, Engineer, PMM, Investor, etc. |
| `dateFrom` / `dateTo` | no | today / +30d | ISO `YYYY-MM-DD` |
| `minScore` | no | `60` | Drop events below this score |
| `maxEventsPerSource` | no | `50` | Per-source cap before scoring |
| `openRouterModel` | no | `openai/gpt-4o-mini` | Any OpenRouter model id |
| `openRouterApiKey` | no | (none) | Billed to your OpenRouter account |
| `dedupStoreName` | no | `events-finder-seen` | Key-value store for dedup |
| `notionConnector` | no | (none) | MCP Connector to Notion |
| `notionParentPageUrl` | no | (none) | Notion page for the events DB |
| `maxNotifyEvents` | no | `50` | Cap on Notion writes per run |

Example input:

```json
{
  "cities": ["Lisbon", "Berlin"],
  "categories": ["AI/ML", "Founders/Startup"],
  "prompt": "AI engineering meetups and founder dinners with a senior crowd. Avoid webinars.",
  "persona": "Founder",
  "minScore": 70,
  "maxEventsPerSource": 30
}
````

Recommendation: keep your prompt under 3 sentences.

### Output

Each item is a scored event record sorted by `score`.

```json
{
  "id": "f7c4a3e2b1d09e4f",
  "source": "luma",
  "title": "AI Tinkerers Lisbon - November meetup",
  "url": "https://lu.ma/ai-tinkerers-lisbon-nov",
  "startsAt": "2026-06-15T18:30:00.000Z",
  "city": "Lisbon",
  "venue": "Beato Innovation District",
  "isOnline": false,
  "organizer": "AI Tinkerers Lisbon",
  "attendeesEstimate": 80,
  "score": 92,
  "matchReasons": ["Topic match: AI engineering", "Audience: founders, senior engineers"],
  "firstSeenAt": "2026-05-26T09:00:00.000Z"
}
```

Export to JSON, CSV, Excel, XML, or RSS from the **Dataset** tab.

Recommendation: use RSS to plug Events Finder into Feedly for a zero-code digest.

### How to run Events Finder via the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/luis.pinto~events-finder/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "cities": ["Lisbon"],
    "categories": ["AI/ML"],
    "prompt": "AI engineering meetups with a senior crowd",
    "minScore": 70
  }'
```

Poll run status via `GET /v2/actor-runs/RUN_ID`, or use the Apify SDK in Node.js or Python.

Recommendation: trigger from your backend on a cron and post results to Slack.

### Limitations

- Only covers Luma, Eventbrite, and Meetup. Conference Alerts, 10times, and similar are out of scope; larger paid conferences may be missed.
- Scoring quality depends on the prompt. "AI events" produces vague scores; write 1 to 3 sentences naming audience, format, and topic.
- Deduplication is scoped per `dedupStoreName`. Two schedules sharing the same store will hide events from each other; use distinct names.

Recommendation: review `dedupStoreName` before duplicating schedules.

### Are there other tools in Apify Store?

- Apify Conference Scout: industry conferences and trade shows
- Shopify Store Finder: discover Shopify stores by niche
- AI SERP Intent Extractor: classify Google search intent with Claude

Recommendation: pair Events Finder with Conference Scout.

### FAQ

**Can you scrape Luma, Eventbrite, and Meetup with Events Finder?**
Yes. All three are scraped in one run, unified into one schema, and scored together.

**How many events can Events Finder scrape per run?**
Up to `maxEventsPerSource` per source, per city, per category. Default 50, max 500.

**Can Events Finder scrape events behind login?**
No. Only public listing pages are scraped. Private Luma communities, gated Meetup groups, and Eventbrite events behind email walls are out of scope.

**How often should you schedule Events Finder?**
Hourly for fast-moving cities, daily for most users, weekly for stable categories such as Investing or Design.

**Can you integrate Events Finder with Notion, Slack, or Google Calendar?**
Yes. Use the Notion MCP Connector, the Apify Slack integration, and Zapier or Make for Google Calendar, Discord, and Telegram.

**Can you use Events Finder with the Apify API?**
Yes. See the curl example above. Events Finder works with the Apify SDK in Node.js or Python.

**Can you use Events Finder through an MCP Server?**
Yes. Every public Apify Actor is available as an MCP tool. Connect via the Apify MCP server URL and call `events-finder` from Claude, Cursor, or any client.

**Is scraping Luma, Eventbrite, and Meetup data legal?**
Events Finder reads only public listing pages, the same information any visitor sees without logging in. Scraping public data is generally lawful in the EU and the US, e.g. *hiQ v. LinkedIn*. You are responsible for respecting each platform's Terms of Service.

### Your feedback

Open an issue on the Events Finder page via the **Issues** tab.

# Actor input Schema

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

Cities the Actor scans on each source. Internally normalized to Luma city slugs, Eventbrite location paths, and Meetup location queries. Accepts common English names: 'Lisbon', 'Berlin', 'San Francisco', 'New York', 'London'. Trade-off: more cities means longer runs and more API credit consumed. Recommended: 1 to 3 cities per watch.

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

Which event categories to scan. The Actor maps each category to the right filters per source (Eventbrite category IDs, Luma discovery tags, Meetup keywords), and the LLM uses them as priors when scoring relevance. Pick 1 to 3 to keep results focused. Selecting all dilutes scoring quality. Recommended: 'AI/ML' plus 'Founders/Startup' for tech founders.

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

Earliest event start date the Actor will include, in ISO format (YYYY-MM-DD). Events starting before this date are dropped. Leave empty to default to today. Example: '2026-06-01'.

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

Latest event start date the Actor will include, in ISO format (YYYY-MM-DD). Events starting after this date are dropped. Leave empty to default to dateFrom plus 30 days. Recommended: a 14 to 60 day window. Narrower windows mean fewer false positives, wider windows surface high-value events earlier. Example: '2026-07-01'.

## `prompt` (type: `string`):

Free-text description of the events you actually want to attend. The LLM scores each scraped event against this prompt and only events scoring above minScore are emitted. Be specific. Include audience, size, format, vibe. Example: 'AI engineering meetups with under 100 people where founders and senior engineers attend; prefer in-person evening events over webinars.'

## `persona` (type: `string`):

Who is attending. Used by the LLM as a prior alongside the prompt to weigh organizers and topics. Pick the closest match. The prompt always overrides. Recommended: 'Founder' for a company runner, 'Engineer' for IC eng meetups.

## `minScore` (type: `integer`):

LLM relevance score below which events are dropped. The scorer rates each event 0 to 100 against the prompt and persona. Default 60 is a balanced threshold. Lower (40) for early discovery when you want to see more borderline events. Higher (80) for tight, high-signal Slack or Notion feeds.

## `maxEventsPerSource` (type: `integer`):

Per-source cap on how many events the Actor scrapes before scoring. Higher means more thorough discovery but longer runs and more credits consumed. Recommended: 50 for normal runs, 10 for cheap daily watches, 200 for one-off backfills.

## `openRouterModel` (type: `string`):

OpenRouter model identifier used by the scorer. The Actor calls the public OpenRouter Apify Actor (sxck9mShRCfmMOZ8S) with this model. Cheaper models keep run costs near zero; smarter models produce better matchReasons. Recommended for Apify Store default: 'openai/gpt-4o-mini'. Other options: 'anthropic/claude-haiku-4-5', 'google/gemini-flash-1.5', 'meta-llama/llama-3.3-70b-instruct'.

## `openRouterApiKey` (type: `string`):

Optional OpenRouter API key. If set, the sub-Actor uses the user's own OpenRouter account and the LLM cost is billed directly (cheaper at scale). If empty, the sub-Actor's default billing applies. Check the OpenRouter Actor README for its current contract. Leave empty for the simplest setup.

## `dedupStoreName` (type: `string`):

Name of the named Key-Value Store used to remember which events have already been emitted. The Actor only emits events whose stable ID is not already in this store. Use different names for different watch profiles (for example 'events-lisbon-ai', 'events-berlin-founders'). Default fits most users.

## `notionConnector` (type: `string`):

An Apify MCP Connector to the Notion workspace. When set, the Actor appends each new event as a row in a database under the page specified below. Create one in Apify Console > Settings > API & Integrations > MCP Connectors. Notion's MCP URL is either https://mcp.notion.com/mcp or https://api.notion.com/mcp. Apify injects the Notion credentials server-side. The Actor never sees a token. Leave empty to skip Notion sync.

## `notionParentPageUrl` (type: `string`):

URL of the Notion page where the events database lives. On the first run the Actor creates an 'Events Finder Inbox' database under this page. Subsequent runs append rows there. Share this page with the Apify integration (page menu > Connections > add the Apify integration). Example: https://www.notion.so/your-workspace/Events-Inbox-1a2b3c4d. Required when notionConnector is set.

## `maxNotifyEvents` (type: `integer`):

Hard cap on how many top-scored events to push to Notion per run. The dataset always contains all new events. This only limits writes to Notion. Notion handles hundreds of rows fine. The cap exists to keep run time predictable. Recommended: 50.

## Actor input object example

```json
{
  "cities": [
    "Lisbon",
    "Berlin",
    "San Francisco"
  ],
  "categories": [
    "AI/ML",
    "Founders/Startup"
  ],
  "prompt": "AI engineering meetups and founder dinners with a senior, in-person crowd. Avoid webinars, sales-pitch events, and beginner workshops.",
  "persona": "Founder",
  "minScore": 60,
  "maxEventsPerSource": 50,
  "openRouterModel": "openai/gpt-4o-mini",
  "dedupStoreName": "events-finder-seen",
  "maxNotifyEvents": 50
}
```

# Actor output Schema

## `dataset` (type: `string`):

All newly discovered events for this run, sorted by relevance score.

# 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": [
        "Lisbon",
        "Berlin",
        "San Francisco"
    ],
    "categories": [
        "AI/ML",
        "Founders/Startup"
    ],
    "dateFrom": "",
    "dateTo": "",
    "prompt": "AI engineering meetups and founder dinners with a senior, in-person crowd. Avoid webinars, sales-pitch events, and beginner workshops.",
    "persona": "Founder",
    "minScore": 60,
    "maxEventsPerSource": 50,
    "openRouterModel": "openai/gpt-4o-mini",
    "dedupStoreName": "events-finder-seen",
    "notionParentPageUrl": "",
    "maxNotifyEvents": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("luis.pinto/events-finder").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": [
        "Lisbon",
        "Berlin",
        "San Francisco",
    ],
    "categories": [
        "AI/ML",
        "Founders/Startup",
    ],
    "dateFrom": "",
    "dateTo": "",
    "prompt": "AI engineering meetups and founder dinners with a senior, in-person crowd. Avoid webinars, sales-pitch events, and beginner workshops.",
    "persona": "Founder",
    "minScore": 60,
    "maxEventsPerSource": 50,
    "openRouterModel": "openai/gpt-4o-mini",
    "dedupStoreName": "events-finder-seen",
    "notionParentPageUrl": "",
    "maxNotifyEvents": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("luis.pinto/events-finder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "Lisbon",
    "Berlin",
    "San Francisco"
  ],
  "categories": [
    "AI/ML",
    "Founders/Startup"
  ],
  "dateFrom": "",
  "dateTo": "",
  "prompt": "AI engineering meetups and founder dinners with a senior, in-person crowd. Avoid webinars, sales-pitch events, and beginner workshops.",
  "persona": "Founder",
  "minScore": 60,
  "maxEventsPerSource": 50,
  "openRouterModel": "openai/gpt-4o-mini",
  "dedupStoreName": "events-finder-seen",
  "notionParentPageUrl": "",
  "maxNotifyEvents": 50
}' |
apify call luis.pinto/events-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=luis.pinto/events-finder",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Events Finder - Luma, Eventbrite & Meetup Tech Events",
        "description": "Discover and rank tech, AI, and founder events across Luma, Eventbrite, and Meetup. LLM scores each event against your intent prompt and dedupes across scheduled runs. Export data, run via API, schedule and monitor runs, or integrate with other tools.",
        "version": "0.1",
        "x-build-id": "4qFj4gXthfqmLF3ky"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/luis.pinto~events-finder/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-luis.pinto-events-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/luis.pinto~events-finder/runs": {
            "post": {
                "operationId": "runs-sync-luis.pinto-events-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/luis.pinto~events-finder/run-sync": {
            "post": {
                "operationId": "run-sync-luis.pinto-events-finder",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "cities",
                    "categories",
                    "prompt"
                ],
                "properties": {
                    "cities": {
                        "title": "Cities",
                        "type": "array",
                        "description": "Cities the Actor scans on each source. Internally normalized to Luma city slugs, Eventbrite location paths, and Meetup location queries. Accepts common English names: 'Lisbon', 'Berlin', 'San Francisco', 'New York', 'London'. Trade-off: more cities means longer runs and more API credit consumed. Recommended: 1 to 3 cities per watch.",
                        "default": [
                            "Lisbon"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "categories": {
                        "title": "Categories",
                        "type": "array",
                        "description": "Which event categories to scan. The Actor maps each category to the right filters per source (Eventbrite category IDs, Luma discovery tags, Meetup keywords), and the LLM uses them as priors when scoring relevance. Pick 1 to 3 to keep results focused. Selecting all dilutes scoring quality. Recommended: 'AI/ML' plus 'Founders/Startup' for tech founders.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "AI/ML",
                                "Web3/Crypto",
                                "Founders/Startup",
                                "Dev/Engineering",
                                "Product",
                                "Design",
                                "Growth/Marketing",
                                "Networking",
                                "Investing"
                            ],
                            "enumTitles": [
                                "🤖 AI / ML",
                                "🪙 Web3 / Crypto",
                                "🚀 Founders / Startup",
                                "💻 Dev / Engineering",
                                "📦 Product",
                                "🎨 Design",
                                "📈 Growth / Marketing",
                                "🤝 Networking",
                                "💰 Investing"
                            ]
                        },
                        "default": [
                            "AI/ML"
                        ]
                    },
                    "dateFrom": {
                        "title": "Date from",
                        "type": "string",
                        "description": "Earliest event start date the Actor will include, in ISO format (YYYY-MM-DD). Events starting before this date are dropped. Leave empty to default to today. Example: '2026-06-01'."
                    },
                    "dateTo": {
                        "title": "Date to",
                        "type": "string",
                        "description": "Latest event start date the Actor will include, in ISO format (YYYY-MM-DD). Events starting after this date are dropped. Leave empty to default to dateFrom plus 30 days. Recommended: a 14 to 60 day window. Narrower windows mean fewer false positives, wider windows surface high-value events earlier. Example: '2026-07-01'."
                    },
                    "prompt": {
                        "title": "Intent prompt",
                        "type": "string",
                        "description": "Free-text description of the events you actually want to attend. The LLM scores each scraped event against this prompt and only events scoring above minScore are emitted. Be specific. Include audience, size, format, vibe. Example: 'AI engineering meetups with under 100 people where founders and senior engineers attend; prefer in-person evening events over webinars.'"
                    },
                    "persona": {
                        "title": "Your persona",
                        "enum": [
                            "Generalist",
                            "Founder",
                            "Engineer",
                            "PMM",
                            "Product",
                            "Investor",
                            "Designer",
                            "Marketer"
                        ],
                        "type": "string",
                        "description": "Who is attending. Used by the LLM as a prior alongside the prompt to weigh organizers and topics. Pick the closest match. The prompt always overrides. Recommended: 'Founder' for a company runner, 'Engineer' for IC eng meetups.",
                        "default": "Generalist"
                    },
                    "minScore": {
                        "title": "Minimum relevance score",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "LLM relevance score below which events are dropped. The scorer rates each event 0 to 100 against the prompt and persona. Default 60 is a balanced threshold. Lower (40) for early discovery when you want to see more borderline events. Higher (80) for tight, high-signal Slack or Notion feeds.",
                        "default": 60
                    },
                    "maxEventsPerSource": {
                        "title": "Max events per source",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Per-source cap on how many events the Actor scrapes before scoring. Higher means more thorough discovery but longer runs and more credits consumed. Recommended: 50 for normal runs, 10 for cheap daily watches, 200 for one-off backfills.",
                        "default": 50
                    },
                    "openRouterModel": {
                        "title": "OpenRouter model",
                        "type": "string",
                        "description": "OpenRouter model identifier used by the scorer. The Actor calls the public OpenRouter Apify Actor (sxck9mShRCfmMOZ8S) with this model. Cheaper models keep run costs near zero; smarter models produce better matchReasons. Recommended for Apify Store default: 'openai/gpt-4o-mini'. Other options: 'anthropic/claude-haiku-4-5', 'google/gemini-flash-1.5', 'meta-llama/llama-3.3-70b-instruct'.",
                        "default": "openai/gpt-4o-mini"
                    },
                    "openRouterApiKey": {
                        "title": "OpenRouter API key (optional)",
                        "type": "string",
                        "description": "Optional OpenRouter API key. If set, the sub-Actor uses the user's own OpenRouter account and the LLM cost is billed directly (cheaper at scale). If empty, the sub-Actor's default billing applies. Check the OpenRouter Actor README for its current contract. Leave empty for the simplest setup."
                    },
                    "dedupStoreName": {
                        "title": "Dedup store name",
                        "type": "string",
                        "description": "Name of the named Key-Value Store used to remember which events have already been emitted. The Actor only emits events whose stable ID is not already in this store. Use different names for different watch profiles (for example 'events-lisbon-ai', 'events-berlin-founders'). Default fits most users.",
                        "default": "events-finder-seen"
                    },
                    "notionConnector": {
                        "title": "Notion Connector (optional)",
                        "type": "string",
                        "description": "An Apify MCP Connector to the Notion workspace. When set, the Actor appends each new event as a row in a database under the page specified below. Create one in Apify Console > Settings > API & Integrations > MCP Connectors. Notion's MCP URL is either https://mcp.notion.com/mcp or https://api.notion.com/mcp. Apify injects the Notion credentials server-side. The Actor never sees a token. Leave empty to skip Notion sync."
                    },
                    "notionParentPageUrl": {
                        "title": "Notion parent page URL",
                        "type": "string",
                        "description": "URL of the Notion page where the events database lives. On the first run the Actor creates an 'Events Finder Inbox' database under this page. Subsequent runs append rows there. Share this page with the Apify integration (page menu > Connections > add the Apify integration). Example: https://www.notion.so/your-workspace/Events-Inbox-1a2b3c4d. Required when notionConnector is set."
                    },
                    "maxNotifyEvents": {
                        "title": "Max events per Notion sync",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Hard cap on how many top-scored events to push to Notion per run. The dataset always contains all new events. This only limits writes to Notion. Notion handles hundreds of rows fine. The cap exists to keep run time predictable. Recommended: 50.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
