# 🎟️ Facebook Events Scraper: Multi-City Search & Ticket Price (`simpleapi/facebook-events-scraper`) Actor

Facebook Events Scraper searches events across multiple cities and extracts event names, dates, locations, descriptions, organizers, ticket prices, URLs, and other public details. Ideal for event discovery, competitor research, local market analysis, and event data collection.

- **URL**: https://apify.com/simpleapi/facebook-events-scraper.md
- **Developed by:** [SimpleAPI](https://apify.com/simpleapi) (community)
- **Categories:** Lead generation, Social media, Automation
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

### Facebook Events Scraper — Events, Ticket Prices and City Data

Facebook Events Scraper turns keyword searches into a structured feed of public Facebook events — event name, URL, date/time sentence, address, coordinates, organizer, going/interested counts, and parsed ticket pricing (`ticketCurrency`, `ticketPriceMin`, `ticketPriceMax`, `isFreeEvent`). Search a list of cities against your keywords in one run instead of many manual searches. Event marketers, ticketing analysts, local SEO agencies, and market researchers use it to compare event pricing and coverage city by city. Every row lands in a ready-to-export Apify dataset.

### 🎟️ What is Facebook Events Scraper?

Facebook Events Scraper is an Apify Actor that discovers public Facebook events by keyword and returns a structured JSON/CSV row per event — no Facebook login or developer account required. It finds event pages through Google's public search index (`site:facebook.com/events <query>`) rather than Facebook's own search, then fetches each event's public page for the full details. On top of the standard fields it adds two built-in upgrades: structured ticket pricing parsed from Facebook's raw price text, and multi-city bulk discovery that cross-produces your keyword list against a list of cities in a single run.

- 🔎 **Discovery by free-text keyword** — one query per line in `searchQueries`, no category taxonomy required
- 🌆 **Multi-city cross-product** — add `cities` and every keyword is searched once per city automatically
- 🎟️ **Ticket price parsing** — raw price text like `"$10 - $50"` is split into currency, min, max, and a free/paid flag
- 📍 **Location data** — venue name, street address, city, country code, and latitude/longitude when Facebook exposes them
- 🧑‍💼 **Organizer extraction** — host name, profile/Page URL, and a verification flag per organizer
- 💾 **Standard Apify export formats** — JSON, CSV, Excel, XML, HTML, or the Dataset API

### 📊 What data can I extract with Facebook Events Scraper?

Every field below is written by the row-building code in `src/main.py` (`build_event_stub` plus the fields `enrich_event_with_details` fills in) — not just the default dataset view.

| Field | Example value | Use case |
| --- | --- | --- |
| `url` | `"https://www.facebook.com/events/1202620635007207/"` | Canonical event link |
| `id` | `"1202620635007207"` | Stable Facebook event ID |
| `name` | `"Downtown Jazz Night"` | Event title |
| `searchKeyword` | `"jazz night"` | Which input query produced this row |
| `queryCity` | `"Chicago"` | Which city (multi-city mode) produced this row, or `null` |
| `dateTimeSentence` | `"FRIDAY, AUGUST 21 2026"` | Upper-cased human date/time sentence |
| `startTime` | `"Friday, August 21 2026"` | Raw human date sentence (not a fixed-format timestamp) |
| `utcStartDate` | `null` | Reserved field — see limitation below |
| `eventFrequency` | `"SINGLE"` | Recurrence type; `"SINGLE"` unless Facebook's own payload states otherwise |
| `imageUrl` | `"https://scontent.xx.fbcdn.net/%E2%80%A6"` | Event cover image |
| `imageCaption` | `null` | Reserved field, currently always `null` |
| `duration` | `"3 hr"` | Display duration text, when Facebook exposes it |
| `description` | `"Party event in Chicago…"` | Full event description text |
| `address` | `"123 Main St, Chicago, US"` | Best-effort composed address string |
| `location` | `{ "name": …, "city": …, "countryCode": …, "latitude": …, "longitude": … }` | Structured venue object (10 keys — see below) |
| `usersGoing` | `76` | Parsed "going" count |
| `usersInterested` | `240` | Parsed "interested" count |
| `usersResponded` | `316` | `usersGoing + usersInterested` (derived, not a separate Facebook field) |
| `ticketsInfo` | `{ "price": "$10 - $25", "buyUrl": null, "title": "Tickets · $10 - $25", "subtitle": …, "ticketProvider": … }` | Raw ticketing-widget payload, or `null` if the event has no ticketing widget |
| `ticketCurrency` | `"USD"` | Parsed from the price text's currency symbol |
| `ticketPriceMin` | `10` | Parsed lowest price |
| `ticketPriceMax` | `25` | Parsed highest price |
| `isFreeEvent` | `false` | `true`/`false` when a price is parsed, `null` when there is no ticketing data at all |
| `ticketBuyUrl` | `null` | Populated only when Facebook's own payload exposes a real buy URL |
| `organizedBy` | `"Blue Room Chicago"` | Primary organizer/host name |
| `organizators` | `[{ "name": …, "id": …, "url": …, "isVerified": false }]` | Full organizer list |
| `eventType` | `"PUBLIC"` | Constant value — see limitation below |
| `privacyInfo` | `"Public · Hosted by Blue Room Chicago"` | Composed privacy sentence |
| `isPast` | `false` | Constant value — see limitation below |
| `isOnline` | `false` | Constant value — see limitation below |
| `isCanceled` | `false` | Constant value — see limitation below |
| `hasChildEvents` | `false` | `true` when recurring child occurrences were found |
| `childEvents` | `[]` | `[{ "id", "url", "name", "dateTimeSentence" }]` when recurring occurrences exist |
| `discoveryCategories` | `[]` | `[{ "url", "label" }]` Facebook discovery-category tags, when present |
| `externalLinks` | `[]` | Unique external URLs found in the description |
| `externalLinksSource` | `null` | Reserved field, currently always `null` |
| `scrapedAt` | `"2026-08-04T09:00:00.000Z"` | ISO scrape timestamp |
| `inputUrl` | `"/events/search/?q=jazz%20night%20Chicago"` | Relative Facebook search path the query would have used |
| `discoverySource` | `"google_serp"` | Constant — how this actor discovers event URLs (see below) |

#### 🎫 Ticket pricing data

`ticketsInfo`, `ticketCurrency`, `ticketPriceMin`, `ticketPriceMax`, and `isFreeEvent` are populated only when the event's own detail page carries a ticketing widget. The raw price text (e.g. `"$10 - $50"`, `"Free"`, `"£5"`) is parsed with a currency-symbol lookup and a number extractor — never guessed. Events with no ticketing widget at all get `ticketsInfo: null` and `isFreeEvent: null`, which is deliberately different from `isFreeEvent: true`: "no price data" and "confirmed free" are not conflated. Use `freeOnly: true` to keep only confirmed-free events, or filter on `ticketPriceMax` client-side to build a price-tier comparison across cities.

#### 🌆 Location and targeting data

`location.city`, `location.countryCode`, `location.latitude`/`longitude`, `queryCity`, and `searchKeyword` are the fields you filter and group on. `queryCity` and `searchKeyword` are tagged on every row so a multi-city run can be split back out per city or per keyword after the fact, without re-running anything.

### 🤔 Why not build this yourself?

Facebook's own anonymous events-search GraphQL endpoint is login-gated platform-wide — this actor's own source confirms it was still gated as of 2026-08-01 across independent live probes. A DIY scraper would need to either authenticate as a real Facebook user (against Facebook's terms and a ban risk) or find another discovery path entirely. This actor instead discovers event URLs through Google's public search index and reads each event's own public detail page for the real data — no login, no cookies, no account.

Even with a working discovery path, a DIY build still has to solve: rotating residential proxies (Facebook blocks datacenter IPs quickly), retry/backoff on `403`/`429`/`blocked`/`rate limit` responses, parsing ticket pricing out of free-text widget payloads instead of a stable field, and re-deriving address/organizer/coordinate data from nested JSON blobs embedded in the page HTML rather than a documented API response shape. This actor already does all of that, with automatic proxy rotation and exponential-backoff retries (up to 3 attempts per request) built in.

Build it yourself if you need a fully custom discovery mechanism (e.g. your own Facebook session) or want to avoid any dependency on Google's index. Use this actor if you want a working keyword-to-structured-event pipeline today, with ticket pricing and multi-city search already solved.

### 🧭 How to use data extracted from Facebook Events

#### 📅 Event marketers and promoters

Feed `searchQueries` with your event category and `cities` with your target markets, then use `ticketPriceMin`/`ticketPriceMax` and `usersGoing`/`usersInterested` to benchmark your own pricing and expected turnout against comparable public events in the same city before setting your own ticket price.

#### 🏢 Agencies and ticketing consultancies

Run the same `searchQueries` across a client's target cities on a recurring schedule, and diff `usersGoing`/`usersInterested`/`ticketPriceMin`/`ticketPriceMax` between runs to show clients how demand and pricing for their event category are trending in each market — a repeatable audit rather than a one-off pull.

#### 📈 Market research and intelligence

Cross a category keyword (e.g. `"comedy show"`) against a city list to build a price-distribution and turnout table across markets in a single run, using `queryCity`, `ticketPriceMin`, `ticketPriceMax`, and `usersGoing` as the grouping and comparison fields — useful for city-selection and pricing-benchmark research.

#### 🤖 AI agents and automated pipelines

Because output is typed JSON keyed by stable field names, an agent can call this actor as a tool to answer "what's happening in `{city}` this week that matches `{keyword}`" and reason directly over `dateTimeSentence`, `address`, and `ticketPriceMin`/`ticketPriceMax` without a separate parsing step.

### 🔼 Input sample

Read directly from `.actor/actor.json`. `searchQueries` is the only required field; everything else has a default and is fully optional.

| Parameter | Required | Type | Description | Example value |
| --- | --- | --- | --- | --- |
| `searchQueries` | Yes | array | Keywords to search for on Facebook Events, one per line. Every query is processed in order. | `["jazz night", "tech meetup"]` |
| `cities` | No | array | Optional list of cities to cross with every search query. Leave empty to search each query as-is. Default `[]`. | `["Chicago", "Austin", "Denver"]` |
| `maxEvents` | No | integer | Stop after this many events per search combination (each query, or each query × city pair). Allowed 1–1000, default `10`. | `25` |
| `freeOnly` | No | boolean | When `true`, only events whose parsed ticket price resolves to free (`isFreeEvent = true`) are returned. Default `false`. | `false` |
| `proxyConfiguration` | No | object | Apify Proxy configuration. See the limitation below — this input is not read for the actual event-page fetch. | `{ "useApifyProxy": false }` |

```json
{
  "searchQueries": ["jazz night"],
  "cities": ["Chicago", "Austin", "Denver"],
  "maxEvents": 25,
  "freeOnly": false,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

⚠️ **Common pitfall:** `proxyConfiguration` is present in the input schema for consistency with sibling actors, but the source (`setup_proxy_with_fallback` in `src/main.py`) always fetches Facebook event pages through the `RESIDENTIAL` Apify Proxy group regardless of what you set here — a documented, deliberate choice because Facebook is unreliable enough on datacenter or no-proxy IPs to cause silent zero-row runs. Don't expect a custom proxy group/country to change how event pages are fetched.

### 🔽 Output sample

Every row is pushed to the dataset as typed, normalized JSON with a consistent schema — export as JSON, CSV, Excel, XML, or HTML from the Apify Console, or read it via the Dataset API.

```json
{
  "url": "https://www.facebook.com/events/1202620635007207/",
  "id": "1202620635007207",
  "name": "Downtown Jazz Night",
  "searchKeyword": "jazz night",
  "queryCity": "Chicago",
  "dateTimeSentence": "FRIDAY, AUGUST 21 2026",
  "utcStartDate": null,
  "startTime": "Friday, August 21 2026",
  "eventFrequency": "SINGLE",
  "imageUrl": "https://scontent.xx.fbcdn.net/v/example.jpg",
  "duration": null,
  "description": "Party event in Chicago, IL by Blue Room Chicago on Friday, August 21 2026 with 240 people interested and 76 people going.",
  "address": "The Blue Room, Chicago, US",
  "location": {
    "url": null,
    "id": null,
    "name": "The Blue Room, Chicago",
    "contextualName": "The Blue Room, Chicago",
    "placeType": "PLACE",
    "latitude": 41.8781,
    "longitude": -87.6298,
    "countryCode": "US",
    "streetAddress": null,
    "city": "Chicago"
  },
  "usersGoing": 76,
  "usersInterested": 240,
  "usersResponded": 316,
  "ticketsInfo": { "buyUrl": null, "price": "$10 - $25", "title": "Tickets · $10 - $25", "subtitle": "eventbrite.com", "ticketProvider": "eventbrite.com" },
  "ticketCurrency": "USD",
  "ticketPriceMin": 10,
  "ticketPriceMax": 25,
  "isFreeEvent": false,
  "ticketBuyUrl": null,
  "organizedBy": "Blue Room Chicago",
  "organizators": [{ "name": "Blue Room Chicago", "id": null, "url": null, "isVerified": false }],
  "eventType": "PUBLIC",
  "privacyInfo": "Public · Hosted by Blue Room Chicago",
  "isPast": false,
  "isOnline": false,
  "isCanceled": false,
  "hasChildEvents": false,
  "childEvents": [],
  "discoveryCategories": [],
  "externalLinks": [],
  "scrapedAt": "2026-08-04T09:00:00.000Z"
}
```

A per-city/per-query result-count summary (`{ "searchKeyword", "city", "eventsCollected" }` rows) is also written to the run's key-value store under `CITY_QUERY_SUMMARY` whenever `cities` is used.

### 🎯 How do you filter and target specific events?

This actor's targeting surface is intentionally small — four real controls, no category taxonomy or radius search:

1. **Free-text query, not category.** `searchQueries` is a plain keyword list — there is no fixed category enum. Specific, concrete phrases (`"jazz night"`, `"5k charity run"`) return more relevant results than broad ones (`"music"`).
2. **City scoping via text, not coordinates.** `cities` appends each city name to the query text (`"jazz night" + "Chicago"` → `"jazz night Chicago"`) rather than a lat/long radius — there is no bounding-box or distance-radius parameter.
3. **Price threshold, not a rating filter.** `freeOnly` is the one quality/segment filter this actor exposes — it keeps only events with a confirmed-free parsed price, leaving unknown-price events in either mode.
4. **Volume control.** `maxEvents` (1–1000, default 10) caps results per keyword/city combination, but see the pagination limit below — setting it above roughly 60–70 will not return more results for a single combination.

```json
{ "searchQueries": ["food truck festival"], "maxEvents": 50 }
```

```json
{ "searchQueries": ["salsa night"], "cities": ["Miami", "Los Angeles"], "freeOnly": true }
```

```json
{ "searchQueries": ["startup networking", "tech meetup"], "cities": ["Austin"], "maxEvents": 15 }
```

⚠️ **Real limit:** discovery goes through Google's public search results (`discover_event_urls_via_google_serp` in `src/main.py`), which pages up to `start=60` (roughly 7 result pages) and stops early after 2 consecutive pages with no new event URLs. In practice this caps a single keyword/city combination at roughly 60–70 unique discoverable events even though `maxEvents` accepts values up to 1000 — a higher `maxEvents` only helps once a query naturally surfaces more results.

### ▶️ Want to try other Facebook and directory scrapers?

| Scraper | What it extracts |
| --- | --- |
| Facebook Group Posts and Details Scraper | Facebook group posts, member profiles, and public contact leads |
| LinkedIn Search Jobs Scraper (Advanced Search Filters) | Job listings with salary, seniority, and advanced filter fields |
| Tripadvisor Review Scraper (Photo and Visual Content Filters) | Business listings, reviews, ratings, and photo/visual content |
| TikTok Shop Data Scraper (Reviews and Sentiment Analysis) | Product listings, reviews, and sentiment-scored feedback |
| Pinterest Ads Scraper (Performance Analytics) | Ad listings with performance/analytics fields |

### 💻 How to extract Facebook event data programmatically

This actor runs as a standard Apify Actor: one API call, your Apify API token as the auth header, structured JSON back from the Dataset API.

#### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")

run = client.actor("SimpleAPI/facebook-events-scraper-multi-city-search-and-ticket-price").call(
    run_input={
        "searchQueries": ["jazz night"],
        "cities": ["Chicago", "Austin"],
        "maxEvents": 25,
        "freeOnly": False,
    }
)

for event in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(event["name"], event["queryCity"], event["ticketPriceMin"], event["ticketPriceMax"])
```

#### 📊 Export to spreadsheets or CRM

Export the dataset directly as CSV or Excel from the Apify Console (or the Dataset API's `format=csv`/`format=xlsx` parameter) and map columns straight from the JSON keys — `name` → event name, `ticketPriceMin`/`ticketPriceMax` → price range columns, `address` and `location.city` → location columns, `organizedBy` → contact/organizer column.

### ⚖️ Is it legal to scrape Facebook Events data?

Scraping publicly accessible Facebook event pages is generally permitted; these listings exist specifically to be discovered and shared, and this actor only reads pages Facebook already serves to logged-out visitors. Most of the data — event name, date, description, ticket price, attendance counts — is public promotional content, not personal data, so it falls under Facebook's Terms of Service rather than data-protection law. The `organizedBy`/`organizators` fields can identify an individual host rather than a Page or business, and in that case GDPR/CCPA-style rules on lawful basis for storage and use of personal data may apply to that subset of the data. Consult legal counsel for commercial applications involving bulk storage of personal data.

### ❓ FAQ

#### Does this actor mark events as past or canceled?

No — `isPast` and `isCanceled` are always `false` in the current output; this actor does not detect event recency or cancellation status. Cross-check `dateTimeSentence`/`startTime` against today's date yourself if you need to filter out events that have already happened.

#### Can I get ticket price data along with the main event records?

Yes, in the same row — `ticketCurrency`, `ticketPriceMin`, `ticketPriceMax`, and `isFreeEvent` are parsed automatically whenever an event's detail page carries a ticketing widget. Events with no ticketing widget return `null` for all four fields rather than a fabricated `0`.

#### How accurate is the date and price data?

The actor returns data exactly as it appears on the public event page at request time. `dateTimeSentence`/`startTime` are extracted from a natural-language sentence (not a machine-parsed timestamp — `utcStartDate` is currently always `null`), so treat them as display text and re-parse if you need a strict date type. Ticket prices reflect whatever text Facebook's ticketing widget shows; recommend spot-checking against the `ticketBuyUrl` before using prices for anything transactional.

#### How many events can I get per run?

`maxEvents` accepts 1–1000 per keyword/city combination, but Google-SERP-based discovery realistically exhausts after roughly 60–70 unique events per combination (see the pagination limit above) — set `maxEvents` near that ceiling for a single keyword rather than expecting 1000 results from one query.

#### How does the multi-city search work?

Every keyword in `searchQueries` is combined with every city in `cities` (2 keywords × 3 cities = 6 scoped searches), each capped independently by `maxEvents`. Leave `cities` empty and it behaves as a plain single-keyword search with no city scoping — fully backward compatible.

#### Does Facebook Events Scraper work with Claude, ChatGPT, and AI agent frameworks?

There is no dedicated MCP server for this actor. It is callable as a standard Apify Actor via the REST API or `apify-client`/`apify-client-js` from any agent framework that can make an authenticated HTTP call and read back JSON.

#### How does Facebook Events Scraper compare to other Facebook scrapers?

This actor's two built-in differentiators — structured ticket-price parsing (currency/min/max/free-flag) and multi-city keyword cross-product in a single run — come from its own input schema and source code, not a competitor comparison. Check any other Facebook events actor's own live Apify Store listing for whether it documents equivalent ticket-pricing or multi-city fields before assuming it does.

#### Can I use this without a Facebook API key or developer account?

Yes. No Facebook login, cookie, or developer account is required — only an Apify account to run the actor. Discovery goes through Google's public search index and every page fetched is a public, logged-out Facebook page.

### ✅ Conclusion

Facebook Events Scraper turns a keyword list into structured, exportable Facebook event data — with ticket pricing parsed into currency/min/max/free fields and multi-city search built in as a single run instead of many. It's built for event marketers, ticketing agencies, and market researchers who need city-by-city event and pricing coverage without a Facebook login. Run it from the Apify Console or call it via the API to get your first structured dataset in minutes.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search for on Facebook Events, one per line. Examples: jazz night, running club, tech meetup, art fair, wine tasting, stand-up comedy. Every query is processed in order.

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

Optional list of cities to cross with every search query. Example: searchQueries=\["jazz night"] + cities=\["Chicago","Austin","Denver"] runs 3 city-scoped searches ("jazz night Chicago", "jazz night Austin", "jazz night Denver") in one run instead of 3 separate manual runs. Leave empty to search each query as-is (no city scoping) — fully backward compatible with a plain keyword run.

## `maxEvents` (type: `integer`):

Stop after this many events for each search combination (each query, or each query x city pair when cities are set). Lower = faster/cheaper test runs. Higher = broader coverage. Allowed 1-1000, default 10.

## `freeOnly` (type: `boolean`):

When ON, only events whose parsed ticket price resolves to free (isFreeEvent = true) are returned. Events with no ticketing data at all are still returned (unknown price is not the same as free). Default OFF.

## `proxyConfiguration` (type: `object`):

Route traffic through Apify Proxy. Residential is used automatically when this is left as default. Pick a specific proxy group or country to override the default with your own choice.

## Actor input object example

```json
{
  "searchQueries": [
    "travel",
    "comedy"
  ],
  "cities": [],
  "maxEvents": 10,
  "freeOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items in the Actor's default dataset.

## `citySummary` (type: `string`):

Result-count summary rows (searchKeyword, city, eventsCollected), written once to the key-value store when the `cities` input is used.

# 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 = {
    "searchQueries": [
        "travel",
        "comedy"
    ],
    "cities": [],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/facebook-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 = {
    "searchQueries": [
        "travel",
        "comedy",
    ],
    "cities": [],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/facebook-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 '{
  "searchQueries": [
    "travel",
    "comedy"
  ],
  "cities": [],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call simpleapi/facebook-events-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,simpleapi/facebook-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/XWr5ZAC8b84FfhPxF/builds/q2j9wV0balGKUPvLO/openapi.json
