~ / guides / How to Scrape Facebook Events (2026)

How to Scrape Facebook Events (2026)

NB
Noah Berg
Facebook data engineer · about the author
the short version
  • I asked Facebook's event search for data the obvious way in July 2026. With a desktop Chrome User-Agent, facebook.com/events/search returned HTTP 400 and a 1,542-byte error page. With no User-Agent the same URL returned HTTP 302, a redirect straight to the login wall.
  • A fully public event page still leaks the basics to a logged-out request: the event name sits in og:title and the date and venue usually sit in og:description. The host and the going/interested counts live in login-gated JSON, so those are the fields that go missing.
  • The Graph API models every field you want (name, start_time, place, owner, attending_count, interested_count), but Meta's own reference says access to Events on Users and Pages is limited to Facebook Marketing Partners, so there is no public API route to an arbitrary event.
  • For attendee counts, host, and event search at volume, a scraper API that takes the event URL and returns parsed JSON removes the login wall. I hit api.chocodata.com/api/v1/facebook/event with no key in July 2026 and got a clean HTTP 401 INVALID_API_KEY, the expected response before you authenticate.

I went looking for how to scrape Facebook events the obvious way first: one requests.get against Facebook’s public event search with a normal Chrome User-Agent. It came back HTTP 400 with a 1,542-byte error page. I dropped the User-Agent and the same URL returned HTTP 302, a redirect straight to Facebook’s login page. Neither is the event data you want, and that gap is the honest starting point for scraping Facebook events in 2026: the events surface is gated harder than Pages, and the field most people actually came for, the attendee count, sits behind the login wall.

Below is what I ran in July 2026, what Facebook returned, and the working route for each field a public event exposes: name, date, location, host, and the going/interested counts.

What data can you scrape from a Facebook event?

A public Facebook event exposes five fields worth collecting: the event name, its date and time, the location or venue, the host, and the attendee counts (going and interested). Not all five come back the same way, and knowing which live in the open markup versus the login-gated JSON decides how much work each one costs.

The name and date are the easy fields. The host and the two attendee counts are the hard ones, because Facebook keeps them in the embedded JSON that a logged-out request does not fully populate.

FieldMaps toWhere it livesLogged-out?
Event namenameog:title meta tagUsually yes
Date and timestart_timeog:description, embedded JSONUsually yes
Location / venueplaceEmbedded JSON, sometimes og:descriptionPartial
Host / organizerownerLogin-gated JSONOften no
Going / interested countsattending_count / interested_countLogin-gated JSONOften no

Those field names are not guesswork. They are the exact keys Meta’s own Graph API Event reference documents for an event object, and they carry over whether you read the API or parse the page. The reference also lists end_time, description, maybe_count, and declined_count if you want the fuller picture. The catch is that the two most valuable fields, the host and the attendee counts, are also the hardest to reach, and that comes down to how Facebook treats event data.

Why are Facebook events harder to scrape than Facebook Pages?

Facebook events are harder to scrape than Pages because the events surface bounces logged-out traffic to a login page, while a public Page still serves its data to the same request. The gap is stark. A logged-out request to a public Page such as facebook.com/Meta returns HTTP 200 and a public shell with the like count sitting in the markup. The equivalent logged-out request to facebook.com/events/search returned HTTP 302 for me, a redirect with a zero-byte body and nothing to parse.

The reason is what each surface treats as public. A Page’s like count is a vanity metric Facebook renders to anyone. An event’s attendee data is closer to social-graph information, so who is going and who is hosting stay in the login-gated JSON rather than the open og: tags. That split is why the event name and date fall out of a public page easily while the going and interested counts do not, and why the header tricks that coax a Page into responding do not unlock an event. Reaching the gated fields means carrying an authenticated session, so before picking a route, the legal line decides which fields are safe to take.

Scraping public, logged-out event data is broadly defensible in the US, and the moment you log in or start collecting attendee identities, the picture changes. Those are two separate situations and they get blurred constantly.

