Facebook API
The TrueScrape Facebook API exposes 22 public endpoints covering Ad details, Ad video transcript and Find advertisers running ads. Every call is a GET against public, logged-out pages and returns the same unified schema as every other platform here. Calls cost 1–2 credits each. A cache hit is free, and a failed or empty response is never charged.
Endpoints
| Endpoint | Returns | Credits | Cacheable | Batchable |
|---|---|---|---|---|
| /v1/facebook/ad-library/ad | Ad details | 1 | yes | yes |
| /v1/facebook/ad-library/ad-transcript | Ad video transcript | 1 | yes | yes |
| /v1/facebook/ad-library/advertisers | Find advertisers running ads | 1 | yes | yes |
| /v1/facebook/ad-library/page-ads | All ads for one advertiser | 2 | yes | yes |
| /v1/facebook/ad-library/search | Search the Meta Ad Library | 2 | yes | yes |
| /v1/facebook/city-events | Get the events of a city | 1 | yes | yes |
| /v1/facebook/comment-replies | Replies to a comment | 1 | yes | yes |
| /v1/facebook/event | Event details | 1 | yes | yes |
| /v1/facebook/events/search | Search public events | 1 | yes | yes |
| /v1/facebook/group | Public group info | 1 | yes | yes |
| /v1/facebook/group-posts | Public group posts | 1 | yes | yes |
| /v1/facebook/marketplace/item | Marketplace listing details | 1 | yes | yes |
| /v1/facebook/marketplace/locations | Find a Marketplace location | 1 | yes | yes |
| /v1/facebook/marketplace/search | Search Marketplace listings | 1 | yes | yes |
| /v1/facebook/page-posts | Public Page posts | 1 | yes | yes |
| /v1/facebook/page-reels | Public Page videos and reels | 1 | yes | yes |
| /v1/facebook/post | Single post, video, or reel | 1 | yes | yes |
| /v1/facebook/post-comments | Comments on a post | 1 | yes | yes |
| /v1/facebook/post-transcript | Video transcript | 1 | yes | yes |
| /v1/facebook/profile | Public Page profile | 1 | yes | yes |
| /v1/facebook/profile-events | Events on a Page | 1 | yes | yes |
| /v1/facebook/profile-photos | Photos on a Page | 1 | yes | yes |
Reference
/v1/facebook/ad-library/ad1 creditcacheablebatchableAd details
One ad from the Meta Ad Library by its archive id. Meta does not expose the archive as an addressable node for every ad; pass page_id as well and we find it by scanning that advertiser's archive instead.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | yes | Ad archive id, or an Ad Library URL containing ?id= |
| page_id | string | no | The advertiser's page id. Enables the archive-scan fallback. |
| country | string | no | Reached country used by the fallback scandefaults to US |
| url | string | no | Ad archive id, or an Ad Library URL containing ?id= |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Ad.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| advertiserId | string | null | always | |
| advertiserName | string | null | always | |
| url | string | null | always | Link to the ad's page in the platform's ad library. |
| headline | string | null | always | |
| body | string | null | always | |
| ctaText | string | null | always | Text of the call-to-action button, such as "Shop now". |
| linkUrl | string | null | always | Where the ad links to. Some ad libraries expose only the destination's domain. |
| creativeType | string | null | always | Format of the ad creative, such as `video` or `image`, as the ad library labels it. |
| imageUrls | string[] | always | |
| videoUrls | string[] | always | |
| platforms | string[] | always | Platforms the ad was shown on, in lowercase, such as `facebook` or `instagram`. |
| countries | string[] | always | Countries the ad ran in or targeted, usually as two-letter country codes. |
| languages | string[] | always | |
| startedAt | string | null | always | |
| endedAt | string | null | always | When the ad stopped running. Null while it is still running, or when the ad library reports no end date. |
| isActive | boolean | null | always | |
| impressionsLower | number | null | always | Lower bound of the impressions range the ad library reports. Libraries publish a range, not an exact figure. |
| impressionsUpper | number | null | always | Upper bound of the impressions range the ad library reports. |
| spendLower | number | null | always | Lower bound of the reported spend range, in `currency`. |
| spendUpper | number | null | always | Upper bound of the reported spend range, in `currency`. |
| currency | string | null | always | Currency of the spend range, as a code such as `USD`. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/ad-library/ad?id=%3Cid%3E&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
id: '<id>',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/ad-library/ad?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/ad-library/ad",
params={
"id": "<id>",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/ad-library/ad-transcript1 creditcacheablebatchableAd video transcript
Retrieves a transcript for a single Facebook Ad Library video ad by ID or URL, read from the caption track Facebook publishes for the ad's video (source: "captions"). Transcription of ad videos without captions is coming soon; until then those answer not_configured (501) and are not charged. Credits are only deducted when a transcript is actually returned. **Required:** Pass exactly one of id or url.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | no | Ad archive id, or an Ad Library URL containing ?id= |
| url | string | no | An Ad Library URL containing ?id= |
| language | string | no | Preferred caption locale |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Transcript.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| postId | string | always | |
| url | string | null | always | |
| language | string | null | always | The transcript's language as the platform labels it, usually a language code such as `en`. |
| isAutoGenerated | boolean | null | always | Whether the platform generated the captions automatically, by speech recognition or machine translation, rather than a person writing them. |
| text | string | always | The full transcript as a single block of text. |
| cues | object[] | always | Timed segments of the transcript. |
| cues[].start | number | always | Seconds from the start of the media. |
| cues[].end | number | null | always | Seconds from the start of the media. Null when the platform gives no end time. |
| cues[].text | string | always | |
| durationSeconds | number | null | always | |
| source | captions | asr | null | always | Where the transcript came from. `captions`: the platform's own caption track, whether a person wrote it or the platform generated it (see `isAutoGenerated`). `asr`: produced by speech recognition on the audio. Null when this cannot be told. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/ad-library/ad-transcript?cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/ad-library/ad-transcript?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/ad-library/ad-transcript",
params={
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/ad-library/advertisers1 creditcacheablebatchableFind advertisers running ads
Distinct advertisers whose ads match a search term, with the page_id needed by /v1/facebook/ad-library/page-ads. Derived from the ads an Ad Library search returns, ranked by how many of them each advertiser ran.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | yes | Advertiser name or a term from their ad copy |
| country | string | no | defaults to US |
| status | active | inactive | all | no | defaults to active |
| limit | number | no | Ads sampled, 1-100. More ads means more advertisers. |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Creator in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | The platform's own id for the account, such as a channel id or a numeric user id, always as a string. |
| handle | string | null | always | The account handle without the leading @. Null when the platform has no handles. |
| displayName | string | null | always | |
| bio | string | null | always | |
| avatarUrl | string | null | always | |
| bannerUrl | string | null | always | |
| url | string | null | always | |
| verified | boolean | null | always | Whether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it. |
| followerCount | number | null | always | Followers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it. |
| followingCount | number | null | always | |
| postCount | number | null | always | Posts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published. |
| viewCount | number | null | always | Lifetime views across the account, where the platform exposes a total. |
| likeCount | number | null | may be absent | Total likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it. |
| isPrivate | boolean | null | always | |
| isBusiness | boolean | null | always | Whether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures. |
| category | string | null | always | A label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform. |
| location | string | null | always | Location as the platform shows it: a city, a country, a region code or an address, depending on the platform. |
| externalLinks | string[] | always | Links the account lists on its profile, such as a website or other social accounts. |
| createdAt | string | null | always | When the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/ad-library/advertisers?query=ai%20agents&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
query: 'ai agents',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/ad-library/advertisers?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/ad-library/advertisers",
params={
"query": "ai agents",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/ad-library/page-ads2 creditscacheablebatchableAll ads for one advertiser
Ads a specific Facebook page is running or has run, from Meta's Ad Library. This is the competitor-monitoring endpoint. pagination.cursor is filled only where the deployment reads the Graph Ad Library API; otherwise pagination.hasMore says whether more exist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| page_id | string | yes | Numeric page id, or an Ad Library URL containing view_all_page_id |
| country | string | no | ISO-3166 country code(s) the ad reached, comma-separated. Meta requires at least one.defaults to US |
| status | active | inactive | all | no | Delivery status at the time of the query.defaults to active |
| ad_type | all | political | housing | employment | credit | no | political unlocks Meta's spend, impression and demographic fields.defaults to all |
| media_type | all | image | meme | video | none | no | — |
| platform | string | no | Comma-separated: facebook, instagram, messenger, audience_network, threads, whatsapp, oculus |
| language | string | no | Comma-separated BCP-47 codes, e.g. "en,es" |
| start_date | string | no | Earliest delivery date, YYYY-MM-DD |
| end_date | string | no | Latest delivery date, YYYY-MM-DD |
| limit | number | no | Ads per page, 1-100. Default 25. |
| cursor | string | no | pagination.cursor from a previous response |
| pageId | string | no | Numeric page id, or an Ad Library URL containing view_all_page_id |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Ad in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| advertiserId | string | null | always | |
| advertiserName | string | null | always | |
| url | string | null | always | Link to the ad's page in the platform's ad library. |
| headline | string | null | always | |
| body | string | null | always | |
| ctaText | string | null | always | Text of the call-to-action button, such as "Shop now". |
| linkUrl | string | null | always | Where the ad links to. Some ad libraries expose only the destination's domain. |
| creativeType | string | null | always | Format of the ad creative, such as `video` or `image`, as the ad library labels it. |
| imageUrls | string[] | always | |
| videoUrls | string[] | always | |
| platforms | string[] | always | Platforms the ad was shown on, in lowercase, such as `facebook` or `instagram`. |
| countries | string[] | always | Countries the ad ran in or targeted, usually as two-letter country codes. |
| languages | string[] | always | |
| startedAt | string | null | always | |
| endedAt | string | null | always | When the ad stopped running. Null while it is still running, or when the ad library reports no end date. |
| isActive | boolean | null | always | |
| impressionsLower | number | null | always | Lower bound of the impressions range the ad library reports. Libraries publish a range, not an exact figure. |
| impressionsUpper | number | null | always | Upper bound of the impressions range the ad library reports. |
| spendLower | number | null | always | Lower bound of the reported spend range, in `currency`. |
| spendUpper | number | null | always | Upper bound of the reported spend range, in `currency`. |
| currency | string | null | always | Currency of the spend range, as a code such as `USD`. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/ad-library/page-ads?page_id=%3Cpage_id%3E&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
page_id: '<page_id>',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/ad-library/page-ads?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 2 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/ad-library/page-ads",
params={
"page_id": "<page_id>",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/ad-library/search2 creditscacheablebatchableSearch the Meta Ad Library
Facebook, Instagram, Messenger and Threads ads matching a search term, from Meta's Ad Library, in the Library's own order. Spend and impression ranges are filled for political and issue ads only where the deployment reads the Graph Ad Library API; pagination.hasMore says when more results exist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | yes | Search term, matched against ad text and advertiser name |
| search_type | unordered | exact_phrase | no | exact_phrase matches the words in orderdefaults to unordered |
| country | string | no | ISO-3166 country code(s) the ad reached, comma-separated. Meta requires at least one.defaults to US |
| status | active | inactive | all | no | Delivery status at the time of the query.defaults to active |
| ad_type | all | political | housing | employment | credit | no | political unlocks Meta's spend, impression and demographic fields.defaults to all |
| media_type | all | image | meme | video | none | no | — |
| platform | string | no | Comma-separated: facebook, instagram, messenger, audience_network, threads, whatsapp, oculus |
| language | string | no | Comma-separated BCP-47 codes, e.g. "en,es" |
| start_date | string | no | Earliest delivery date, YYYY-MM-DD |
| end_date | string | no | Latest delivery date, YYYY-MM-DD |
| limit | number | no | Ads per page, 1-100. Default 25. |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Ad in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| advertiserId | string | null | always | |
| advertiserName | string | null | always | |
| url | string | null | always | Link to the ad's page in the platform's ad library. |
| headline | string | null | always | |
| body | string | null | always | |
| ctaText | string | null | always | Text of the call-to-action button, such as "Shop now". |
| linkUrl | string | null | always | Where the ad links to. Some ad libraries expose only the destination's domain. |
| creativeType | string | null | always | Format of the ad creative, such as `video` or `image`, as the ad library labels it. |
| imageUrls | string[] | always | |
| videoUrls | string[] | always | |
| platforms | string[] | always | Platforms the ad was shown on, in lowercase, such as `facebook` or `instagram`. |
| countries | string[] | always | Countries the ad ran in or targeted, usually as two-letter country codes. |
| languages | string[] | always | |
| startedAt | string | null | always | |
| endedAt | string | null | always | When the ad stopped running. Null while it is still running, or when the ad library reports no end date. |
| isActive | boolean | null | always | |
| impressionsLower | number | null | always | Lower bound of the impressions range the ad library reports. Libraries publish a range, not an exact figure. |
| impressionsUpper | number | null | always | Upper bound of the impressions range the ad library reports. |
| spendLower | number | null | always | Lower bound of the reported spend range, in `currency`. |
| spendUpper | number | null | always | Upper bound of the reported spend range, in `currency`. |
| currency | string | null | always | Currency of the spend range, as a code such as `USD`. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/ad-library/search?query=ai%20agents&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
query: 'ai agents',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/ad-library/search?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 2 credits, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/ad-library/search",
params={
"query": "ai agents",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/city-events1 creditcacheablebatchableGet the events of a city
Public events Facebook is suggesting for a city, from its Events Explore feed (e.g. https://www.facebook.com/events/explore/saint-petersburg-florida/111326725552547). time narrows the window to today, this week, or next week; without it Facebook returns whatever it has queued as upcoming, in whatever order it ranks them. Only the first, server-rendered page: host and description are not exposed on this listing (only on /v1/facebook/event). pagination.hasMore says whether Facebook has more; this endpoint returns no cursor to fetch them.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Explore URL ("facebook.com/events/explore/<city-slug>/<id>") or a bare "<city-slug>/<id>" pair |
| time | today | this_week | next_week | no | Narrow to Facebook's own window. Defaults to all upcoming. |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of object in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| name | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| startsAt | string | null | always | ISO 8601, UTC. |
| endsAt | string | null | always | ISO 8601, UTC. Null when the event has no end time. |
| timeText | string | null | always | Facebook's own rendering of the time, e.g. "Sat, Sep 5 at 3:00 PM MDT". It carries the event's LOCAL timezone, which the epoch timestamps do not. |
| isOnline | boolean | null | always | |
| isCanceled | boolean | null | always | |
| isPast | boolean | null | always | |
| place | object | null | always | |
| place.id | string | null | always | |
| place.name | string | null | always | |
| place.address | string | null | always | |
| place.latitude | number | null | always | |
| place.longitude | number | null | always | |
| hostId | string | null | always | |
| hostName | string | null | always | |
| hostUrl | string | null | always | |
| thumbnailUrl | string | null | always | |
| ticketPriceText | string | null | always | |
| interestedCount | number | null | always | People who marked the event Interested or Going. In list results above a thousand, Facebook's rounded figure ("1.2K"). |
| fetchedAt | string | always |
curl "$API/v1/facebook/city-events?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/city-events?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/city-events",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/comment-replies1 creditcacheablebatchableReplies to a comment
Replies under one comment on a public Facebook post, ten per page. Pass the post URL and the comment id (the id of any item from /v1/facebook/post-comments), then pagination.cursor for the next page.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Full post URL the comment sits on |
| comment_id | string | yes | Numeric comment id |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Comment in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| postId | string | null | always | |
| parentId | string | null | always | Id of the comment this one replies to. Null on a top-level comment. |
| text | string | always | |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| authorAvatarUrl | string | null | always | |
| likeCount | number | null | always | |
| replyCount | number | null | always | |
| isPinned | boolean | null | always | |
| isAuthorReply | boolean | null | always | Whether the comment was written by the author of the post. |
| publishedAt | string | null | always | When the comment was posted. Usually an ISO 8601 timestamp; some platforms expose only relative text such as "2 days ago". |
curl "$API/v1/facebook/comment-replies?url=8XkPqR2nLvE&comment_id=%3Ccomment_id%3E&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
comment_id: '<comment_id>',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/comment-replies?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/comment-replies",
params={
"url": "8XkPqR2nLvE",
"comment_id": "<comment_id>",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/event1 creditcacheablebatchableEvent details
Full details for one public Facebook event: description, start and end time, venue with coordinates, host and ticket price range.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Event URL or numeric event id |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns an object with platform, id, name, url, description, startsAt, endsAt, timeText, isOnline, isCanceled, isPast, place, hostId, hostName, hostUrl, thumbnailUrl, ticketPriceText, interestedCount, fetchedAt.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| name | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| startsAt | string | null | always | ISO 8601, UTC. |
| endsAt | string | null | always | ISO 8601, UTC. Null when the event has no end time. |
| timeText | string | null | always | Facebook's own rendering of the time, e.g. "Sat, Sep 5 at 3:00 PM MDT". It carries the event's LOCAL timezone, which the epoch timestamps do not. |
| isOnline | boolean | null | always | |
| isCanceled | boolean | null | always | |
| isPast | boolean | null | always | |
| place | object | null | always | |
| place.id | string | null | always | |
| place.name | string | null | always | |
| place.address | string | null | always | |
| place.latitude | number | null | always | |
| place.longitude | number | null | always | |
| hostId | string | null | always | |
| hostName | string | null | always | |
| hostUrl | string | null | always | |
| thumbnailUrl | string | null | always | |
| ticketPriceText | string | null | always | |
| interestedCount | number | null | always | People who marked the event Interested or Going. In list results above a thousand, Facebook's rounded figure ("1.2K"). |
| fetchedAt | string | always |
curl "$API/v1/facebook/event?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/event?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/event",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/events/search1 creditcacheablebatchableSearch public events
Public Facebook events matching a search term. Results are ranked and biased toward where Facebook places the request, so the same query can return a different set on another call. Treat this as discovery, not as an enumerable list.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | yes | What to search for, e.g. "jazz festival" |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of object in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| name | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| startsAt | string | null | always | ISO 8601, UTC. |
| endsAt | string | null | always | ISO 8601, UTC. Null when the event has no end time. |
| timeText | string | null | always | Facebook's own rendering of the time, e.g. "Sat, Sep 5 at 3:00 PM MDT". It carries the event's LOCAL timezone, which the epoch timestamps do not. |
| isOnline | boolean | null | always | |
| isCanceled | boolean | null | always | |
| isPast | boolean | null | always | |
| place | object | null | always | |
| place.id | string | null | always | |
| place.name | string | null | always | |
| place.address | string | null | always | |
| place.latitude | number | null | always | |
| place.longitude | number | null | always | |
| hostId | string | null | always | |
| hostName | string | null | always | |
| hostUrl | string | null | always | |
| thumbnailUrl | string | null | always | |
| ticketPriceText | string | null | always | |
| interestedCount | number | null | always | People who marked the event Interested or Going. In list results above a thousand, Facebook's rounded figure ("1.2K"). |
| fetchedAt | string | always |
curl "$API/v1/facebook/events/search?query=ai%20agents&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
query: 'ai agents',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/events/search?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/events/search",
params={
"query": "ai agents",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/group1 creditcacheablebatchablePublic group info
Name, member count, privacy setting and description for a public Facebook group. Member count lands in followerCount (a group's equivalent of an audience size) and the privacy setting in category. Facebook rounds that count on large groups ("12K members"); raw.memberCountIsApproximate says whether the number you got was rounded.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Group URL, group id, or group slug |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Creator.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | The platform's own id for the account, such as a channel id or a numeric user id, always as a string. |
| handle | string | null | always | The account handle without the leading @. Null when the platform has no handles. |
| displayName | string | null | always | |
| bio | string | null | always | |
| avatarUrl | string | null | always | |
| bannerUrl | string | null | always | |
| url | string | null | always | |
| verified | boolean | null | always | Whether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it. |
| followerCount | number | null | always | Followers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it. |
| followingCount | number | null | always | |
| postCount | number | null | always | Posts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published. |
| viewCount | number | null | always | Lifetime views across the account, where the platform exposes a total. |
| likeCount | number | null | may be absent | Total likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it. |
| isPrivate | boolean | null | always | |
| isBusiness | boolean | null | always | Whether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures. |
| category | string | null | always | A label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform. |
| location | string | null | always | Location as the platform shows it: a city, a country, a region code or an address, depending on the platform. |
| externalLinks | string[] | always | Links the account lists on its profile, such as a website or other social accounts. |
| createdAt | string | null | always | When the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/group?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/group?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/group",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/group-posts1 creditcacheablebatchablePublic group posts
Recent posts from a public Facebook group, with reaction, comment and share counts where Facebook renders them. Only the newest few stories render to a logged-out visitor, the same limit /v1/facebook/page-posts has. Private groups return an empty result; their posts are not public and we do not log in.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Group URL, group id, or group slug |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Post in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| type | video | short | image | carousel | text | live | story | reel | audio | album | episode | unknown | always | What kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else. |
| url | string | null | always | |
| title | string | null | always | |
| text | string | null | always | The post's text: a caption, a description or the message body. |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| thumbnailUrl | string | null | always | |
| mediaUrls | string[] | always | |
| durationSeconds | number | null | always | |
| viewCount | number | null | always | Views. Null means the platform did not expose a count, which is not the same as zero. |
| likeCount | number | null | always | Likes, or the platform's nearest equivalent. Null means not exposed, not zero. |
| commentCount | number | null | always | Comments. Null means not exposed, not zero. |
| shareCount | number | null | always | Shares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero. |
| hashtags | string[] | always | Hashtags or the platform's own topic tags, without the leading #. |
| mentions | string[] | always | Handles mentioned in the post text, without the leading @. |
| taggedUsers | string[] | may be absent | Usernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none. |
| isSponsored | boolean | null | always | Whether the platform labels the post as an ad, promoted content or a paid partnership. |
| publishedAt | string | null | always | When the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago". |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/group-posts?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/group-posts?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/group-posts",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/marketplace/item1 creditcacheablebatchableMarketplace listing details
One public Facebook Marketplace listing: title, full description, price, location, delivery options and every photo. Facebook does not render the seller to a logged-out visitor, so seller identity is not returned.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Marketplace item URL or numeric listing id |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns an object with platform, id, title, url, description, priceText, priceAmount, originalPriceText, isSold, isPending, isLive, locationText, city, state, categoryId, deliveryTypes, thumbnailUrl, imageUrls, listedAt, fetchedAt.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| title | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| priceText | string | null | always | As Facebook formatted it, e.g. "$150", carrying the currency symbol. |
| priceAmount | number | null | always | Numeric amount in the listing's own currency. |
| originalPriceText | string | null | always | The pre-discount price, when the seller marked one down. |
| isSold | boolean | null | always | |
| isPending | boolean | null | always | |
| isLive | boolean | null | always | |
| locationText | string | null | always | |
| city | string | null | always | |
| state | string | null | always | |
| categoryId | string | null | always | |
| deliveryTypes | string[] | always | |
| thumbnailUrl | string | null | always | |
| imageUrls | string[] | always | Up to ten, the first of which is `thumbnailUrl`. |
| listedAt | string | null | always | |
| fetchedAt | string | always |
curl "$API/v1/facebook/marketplace/item?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/marketplace/item?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/marketplace/item",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/marketplace/locations1 creditcacheablebatchableFind a Marketplace location
Resolve a place name to the Marketplace location ids /v1/facebook/marketplace/search accepts, plus the neighbouring locations Facebook offers around it. Marketplace is city-scoped, so this is how you search a city you are not sitting in.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | yes | Place name, e.g. "London" or "San Francisco" |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of object in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | City page id where Facebook gave one, otherwise the resolved slug. Either is valid as `location` on /v1/facebook/marketplace/search. |
| name | string | always | |
| url | string | always | |
| isPrimary | boolean | always | True for the place the query resolved to; the rest are its neighbours. |
| fetchedAt | string | always |
curl "$API/v1/facebook/marketplace/locations?query=ai%20agents&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
query: 'ai agents',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/marketplace/locations?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/marketplace/locations",
params={
"query": "ai agents",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/marketplace/search1 creditcacheablebatchableSearch Marketplace listings
Public Facebook Marketplace listings matching a search term, with price, condition flags, location and photos. location takes a city slug or a location id from /v1/facebook/marketplace/locations; without one, Facebook picks the city it places the request in, which you do not control. Pass location for results you can repeat.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | yes | What to search for, e.g. "mountain bike" |
| location | string | no | City slug ("nyc", "london") or a location id from /v1/facebook/marketplace/locations |
| min_price | number | no | Lowest price, in the location's currency |
| max_price | number | no | Highest price, in the location's currency |
| days_since_listed | number | no | Only listings posted in the last N days |
| radius_km | number | no | Search radius around the location, in kilometres |
| sort_by | best_match | creation_time_descend | price_ascend | price_descend | distance_ascend | no | Facebook's own sort keys |
| delivery_method | local_pick_up | shipping | no | Restrict to collection-only or shipped listings |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of object in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| title | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| priceText | string | null | always | As Facebook formatted it, e.g. "$150", carrying the currency symbol. |
| priceAmount | number | null | always | Numeric amount in the listing's own currency. |
| originalPriceText | string | null | always | The pre-discount price, when the seller marked one down. |
| isSold | boolean | null | always | |
| isPending | boolean | null | always | |
| isLive | boolean | null | always | |
| locationText | string | null | always | |
| city | string | null | always | |
| state | string | null | always | |
| categoryId | string | null | always | |
| deliveryTypes | string[] | always | |
| thumbnailUrl | string | null | always | |
| imageUrls | string[] | always | Up to ten, the first of which is `thumbnailUrl`. |
| listedAt | string | null | always | |
| fetchedAt | string | always |
curl "$API/v1/facebook/marketplace/search?query=ai%20agents&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
query: 'ai agents',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/marketplace/search?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/marketplace/search",
params={
"query": "ai agents",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/page-posts1 creditcacheablebatchablePublic Page posts
Recent public posts from a Facebook Page, newest first, three per page, with text, reaction, comment and share counts, and the publish timestamp. Pass pagination.cursor back for the next three.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Page URL, @handle, slug, or numeric page id |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Post in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| type | video | short | image | carousel | text | live | story | reel | audio | album | episode | unknown | always | What kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else. |
| url | string | null | always | |
| title | string | null | always | |
| text | string | null | always | The post's text: a caption, a description or the message body. |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| thumbnailUrl | string | null | always | |
| mediaUrls | string[] | always | |
| durationSeconds | number | null | always | |
| viewCount | number | null | always | Views. Null means the platform did not expose a count, which is not the same as zero. |
| likeCount | number | null | always | Likes, or the platform's nearest equivalent. Null means not exposed, not zero. |
| commentCount | number | null | always | Comments. Null means not exposed, not zero. |
| shareCount | number | null | always | Shares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero. |
| hashtags | string[] | always | Hashtags or the platform's own topic tags, without the leading #. |
| mentions | string[] | always | Handles mentioned in the post text, without the leading @. |
| taggedUsers | string[] | may be absent | Usernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none. |
| isSponsored | boolean | null | always | Whether the platform labels the post as an ad, promoted content or a paid partnership. |
| publishedAt | string | null | always | When the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago". |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/page-posts?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/page-posts?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/page-posts",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/page-reels1 creditcacheablebatchablePublic Page videos and reels
Public videos and reels from a Facebook Page. Reads the Page's reels tab first, ten per page with pagination.cursor for the next ten, and falls back to its video grid, which renders around twenty entries with titles, view counts and durations and has no cursor, so a Page with no reels returns its videos rather than an error. Items are keyed by video id and can be passed straight to /v1/facebook/post or /v1/facebook/post-transcript.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Page URL, @handle, slug, or numeric page id |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Post in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| type | video | short | image | carousel | text | live | story | reel | audio | album | episode | unknown | always | What kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else. |
| url | string | null | always | |
| title | string | null | always | |
| text | string | null | always | The post's text: a caption, a description or the message body. |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| thumbnailUrl | string | null | always | |
| mediaUrls | string[] | always | |
| durationSeconds | number | null | always | |
| viewCount | number | null | always | Views. Null means the platform did not expose a count, which is not the same as zero. |
| likeCount | number | null | always | Likes, or the platform's nearest equivalent. Null means not exposed, not zero. |
| commentCount | number | null | always | Comments. Null means not exposed, not zero. |
| shareCount | number | null | always | Shares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero. |
| hashtags | string[] | always | Hashtags or the platform's own topic tags, without the leading #. |
| mentions | string[] | always | Handles mentioned in the post text, without the leading @. |
| taggedUsers | string[] | may be absent | Usernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none. |
| isSponsored | boolean | null | always | Whether the platform labels the post as an ad, promoted content or a paid partnership. |
| publishedAt | string | null | always | When the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago". |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/page-reels?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/page-reels?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/page-reels",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/post1 creditcacheablebatchableSingle post, video, or reel
One public Facebook post, video or reel by URL, with its text and engagement counts.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Full post, video, or reel URL |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Post.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| type | video | short | image | carousel | text | live | story | reel | audio | album | episode | unknown | always | What kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else. |
| url | string | null | always | |
| title | string | null | always | |
| text | string | null | always | The post's text: a caption, a description or the message body. |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| thumbnailUrl | string | null | always | |
| mediaUrls | string[] | always | |
| durationSeconds | number | null | always | |
| viewCount | number | null | always | Views. Null means the platform did not expose a count, which is not the same as zero. |
| likeCount | number | null | always | Likes, or the platform's nearest equivalent. Null means not exposed, not zero. |
| commentCount | number | null | always | Comments. Null means not exposed, not zero. |
| shareCount | number | null | always | Shares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero. |
| hashtags | string[] | always | Hashtags or the platform's own topic tags, without the leading #. |
| mentions | string[] | always | Handles mentioned in the post text, without the leading @. |
| taggedUsers | string[] | may be absent | Usernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none. |
| isSponsored | boolean | null | always | Whether the platform labels the post as an ad, promoted content or a paid partnership. |
| publishedAt | string | null | always | When the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago". |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/post?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/post?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/post",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/post-comments1 creditcacheablebatchableComments on a post
Top-level comments on a public Facebook post, with author, reaction count and reply count, in Facebook's "Most relevant" order. The first page is the head of the thread Facebook renders into the post, usually two comments; pass pagination.cursor back for the next ten. The post's full comment total is on /v1/facebook/post. Use /v1/facebook/comment-replies for the replies under one comment. likeCount is only as precise as Facebook publishes it: comment reactions ship in abbreviated form ("2.4K") with no exact figure anywhere in the payload, so counts above about a thousand are rounded at source.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Full post, video, or reel URL |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Comment in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| postId | string | null | always | |
| parentId | string | null | always | Id of the comment this one replies to. Null on a top-level comment. |
| text | string | always | |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| authorAvatarUrl | string | null | always | |
| likeCount | number | null | always | |
| replyCount | number | null | always | |
| isPinned | boolean | null | always | |
| isAuthorReply | boolean | null | always | Whether the comment was written by the author of the post. |
| publishedAt | string | null | always | When the comment was posted. Usually an ISO 8601 timestamp; some platforms expose only relative text such as "2 days ago". |
curl "$API/v1/facebook/post-comments?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/post-comments?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/post-comments",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/post-transcript1 creditcacheablebatchableVideo transcript
Transcript for a public Facebook video or reel, as one text block plus timed cues. Reads the caption track Facebook publishes for the video, auto-generated when the uploader added none (source: "captions"). Transcription of videos without captions is coming soon; until then such a video answers not_configured (501) and is not charged.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Full video or reel URL |
| language | string | no | Preferred caption locale, e.g. "en" or "en_US" |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Transcript.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| postId | string | always | |
| url | string | null | always | |
| language | string | null | always | The transcript's language as the platform labels it, usually a language code such as `en`. |
| isAutoGenerated | boolean | null | always | Whether the platform generated the captions automatically, by speech recognition or machine translation, rather than a person writing them. |
| text | string | always | The full transcript as a single block of text. |
| cues | object[] | always | Timed segments of the transcript. |
| cues[].start | number | always | Seconds from the start of the media. |
| cues[].end | number | null | always | Seconds from the start of the media. Null when the platform gives no end time. |
| cues[].text | string | always | |
| durationSeconds | number | null | always | |
| source | captions | asr | null | always | Where the transcript came from. `captions`: the platform's own caption track, whether a person wrote it or the platform generated it (see `isAutoGenerated`). `asr`: produced by speech recognition on the audio. Null when this cannot be told. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/post-transcript?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/post-transcript?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/post-transcript",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/profile1 creditcacheablebatchablePublic Page profile
Name, category, follower and like counts, description, banner and outbound links for a public Facebook Page. followerCount is as precise as Facebook renders it: exact on a small Page ("498 followers"), rounded on a large one ("28M followers", so ±500,000). raw.followerCountIsApproximate says which you got, and raw.likeCount carries the exact like figure Facebook always prints. Pass extra_fetch=true to also fill createdAt, the date the Page was created, which lives only on the Page transparency tab: it costs 1 extra credit and one large additional fetch, refunded if that fetch cannot be read.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Page URL, @handle, slug, or numeric page id |
| extra_fetch | boolean | no | When true, fetches each item's own page to fill fields the list page leaves null. Costs 1 extra credit per page fetched, up to the page size. |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns one Creator.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | The platform's own id for the account, such as a channel id or a numeric user id, always as a string. |
| handle | string | null | always | The account handle without the leading @. Null when the platform has no handles. |
| displayName | string | null | always | |
| bio | string | null | always | |
| avatarUrl | string | null | always | |
| bannerUrl | string | null | always | |
| url | string | null | always | |
| verified | boolean | null | always | Whether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it. |
| followerCount | number | null | always | Followers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it. |
| followingCount | number | null | always | |
| postCount | number | null | always | Posts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published. |
| viewCount | number | null | always | Lifetime views across the account, where the platform exposes a total. |
| likeCount | number | null | may be absent | Total likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it. |
| isPrivate | boolean | null | always | |
| isBusiness | boolean | null | always | Whether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures. |
| category | string | null | always | A label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform. |
| location | string | null | always | Location as the platform shows it: a city, a country, a region code or an address, depending on the platform. |
| externalLinks | string[] | always | Links the account lists on its profile, such as a website or other social accounts. |
| createdAt | string | null | always | When the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile. |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/profile?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/profile?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/profile",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/profile-events1 creditcacheablebatchableEvents on a Page
Events hosted by a public Facebook Page, upcoming ones first, with past events where Facebook still lists them, eight per page; pass pagination.cursor back for the next eight. Each carries start time, place, host and the cover photo.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Page URL, @handle, slug, or numeric page id |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of object in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | "facebook" | always | |
| id | string | always | |
| name | string | null | always | |
| url | string | always | |
| description | string | null | always | |
| startsAt | string | null | always | ISO 8601, UTC. |
| endsAt | string | null | always | ISO 8601, UTC. Null when the event has no end time. |
| timeText | string | null | always | Facebook's own rendering of the time, e.g. "Sat, Sep 5 at 3:00 PM MDT". It carries the event's LOCAL timezone, which the epoch timestamps do not. |
| isOnline | boolean | null | always | |
| isCanceled | boolean | null | always | |
| isPast | boolean | null | always | |
| place | object | null | always | |
| place.id | string | null | always | |
| place.name | string | null | always | |
| place.address | string | null | always | |
| place.latitude | number | null | always | |
| place.longitude | number | null | always | |
| hostId | string | null | always | |
| hostName | string | null | always | |
| hostUrl | string | null | always | |
| thumbnailUrl | string | null | always | |
| ticketPriceText | string | null | always | |
| interestedCount | number | null | always | People who marked the event Interested or Going. In list results above a thousand, Facebook's rounded figure ("1.2K"). |
| fetchedAt | string | always |
curl "$API/v1/facebook/profile-events?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/profile-events?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/profile-events",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
/v1/facebook/profile-photos1 creditcacheablebatchablePhotos on a Page
Photos from a public Facebook Page's photo grid, eight per page, newest first; pass pagination.cursor back for the next eight. Facebook exposes each photo's accessibility caption rather than the text of the post it came from, so that is what lands in title.
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | yes | Page URL, @handle, slug, or numeric page id |
| cursor | string | no | pagination.cursor from a previous response |
Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).
Returns a list of Post in data.items.
Fields
| Field | Type | Present | Description |
|---|---|---|---|
| platform | one of 32 strings | always | |
| id | string | always | |
| type | video | short | image | carousel | text | live | story | reel | audio | album | episode | unknown | always | What kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else. |
| url | string | null | always | |
| title | string | null | always | |
| text | string | null | always | The post's text: a caption, a description or the message body. |
| authorId | string | null | always | |
| authorHandle | string | null | always | |
| authorName | string | null | always | |
| thumbnailUrl | string | null | always | |
| mediaUrls | string[] | always | |
| durationSeconds | number | null | always | |
| viewCount | number | null | always | Views. Null means the platform did not expose a count, which is not the same as zero. |
| likeCount | number | null | always | Likes, or the platform's nearest equivalent. Null means not exposed, not zero. |
| commentCount | number | null | always | Comments. Null means not exposed, not zero. |
| shareCount | number | null | always | Shares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero. |
| hashtags | string[] | always | Hashtags or the platform's own topic tags, without the leading #. |
| mentions | string[] | always | Handles mentioned in the post text, without the leading @. |
| taggedUsers | string[] | may be absent | Usernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none. |
| isSponsored | boolean | null | always | Whether the platform labels the post as an ad, promoted content or a paid partnership. |
| publishedAt | string | null | always | When the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago". |
| fetchedAt | string | always | When this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch. |
curl "$API/v1/facebook/profile-photos?url=8XkPqR2nLvE&cache_max_age=7d" \
-H "x-api-key: $KEY"const query = new URLSearchParams({
url: '8XkPqR2nLvE',
cache_max_age: '7d',
});
const response = await fetch(`${API}/v1/facebook/profile-photos?${query}`, {
headers: { 'x-api-key': KEY },
});
const body = await response.json();
if (!body.success) throw new Error(body.error.code);
// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);Python
import os, httpx
r = httpx.get(
f"{os.environ['API']}/v1/facebook/profile-photos",
params={
"url": "8XkPqR2nLvE",
"cache_max_age": "7d",
},
headers={"x-api-key": os.environ["KEY"]},
timeout=30,
)
body = r.json()
if not body["success"]:
raise RuntimeError(body["error"]["code"])
print(body["data"], body["meta"]["creditsCharged"])Response codes
| 200 | Success |
| 400 | invalid_request. Not charged |
| 401 | missing_api_key / invalid_api_key / revoked_api_key. Never a billing error |
| 402 | insufficient_credits. The key is valid, the balance is not |
| 429 | daily_cap_exceeded or upstream_rate_limited. Not charged |
| 501 | not_configured. This deployment is not set up to serve this endpoint. Not charged. |
| 502 | upstream_blocked / upstream_schema_drift. Not charged |
| 504 | upstream_timeout. Not charged |
Questions
- How much does the Facebook API cost?
- Calls cost 1–2 credits each. Every endpoint is cacheable, and a cache hit costs nothing. A failed request and an empty result are both free, on every endpoint.
- Does the Facebook API need a login or cookies?
- No. Every endpoint reads public, logged-out pages only — no account, no cookies, no session. An API key identifies your own TrueScrape account and nothing else.
- Can I fetch many Facebook targets in one request?
- Yes. 22 of 22 are batchable: one POST to /v1/jobs/batch takes many targets and returns a job id to poll.
- Can I watch Facebook endpoints for changes?
- Yes, 15 of 22. A subscription polls on your schedule and fires your webhook only when the content changed; the rest carry x-subscribable: false in the spec.