All use cases

Local events discovery: build a city calendar from social data

November 8, 2026

Short answer

Collect public event listings from the city's Facebook events page, keyword search and venue pages, then add buzz signals from Instagram hashtags, TikTok searches and local subreddits, dedupe and rank. One city takes about 180 credits a week, roughly $1.46 a month on the $47 pack. Store only public listing fields and link back to the original listing.

A good local events calendar needs two things: coverage, so nothing big is missing, and ranking, so the best ten events are at the top. Public Facebook event listings give you coverage. Social buzz on Instagram, TikTok and Reddit gives you ranking. This playbook combines them for one city or many.

The mechanics of collecting Facebook events by city, keyword or Page are in Facebook event scrapers. This page is about turning those listings into a calendar people trust.

Who does this

  • City guides and newsletters publishing "this weekend" picks.
  • Event and ticketing apps filling gaps in their own inventory.
  • Tourism boards showing visitors what is on during their stay.
  • Venues and promoters checking what else is on the same night before booking a date.

This is about public event listings: what is on, where and when. It is not about who is attending. Do not collect attendee lists or build profiles of the people who RSVP.

The data, per source

StepPlatformEndpointCalls a weekCredits
City events, this week and next, 4 pages eachFacebookfacebook events API88
Keyword searches (jazz, comedy, markets, run clubs, family)Facebookfacebook events search API55
Events from 40 venue PagesFacebookfacebook profile events API4040
Details for about 120 new eventsFacebookfacebook event details API120120
3 local event hashtagsInstagraminstagram search hashtag API33
"Things to do in [city] this weekend" and two moreTikToktiktok search keyword API33
The city subreddit's weekend threadRedditreddit subreddit search API11
Weekly total, one city180180

Worked example: cost

180 credits a week × 4.3 weeks = 774 credits a month for one city, about $1.46 on the $47 pack. Ten cities cost 7,740 credits, about $14.55, and one 25,000-credit pack lasts a little over three months at that size. The biggest line is event details, so fetch details only for events you have not seen before.

Dedupe: one event, many listings

The same concert can appear on the venue Page, the promoter's Page and the city feed. Treat two listings as one event when:

  1. the start date is the same (in the city's local time), and
  2. the venue name matches after lowercasing and removing words like "the" and "bar", and
  3. the title word overlap (Jaccard) is at least 0.6.

Keep the listing with the most complete details as the main record and store the other listing URLs alongside it.

Ranking: which ten go on top

  • Interest: the public response counts on the listing where it shows them, as a percentile within the week.
  • Buzz: mentions of the event name or headliner in the week's Instagram, TikTok and Reddit results, as a percentile.
  • Novelty: 1 if this is the first time the series has appeared, 0.5 if it is monthly, 0 if it is weekly. Readers already know the weekly trivia night.

Pick score = 0.4 × interest + 0.4 × buzz + 0.2 × novelty. Then apply a category cap, for example no more than three music events in the top ten, so the list reads like a guide and not a gig listing.

Also track coverage. Count events per neighborhood and per category each week. A neighborhood with zero events is usually a gap in your venue list, not a quiet area. Add venues there.

A collection script for the city feed

import os, requests

KEY = os.environ["SCRAPEIO_API_KEY"]
H = {"x-api-key": KEY}
CITY_PAGE = "CITY_EVENTS_PAGE_URL"  # copy the city's Facebook Events page URL from your browser
seen = set(open("seen_events.txt").read().split()) if os.path.exists("seen_events.txt") else set()

new = []
for when in ("this_week", "next_week"):
    cursor = None
    for _ in range(4):
        p = {"url": CITY_PAGE, "time": when}
        if cursor:
            p["cursor"] = cursor
        d = requests.get("https://scrapeio.com/v1/facebook/events", params=p,
                         headers=H, timeout=60).json()["data"]
        for e in d.get("items", d.get("events", [])):
            eid = str(e.get("id") or e.get("event_id"))
            if eid not in seen:
                seen.add(eid)
                new.append(eid)
        cursor = d.get("cursor")
        if not cursor:
            break

print(len(new), "new events to fetch details for")
open("seen_events.txt", "w").write("\n".join(seen))

Check the list key and id field in your first response on the endpoint page, then fetch details only for the ids in new.

Pitfalls

  • Time zones. Store start times in the event's local zone. A UTC midnight cut will move late shows to the wrong day.
  • Cancellations. Re-fetch details for your top picks 48 hours before the date. Postponed events often keep the same URL.
  • Recurring events. A weekly market can create 52 listings. Group them as one series.
  • Private events. Only public events are visible. Do not try to reach anything else.
  • Images. Event flyers belong to the organizer. Link to the listing rather than rehosting artwork without permission.
  • Personal data. Store the listing fields (title, time, venue, host Page, link). Do not store attendee names or profile links.

Run it from an AI agent

claude mcp add --transport http scrapeio https://scrapeio.com/mcp --header "x-api-key: $SCRAPEIO_API_KEY"

Then ask: "Call facebook_events for this city page for this_week, 3 pages. Add facebook_events_search for 'comedy' and 'night market'. Dedupe by date and venue, then check tiktok_search_keyword for 'things to do in Austin this weekend' and tell me which events are mentioned. Give me 10 picks with links and one line each." Tool lists are on the Facebook Events MCP server page.

How to do it with ScrapeIO

Facebook events by city, keyword and Page, event details, Instagram hashtags, TikTok search and Reddit all come through one key at 1 credit per call. Not-found and failed calls are not charged, which matters for a calendar where events get deleted between runs.

100 free credits, no card. Credits never expire.

Get API key