# Tech & Business Events Scraper (Luma, Eventbrite) (`ahmed-data-tools/tech-business-events-scraper`) Actor

Collect upcoming public tech, startup and business events from Luma and Eventbrite: dates, venue, city, organizer, attendee count and ticket price. Filter by keyword, city and date. No login.

- **URL**: https://apify.com/ahmed-data-tools/tech-business-events-scraper.md
- **Developed by:** [ahmed abdelmenem](https://apify.com/ahmed-data-tools) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

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

## Tech & Business Events Scraper – Luma & Eventbrite

Collect upcoming public **tech, startup and business events** from **Luma** and **Eventbrite** into one clean, de-duplicated dataset. No login, no cookies, no API keys. Filter by keywords, city and start-date window and get one row per event with dates, venue, city, country, organizer, attendee count (when public) and ticket price.

### What you get

One dataset item per event:

- `title`, `startAt`, `endAt` (UTC ISO 8601) and `timezone` (IANA)
- `venue`, `address`, `city`, `region`, `country`, `countryCode`, `latitude`, `longitude`
- `organizer` (and `hosts`)
- `attendeeCount` – only when the platform shows the guest count publicly (Luma); otherwise `null`
- `isFree`, `priceMin`, `priceMax`, `currency` (`null` when the price is unknown)
- `isOnline`, `tags`, `imageUrl`
- `url` (public event page), `source` (`luma` / `eventbrite`), `eventId`, `scrapedAt`

#### Example output

```json
{
  "title": "Company Brain Hackathon: Build an AI Agent That Knows Your Organization",
  "startAt": "2026-10-12T19:30:00Z",
  "endAt": "2026-10-13T00:00:00Z",
  "timezone": "America/Los_Angeles",
  "venue": "135 Constitution Dr",
  "city": "Menlo Park",
  "country": "United States",
  "organizer": "TechEquity Ai - Silicon Valley",
  "attendeeCount": 580,
  "isFree": true,
  "priceMin": 0,
  "priceMax": 0,
  "isOnline": false,
  "url": "https://luma.com/oct-hackathon",
  "source": "luma"
}
```

### Use cases

- Lead generation: find conferences, meetups and hackathons where your buyers show up
- Sponsorship and recruiting calendars for a city or topic
- Market research on the startup / AI / developer event scene
- Feeding event listings, newsletters or calendars

### Input

| Field | Description |
| --- | --- |
| `sources` | `luma`, `eventbrite` (both by default) |
| `keywords` | Topics to match (any). Eventbrite searches each keyword separately; Luma events are kept when title, organizer or hosts match. Whole-word match for keywords of up to 3 characters, word-prefix match for longer ones |
| `location` | City, e.g. `San Francisco`, `London`, `Austin, TX`, `Toronto, Canada`. Empty = several major tech hubs plus online events |
| `startWithinDays` | Only events starting in the next N days (default 30) |
| `includeOnline` | Keep online events (default on) |
| `onlyFree` | Keep only events with a known free ticket |
| `enrichEventbrite` | Open each Eventbrite event page to add organizer, price range and exact end time (default on) |
| `maxItems` | Maximum number of events saved (= billable results) |
| `maxPagesPerSource` | Result pages per Luma city / Eventbrite keyword |

#### Example input

```json
{
  "keywords": ["ai", "startup", "developer"],
  "location": "San Francisco",
  "startWithinDays": 30,
  "maxItems": 100
}
```

The default input finishes in well under a minute and returns up to 100 events.

### How it works

- **Luma** – reads the same public "discover" feed that luma.com uses for its city hub pages (`api.lu.ma/discover/...`). About 90 city hubs exist; a location without a Luma hub is skipped for Luma.
- **Eventbrite** – reads the public search pages (`eventbrite.com/d/<city>/<keyword>/`), which embed the result list as structured data, and optionally each public event page (`/e/...`, JSON-LD) for organizer and price.
- Every request is checked against the site's `robots.txt` (wildcards supported) before it is sent. Requests are throttled and use at most 3 parallel connections.
- Events listed on several platforms (same title and start hour) are de-duplicated.

### Sources that are not included

- **Meetup** – its `robots.txt` disallows the GraphQL endpoint (`/gql*`), `/mu_api/` and all search URLs that carry query parameters (`keywords`, `location`, `source`, …), so it cannot be scraped in a permitted way.
- **Luma search** (`/search/...`) requires sign-in and is not used.

### Pricing – pay per result

You are charged per event saved to the dataset. Set `maxItems` to cap spend; the Actor stops as soon as your spending limit is reached.

### Terms and responsible use

Only publicly visible data is collected, and no personal profiles are scraped (organizer / host names are the public names shown on the event page). You are responsible for using the data in line with the terms of the source sites and applicable privacy law.

### Limitations

- Luma's discover feed is curated per city hub (typically a few dozen upcoming events per city) and is not a full search; it is an unofficial endpoint and may change.
- Luma hides exact venues for many events (shown to registered guests only) – `venue` is then `null`; `city` and `country` are still provided.
- Eventbrite results are relevance-ranked and filtered again against your keywords; very broad cities may need a higher `maxPagesPerSource`.
- Attendee counts are not public on Eventbrite and Luma hides them when the host disables the guest list.

### FAQ

**Why are some venues empty?** The organizer chose to show the address only to registered guests, or the event is online.

**Can I search a city Luma does not cover?** Yes – Eventbrite still covers it; Luma is skipped with a log warning.

# Actor input Schema

## `sources` (type: `array`):

Event platforms to collect from. Both use only public pages/endpoints that need no login and are permitted by the site's robots.txt. Leave all selected to combine them.

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

Topics to look for, e.g. "ai", "startup", "fintech", "hackathon". On Eventbrite each keyword is searched separately; on Luma events are kept when the title, organizer or tags match any keyword (whole-word match, case-insensitive). Leave empty to use general tech and business keywords.

## `location` (type: `string`):

City to search in, e.g. "San Francisco", "London", "Berlin" or "Austin, TX" / "Toronto, Canada". Luma covers about 90 city hubs worldwide (cities without a Luma hub are skipped for Luma); Eventbrite accepts most cities. Leave empty to search a set of major tech hubs plus online events.

## `startWithinDays` (type: `integer`):

Only return events that start between now and N days from now.

## `includeOnline` (type: `boolean`):

When disabled, events flagged as online/virtual are dropped and only in-person events are returned.

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

Keep only events with a known free ticket. Events with unknown price are dropped when this is enabled.

## `enrichEventbrite` (type: `boolean`):

Eventbrite search pages do not include the organizer or ticket price. When enabled, each Eventbrite event page is opened (slower, but adds organizer, price range and exact end time).

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

Maximum number of events to save (each saved event is one billable result).

## `maxPagesPerSource` (type: `integer`):

Upper bound on result pages requested per city (Luma, 50 events/page) or per keyword (Eventbrite, 20 events/page). Paging also stops early when a page has no matching events.

## Actor input object example

```json
{
  "sources": [
    "luma",
    "eventbrite"
  ],
  "keywords": [
    "ai",
    "startup",
    "developer"
  ],
  "location": "San Francisco",
  "startWithinDays": 30,
  "includeOnline": true,
  "onlyFree": false,
  "enrichEventbrite": true,
  "maxItems": 100,
  "maxPagesPerSource": 3
}
```

# Actor output Schema

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

Upcoming events (overview table view)

# 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 = {
    "sources": [
        "luma",
        "eventbrite"
    ],
    "keywords": [
        "ai",
        "startup",
        "developer"
    ],
    "location": "San Francisco",
    "startWithinDays": 30,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed-data-tools/tech-business-events-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 = {
    "sources": [
        "luma",
        "eventbrite",
    ],
    "keywords": [
        "ai",
        "startup",
        "developer",
    ],
    "location": "San Francisco",
    "startWithinDays": 30,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed-data-tools/tech-business-events-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 '{
  "sources": [
    "luma",
    "eventbrite"
  ],
  "keywords": [
    "ai",
    "startup",
    "developer"
  ],
  "location": "San Francisco",
  "startWithinDays": 30,
  "maxItems": 100
}' |
apify call ahmed-data-tools/tech-business-events-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed-data-tools/tech-business-events-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/6vN4bliwoIG9PRVd0/builds/0SOSE7gl8FpeULBo1/openapi.json