On January 23, 2024, a federal judge ruled in Meta Platforms v. Bright Data that Meta’s terms do not bar logged-off scraping of public data, because those terms bind a user who is actively logged into an account. An event’s public name, date, and venue fall on the defensible side of that line. Meta dropped the case the following month.

The constraints still matter. Facebook’s robots.txt opens by stating that collection of data through automated means is prohibited without express written permission, and Meta’s Automated Data Collection Terms bind you once you authenticate a session. Attendee names are personal data, so the GDPR applies to them no matter how public the event page is, which is why I treat a headcount very differently from a list of who is going. I keep the full breakdown in is scraping Facebook legal. The working rule: stay logged out, take the public event fields, and treat any individual attendee as regulated. With the legal line set, the routes to the data split cleanly.

What are the ways to scrape Facebook events?

There are four ways to get event data off Facebook, and picking the wrong one is where most projects stall. Here is how they compare before I get into code.

RouteAuthReturnsBest forMain limit
Graph API EventMarketing Partner + tokenFull event objectEvents a partner managesPartners only, no arbitrary events
Logged-out og: parseNoneName, date, venueOne-off public basicsHost and counts gated
facebook-events-scraper (Selenium)BrowserTitle, date, location, hostsSmall local pullsv0.0.2, brittle, slow
Scraper APIAPI keyParsed JSON, incl. counts and hostVolume and searchPer-request cost

The Graph API is the cleanest data and the narrowest door. Meta’s Event reference is blunt that “access to Events on Users and Pages is only available to Facebook Marketing Partners,” so unless your app holds that status, the API returns nothing for an event you do not own. The older public event search by location was retired years before that. The logged-out og: parse reaches the headline fields the API will not hand you, and it stops at the login wall for the host and counts. A Selenium library or a scraper API is what teams reach for once they need those gated fields at any volume. I will walk the two routes that actually return data, starting with the hands-on Python.

How do you scrape a public Facebook event with Python?

The fastest way to scrape a public Facebook event with Python is to request the event URL logged out and parse the og: meta tags, which carry the event name and usually the date and venue without any login. This is the same technique that works on Pages, and it hits the same header quirk.

Here is the request behavior I measured against Facebook’s event surface in July 2026:

RequestUser-AgentStatusBody sizeUsable data
GET /events/search?q=musicDesktop Chrome string4001,542 bytesNone (error page)
GET /events/search?q=musicNone3020 bytesRedirect to login

The lesson matches the Pages one: a realistic desktop Chrome User-Agent was the combination that got rejected, and removing it did not help either, because the events search endpoint bounces logged-out traffic to a login page. Individual public event URLs are friendlier, and this is the parse I run against one:

import requests, re, html

# A public Facebook event URL. No User-Agent header on purpose: in my
# July 2026 test, a desktop Chrome UA returned HTTP 400 on Facebook's
# events endpoints, the same quirk I see on Pages.
url = "https://www.facebook.com/events/1234567890"
r = requests.get(url, timeout=20)
print(r.status_code)

def og(prop):
    m = re.search(rf'<meta property="{prop}" content="(.*?)"\s*/?>', r.text)
    return html.unescape(m.group(1)) if m else None

print(og("og:title"))        # -> the event name
print(og("og:description"))  # -> usually carries the date, time, and venue

That returns the event name and, in the description, the date and venue for a fully public event. What it does not return is the host and the two attendee counts, because attending_count and interested_count sit in the login-gated JSON, not the og: tags. That is the exact boundary the 302 above marks: the open markup gives you the headline, the login wall guards the rest.

The community shortcut is the facebook-events-scraper library, a Selenium tool that exposes find_all_events() to list an organizer’s event URLs and get_event_details() to pull each one’s title, timing, location, hosts, and image. It drives a real Chrome, so it renders more than requests does. Read its own caveat first: the latest release is 0.0.2 and the author states plainly that it is “a very early version” and “not yet complete.”

A logged-in browser session against Facebook is also exactly what Meta’s Automated Data Collection Terms restrict, and a single Chrome instance does not rotate IPs, so the account and the datacenter address both get flagged fast. It handles a handful of local events and becomes a maintenance treadmill at volume. When the counts and host have to come back reliably, the next step is to hand the rendering off.

