Facebook Event Search API. Events matching your search.
Events by keyword, anywhere or in one city. We handle the proxies, blocks and platform changes.
Facebook Event Search API at a glance
Searches public Facebook events by keyword, anywhere or in one place, and returns them in Facebook's own ranking. Each result has the event's ID, link and name, its start, venue and cover, whether it's online, its status, and how many people are interested and going. Narrow by date with since and until. When Facebook refuses the query, results come from the search's page and are thin: mostly the ID, link, name and a picture.
GET /v1/facebook/search_events
- 1 credit per page, $0.75–$1.97 per 1,000 pages
- 21 typed fields null when unknown
- 20 events per page, Facebook's ranking of the results, not by date
queryis all it needs, e.g.jazz
Send one request. Get up to 20 events back.
Copy the request in your language, or hand it to your agent. Sign up for an API key and your first 100 credits are free.
$ npm install socialtapquery = jazzconst params = new URLSearchParams({
query: "jazz",
});
const res = await fetch(`https://socialtap.dev/v1/facebook/search_events?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/facebook/search_events",
params={"query": "jazz"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/facebook/search_events")
uri.query = URI.encode_www_form('query' => 'jazz')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'query' => 'jazz',
]);
$ch = curl_init('https://socialtap.dev/v1/facebook/search_events?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("query", "jazz")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/facebook/search_events?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl 'https://socialtap.dev/v1/facebook/search_events?query=jazz' \
-H "x-api-key: $SOCIALTAP_API_KEY"{
"data": [
{
"approximate_fields": [],
"categories": [],
"community_id": null,
"cover_url": "https://scontent.ftol2-1.fna.fbcdn.net/v/t39.30808-6/737325123_4499264600219134_9055237808772320460_n.jpg?stp=c0.138.1254.836a_dst-jpg_tt6&cstp=mx1254x836&ctp=s1254x836&_nc_cat=101&_nc_map=urlgen_bucketless&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=23&…",
"description": null,
"end_at": null,
"hosts": [],
"id": "935939818906345",
"is_online": false,
"metrics": {
"attendee_count": 1
},
"name": "JAZZ fest «Blue Note»",
"parent_id": null,
"place": {
"address": null,
"city": null,
"country_code": null,
"id": null,
"latitude": null,
"longitude": null,
"name": "Тверская Область",
"url": null
},
"platform": "facebook",
"platform_specific": {
"facebook": {
"city_id": null,
"date_text": "Tue, Jun 1, 2027 - Jun 15, 2027",
"frequency": null,
"metrics": {
"interested_count": 3,
"response_count": null
},
"occurrence_count": null,
"price_text": null,
"ticket_provider": null
}
},
"start_at": "2027-05-31T21:00:00Z",
"status": "scheduled",
"ticket_url": null,
"time_zone": null,
"unknown_fields": [
"hosts",
"categories"
],
"url": "https://www.facebook.com/events/935939818906345/",
"utc_offset_minutes": null
},
{
"approximate_fields": [],
"categories": [],
"community_id": null,
"cover_url": "https://scontent.ftol2-1.fna.fbcdn.net/v/t39.30808-6/583712862_1185733750330218_7695504167411277837_n.jpg?stp=c160.0.1728.1152a_dst-jpg_tt6&cstp=mx1728x1152&ctp=s1728x1152&_nc_cat=106&_nc_map=urlgen_bucketless&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=…",
"description": null,
"end_at": null,
"hosts": [],
"id": "733095653165588",
"is_online": false,
"metrics": {
"attendee_count": null
},
"name": "Jazz Jam",
"parent_id": null,
"place": {
"address": null,
"city": null,
"country_code": null,
"id": "602685513168965",
"latitude": null,
"longitude": null,
"name": "Funk 'n Waffles Syracuse",
"url": null
},
"platform": "facebook",
"platform_specific": {
"facebook": {
"city_id": null,
"date_text": "Sun, Nov 8 at 3:00 PM EST and 7 more",
"frequency": null,
"metrics": {
"interested_count": 403,
"response_count": null
},
"occurrence_count": null,
"price_text": null,
"ticket_provider": null
}
},
"start_at": "2025-11-23T20:00:00Z",
"status": "ongoing",
"ticket_url": null,
"time_zone": null,
"unknown_fields": [
"hosts",
"categories"
],
"url": "https://www.facebook.com/events/733095653165588/",
"utc_offset_minutes": -300
},
{
"approximate_fields": [
"platform_specific.facebook.metrics.interested_count"
],
"categories": [],
"community_id": null,
"cover_url": "https://scontent.ftol2-1.fna.fbcdn.net/v/t39.30808-6/866591974_1157426943381928_6760248865572493930_n.jpg?stp=c206.0.1508.1005a_dst-jpg_tt6&cstp=mx1508x1005&ctp=s1508x1005&_nc_cat=107&_nc_map=urlgen_bucketless&ccb=SCRUBBED&_nc_sid=SCRUBBED&_nc_ohc=SCRUBBED&_nc_oc=SCRUBBED&_nc_zt=…",
"description": null,
"end_at": null,
"hosts": [],
"id": "769677042050918",
"is_online": false,
"metrics": {
"attendee_count": 1
},
"name": "Sunday Jazz Service",
"parent_id": null,
"place": {
"address": null,
"city": null,
"country_code": null,
"id": null,
"latitude": null,
"longitude": null,
"name": "Eliaskirken, Vesterbrogade 49, 1620 Copenhagen, Denmark",
"url": null
},
"platform": "facebook",
"platform_specific": {
"facebook": {
"city_id": null,
"date_text": "Sun, Nov 8 at 1:00 PM CET and 2 more",
"frequency": null,
"metrics": {
"interested_count": 1400,
"response_count": null
},
"occurrence_count": null,
"price_text": null,
"ticket_provider": null
}
},
"start_at": "2025-11-02T12:00:00Z",
"status": "ongoing",
"ticket_url": null,
"time_zone": null,
"unknown_fields": [
"hosts",
"categories"
],
"url": "https://www.facebook.com/events/769677042050918/",
"utc_offset_minutes": 60
}
],
"page": {
"has_more": true,
"next_cursor": "c1.EXAMPLE_CURSOR",
"next_cursor_expires_at": "2026-10-26T12:00:00Z",
"end_reason": null
},
"meta": {
"request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
"platform": "facebook",
"source": "api",
"is_cached": false,
"credits_charged": 1,
"latency_ms": 1374,
"fetched_at": "2026-10-25T12:00:00Z",
"input": null,
"credits_remaining": 9999,
"client_request_id": null,
"warnings": []
}
}import { SocialTap } from "socialtap";
const client = new SocialTap(); // apiKey defaults to process.env.SOCIALTAP_API_KEY
const res = await client.facebook.searchEvents.list({ query: "jazz" });
console.log(res.data);
console.log(res.credits.charged, res.meta.request_id);import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws Exception {
String query = "query=" + encode("jazz");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://socialtap.dev/v1/facebook/search_events?" + query))
.header("x-api-key", System.getenv("SOCIALTAP_API_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// An error is {"error": {"code", "message", ...}}; success is {data, meta}, meta.credits_charged its price.
if (response.statusCode() >= 400) throw new RuntimeException(response.body());
System.out.println(response.body());
}
static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
}using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("SOCIALTAP_API_KEY"));
var query = string.Join("&",
"query=" + Uri.EscapeDataString("jazz"));
var res = await http.GetAsync("https://socialtap.dev/v1/facebook/search_events?" + query);
using var body = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
if (!res.IsSuccessStatusCode)
{
var error = body.RootElement.GetProperty("error");
throw new Exception($"{error.GetProperty("code")}: {error.GetProperty("message")}");
}
Console.WriteLine(body.RootElement.GetProperty("data"));
Console.WriteLine(body.RootElement.GetProperty("meta").GetProperty("credits_charged"));// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::blocking::Client::new()
.get("https://socialtap.dev/v1/facebook/search_events")
.query(&[("query", "jazz")])
.header("x-api-key", env::var("SOCIALTAP_API_KEY")?)
.send()?;
let ok = res.status().is_success();
let body: serde_json::Value = res.json()?;
if !ok {
return Err(format!("{}: {}", body["error"]["code"], body["error"]["message"]).into());
}
println!("{} {}", body["data"], body["meta"]["credits_charged"]);
Ok(())
}200 OK · GET https://socialtap.dev/v1/facebook/search_eventsLong arrays and strings are shortened here. Real responses are complete.Docs What you send and what comes back.
The response reference lists every field, its type and when it is null. See the full schema.
Null means unknown
A field Facebook Events doesn't show is null, never zero or an empty string, so a real zero always means zero.
What it accepts
The words to search events for, as in Facebook's event search: names, artists, topics, places.
What comes back
Public events with their start and end, time zone, venue or online flag, hosts, categories, ticket link and attendance.
platformstring- Platform ID (facebook, …).
idstring- Platform-native event ID (string; Facebook's numeric event ID).
urlstring- Canonical event page URL (https://www.facebook.com/events/<id>/).
namestring- The event's name as its page shows it.
descriptionstring- Its description as plain text; null when it has none.
statusstring- At fetch time: scheduled (not started), ongoing (started, not over), ended (over), canceled (called off by its hosts); unknown when the source that answered does not show it (a fallback whose results hold only a name and a picture). New values may be added; treat any other value as unknown.
start_atstring- When it starts, RFC 3339 UTC; null only when the platform shows no start.
end_atstring- When it ends, RFC 3339 UTC; null when its hosts set no end or the platform does not show it.
Live data from 33 platforms.
What teams build with the Facebook Event Search API.
Find upcoming events on a topic or artist
Rank events by how many are going
Monitor a keyword for new events
Check whether a brand's event is listed
Good to know before you build.
- A result holds id, url, name, start_at, status, is_online, place, cover_url, platform_specific.facebook.date_text and, when Facebook shows them, its interested and going counts and price text. description, end_at and ticket_url are null and hosts and categories [] (listed in unknown_fields), because a search doesn't show them: send an id to the Facebook Event API for its full record.
- A recurring event's start_at is the first date of its series, which can be long past, and its status is ongoing until the series ends. platform_specific.facebook.date_text gives its next date as Facebook shows it, and the Facebook Event API returns the series.
- Counts of a thousand or more are rounded by Facebook and listed in approximate_fields.
- A venue is often the text its host typed: then place has a name and no ID.
- When Facebook refuses the query (its rate limit, or a change on its side), the first page comes from the search's own page (meta.source page), with fewer and thinner results: id, url, name and a square cover_url, status unknown, and start_at, place, date_text and the counts null. page.next_cursor goes on with whole results.
- since and until go to Facebook's date filter, which reads whole days and keeps a recurring event by any of its dates, so a result's start_at can be before since.
- Results come in Facebook's ranking, not by date, and it depends on where the request comes from: the same words can return different events from one request to the next. location narrows them to one place.
- Facebook returns nothing for some single common words (party, bar, wine), from every country tried, while a phrase with one of them answers in full (birthday party). That empty list is Facebook's answer and is charged as usual, so try a longer phrase.
- A search with no results returns an empty list, and so does a location ID that names no place. A page can hold fewer events than limit and the list still goes on: follow page.next_cursor until it ends.
- If Facebook's search returns next to nothing where the request comes from, on every try, the search answers upstream_blocked and costs nothing, rather than a false empty list: retry later.
- Cursors expire sooner than on most lists, because Facebook's do: an older one returns invalid_cursor, and the search starts again from its first page.
1 credit per page. Failed requests are free.
Buy credits once and spend them on any endpoint, on any platform.
| Source | Price per successful page | Per 1,000 pages |
|---|---|---|
| Any source | 1 credit | $0.75–$1.97 |
- Cache hits are free.
- Credits from packs and top-ups never expire.
- A monthly plan's credits are spent first, and what is left of them ends at each renewal.
- Prices exclude tax: sales tax is added at checkout where it applies.
- Outside the US, plans and packs are sold to businesses: checkout asks for your VAT, GST or other business tax ID.
Questions about the Facebook Event Search API.
More in the API reference.
What does a result leave out?
How do I search one city?
Does it find past events?
How much does the Facebook Event Search API cost?
How do I get the next page?
Try it with your own search.
Type it in the playground, or copy the request into your code.
- No credit card
- Failed requests are free
- Works on all 218 endpoints