How do you scrape Facebook events at scale without hitting the login wall?

A scraper API removes the login wall by accepting a Facebook event URL and returning parsed JSON, with the authenticated residential session, anti-bot handling, and retries run server-side. You send one request and get the full field set back, including the host and the going/interested counts that the logged-out og: route leaves empty.

The request shape is a target URL plus your key. Here it is as a curl call:

curl "https://api.chocodata.com/api/v1/facebook/event?url=https://www.facebook.com/events/1234567890&api_key=$CHOCO_API_KEY"

The same call from Python, which is what slots into a pipeline:

import os, requests

resp = requests.get(
    "https://api.chocodata.com/api/v1/facebook/event",
    params={
        "url": "https://www.facebook.com/events/1234567890",
        "api_key": os.environ["CHOCO_API_KEY"],
    },
    timeout=60,
)
event = resp.json()
print(event["name"], "-", event["start_time"])
print(event["location"], "- host:", event["host"])
print(event["attending_count"], "going /", event["interested_count"], "interested")

When I hit that endpoint without a provisioned key in July 2026 it returned HTTP 401 and the body {"error":{"code":"INVALID_API_KEY","message":"Missing api_key query parameter."}}, the expected response before you authenticate. With a key it returns the flattened event object, so your script reads clean fields instead of reverse-engineering the embedded JSON. You can get an API key from ChocoData to run the calls in this guide against a live event.

The same base handles event search and location feeds, which is the piece the DIY route cannot reach: because the public search endpoint redirects logged-out traffic, a managed session is what turns a query or a city URL into a list of event cards. For a one-off pull of a single public event, the og: parse above is free and fine. Once you need the host, the counts, or a recurring feed of many events, offloading the login wall is the cheaper path once you price in the hours you would spend maintaining a browser farm. I compare the managed options in the best Facebook scrapers of 2026, and the full multi-surface walkthrough sits in my complete guide to scraping Facebook.

FAQ

Can you scrape Facebook events without logging in?

Partly. On a fully public event, a logged-out GET returns the event name in og:title and usually the date and venue in og:description. The going/interested counts and the host sit in login-gated JSON, so a plain request does not populate them. In my July 2026 test the logged-out event search endpoint returned HTTP 302, a redirect to the login page, rather than results. Logged-off scraping of public data survived Meta v. Bright Data in January 2024.

Does the Facebook Graph API still return public events?

Only within narrow limits. The Event object still documents name, start_time, place, owner, attending_count, and interested_count, but Meta's Event reference states access to Events on Users and Pages is available only to Facebook Marketing Partners, and public event search by location was removed years ago. For an event you do not manage through a partner, the API returns nothing, which is why people parse the public page instead.

How do you get the going and interested counts from a Facebook event?

The going and interested numbers map to attending_count and interested_count in Facebook's event data, and they sit in the login-gated JSON rather than the og: meta tags. A plain logged-out request usually returns the name and date but not the counts. Clearing the login wall with an authenticated, residential session populates them, which is the work a scraper API does server-side before returning both counts as JSON.

Can you scrape Facebook events by location or city?

There is no official endpoint that lists every event in a city. Facebook discontinued public event search by location years ago, so the routes left are the event's own URL and the on-site events search, which redirected my logged-out request to a login page. A scraper API that runs an authenticated session can take a search or location URL and return the event cards as JSON, which is the practical way to build a city feed.

Why does a browser User-Agent return HTTP 400 on Facebook's event pages?

In my July 2026 tests, sending a full desktop Chrome User-Agent to facebook.com/events/search triggered an HTTP 400 error page of about 1,542 bytes, the same quirk I see on Facebook Pages. Facebook's edge makes a blocking decision on the whole request shape, so the header that looks most human is not reliably the one that returns data. Dropping the User-Agent changed the response to a 302 redirect, not usable data either, because the events surface is login-gated for logged-out traffic.

NB
Noah Berg
I've built Facebook data pipelines for years. On facebookscraperapi.com I run Facebook scraping methods against live pages and publish what actually holds up.