Facebook Data API: The Complete 2026 Developer Guide
Complete guide to the Facebook Data API in 2026: what Graph API still provides, unified API alternatives, Python and curl examples, rate limit handling.

Facebook Data API in 2026: What Works When Graph API Won't
In 2026, the Facebook Data API landscape is split between Meta's official Graph API (which requires App Review and carries strict rate limits) and third-party unified APIs that offer immediate programmatic access via a single key. This guide covers both paths in full.
Graph API v18.0 expired January 26, 2026. v19.0 expired May 21, 2026. The metadata=1 parameter (the introspection shortcut developers used to discover available fields on any node) was removed across every Graph API version on May 19, 2026. If you built a Facebook integration before 2025 and haven't touched it since, there's a reasonable chance it's already broken.
This guide maps every working path to Facebook data in 2026: what the official Graph API still gives you, what's behind a hard wall, and how to pull page posts, follower counts, and engagement metrics via a single API key with no app review. Examples are in curl and Python. We'll use the SocialCrawl API for the production path and the official Graph API for context on what it still covers.
What Does the Facebook Graph API Actually Give You in 2026?
The Graph API is Meta's official programmatic interface to Facebook data, operating over HTTPS at graph.facebook.com. It uses a node/edge/field model: nodes are objects (Pages, Posts, Users, Photos), edges are connections between them, and fields are properties on those objects.
Current version: v25.0, released February 18, 2026. Available versions run from v20.0 through v25.0 (see Meta changelog). v18.0 and v19.0 are expired: any code still pointing at those versions returns errors today.
What's accessible with the right permissions:
- Page posts and feed via
/page/feed,/page-post, and/page-post/comments, requiring the Page Public Content Access feature, which itself requires App Review - Page business metadata: name, category, location, contact details
- Reactions, comment counts, and share counts via Page Public Content Access
- Ads and Marketing data for ad accounts you own, via the Marketing API
- Webhooks for real-time notifications (new comments, reactions on Page posts)
What's officially off-limits:
- Personal user profiles and private content (user data is strictly app-scoped and requires explicit OAuth consent from each user)
- Group posts and membership
- Friend lists and social graphs between users, closed since 2015
- Audience demographics beyond what the Page itself owns, removed after 2018
- Private messages, available only through the Messenger Platform for page-initiated conversations
The App Review bottleneck
Every Page-related permission requires App Review before a live app can access real data. During development mode, your app can only access Pages where the same person holds both the Page admin role and an app developer or tester role. You cannot test against arbitrary public pages without clearing App Review first.
Page Public Content Access specifically requires:
- Completed App Review
- Business verification, with possible additional contracts
- A system user access token (recommended to avoid rate limit collisions on shared tokens)
Rate limits that scale against a user base you don't have yet
The platform rate limit for app tokens is 200 × Number of Daily Active Users calls per rolling hour. A new app with no users gets zero meaningful headroom. The Pages API rate limit is 4,800 × Number of Engaged Users per 24-hour window. For a new integration, this math is brutal.
The specific throttle error codes to know: 4 (app limit reached), 32 (Pages API limit), 80001 (Pages API with page or system user token). Rate limit usage is exposed via the X-App-Usage response header, returning three percentages: call_count, total_cputime, and total_time.
One more live deprecation: In v25.0, metadata=1 was deprecated. As of May 19, 2026, it was removed for all Graph API versions, not just v25.0. This parameter was a common debugging shortcut for field discovery. It no longer exists. Use the Graph API Explorer or the reference documentation instead.
The honest picture: Graph API is the compliant official path if you qualify. But qualification takes weeks, and rate limits scale against a user base most new integrations don't have.
For teams that need data now, a third-party unified API is the practical alternative to Facebook Graph API: no App Review, no rate limit math tied to an unknown user base, and immediate x-api-key access from the first request.
How Do You Scrape or Access Facebook Data in 2026? Five Methods Compared
Finding a reliable path to Facebook data is harder than it looks. Here are the five methods that actually work in 2026, with honest trade-offs on each.
| Method | Entry cost | Data freshness | App Review required? | Multi-platform? |
|---|---|---|---|---|
| Official Graph API | Free | Real-time | Yes | Facebook only |
| Apify Facebook actors | $29/mo | Near real-time | No | Facebook family |
| Bright Data datasets | $250 minimum | Batch (pre-collected) | No | No (bulk only) |
| RapidAPI scrapers | Not published | Near real-time | No | Single-purpose |
| Unified API (one key) | Credit-based | Near real-time | No | 42 platforms |
Official Graph API is the right path if you qualify. Data freshness is excellent, the authentication model is stable, and Meta is the canonical source. The cost is the weeks-long App Review process and rate limits that start at zero.
Apify runs browser automation against Facebook's public pages. Their Facebook Posts Scraper has 82,000 total users and 8,700 monthly active users. The demand is clearly real. The structural limitation: every time Facebook changes its page layout, selectors break. Budget for ongoing maintenance, not a one-time setup.
Bright Data offers 10 distinct Facebook dataset types with over 1.4 billion records, starting at $0.0025 per record. The key constraint: this is a bulk dataset product, not a per-request API. If you need to query a specific page's current follower count right now, Bright Data is the wrong tool.
RapidAPI hosts multiple community-maintained Facebook scrapers. Pricing was not published on the marketplace hub page at time of writing; check individual vendor listings before budgeting.
A unified schema across platforms is the fifth option, covered in the next steps below.
One note on the legal angle: the Ninth Circuit's 2022 ruling in hiQ v. LinkedIn held that scraping publicly accessible data likely does not violate the CFAA. Facebook's data is largely login-gated, which distinguishes it from the fully public LinkedIn profiles in hiQ, so the legal picture for Facebook specifically is less settled. The lower-risk routes are the official API and unified APIs with published Terms of Service. This is not legal advice. The full picture is in the FAQ below.
Facebook Scraper API Pricing: What 1,000 Page Profiles Actually Cost
Pricing across Facebook data tools is poorly documented by design. Here's what the published numbers show:
| Tool | Entry price | Cost per 1,000 pages | Minimum spend | Per-request? |
|---|---|---|---|---|
| Apify (Starter) | $29/mo | ~$5–8 all-in | $29/mo | Yes |
| Bright Data | $0.0025/record | $2.50 | $250 | No (bulk only) |
| RapidAPI | Not published | Not published | Not published | Varies |
| SocialCrawl | Credit-based | See pricing | None | Yes |
One note on Apify's numbers: the actor page shows a base rate, but total platform cost (compute included) runs $5–8/1,000 pages all-in per their own FAQ. Budget against the higher figure.
Bright Data's $250 minimum makes it impractical for per-request lookups. If you need one page's current data, you're paying $250 for 100,000 records and using one. For bulk collection at scale (sentiment analysis across thousands of brand pages), the per-record math becomes genuinely competitive.
For a broader cost breakdown across social platforms, see our full comparison of social media scraping APIs.
Prerequisites
Before the first curl command, you need:
- A SocialCrawl API key: sign up at socialcrawl.dev. No App Review, no OAuth negotiation with Meta. Your key is in the dashboard immediately after signup.
- curl (any version) OR Python 3.8+ with the
requestslibrary (pip install requests) - For the Graph API comparison sections: a Meta developer account with an app in development mode (optional, only needed if you're following the official path)
- No Facebook Business Manager account required for the unified API path
Step 1: Get a Facebook Page's Followers, Posts, and Engagement
The SocialCrawl Facebook page data API follows the same pattern as every endpoint in the series: GET /v1/{platform}/{resource} with your key in the x-api-key header. For a Facebook page profile:
curl:
curl "https://www.socialcrawl.dev/v1/facebook/profile?url=https://www.facebook.com/NASA" \
-H "x-api-key: YOUR_API_KEY"
Python:
import os
import requests
API_KEY = os.environ["SOCIALCRAWL_API_KEY"]
BASE_URL = "https://www.socialcrawl.dev"
HEADERS = {"x-api-key": API_KEY}
response = requests.get(
f"{BASE_URL}/v1/facebook/profile",
headers=HEADERS,
params={"url": "https://www.facebook.com/NASA"}
)
page = response.json()
data = page["data"]
print(f"Page: {data['name']}")
print(f"Category: {data['category']}")
print(f"Followers: {data['followers_count']:,}")
print(f"Likes: {data['likes_count']:,}")
# engagement_rate is computed, not a raw field the Graph API returns
print(f"Engagement rate: {data['engagement_rate']}%")
# content_category classifies the page's content type from post history
print(f"Content category: {data['content_category']}")
Two fields worth noting explicitly:
engagement_rateis computed from raw counts: the Graph API returns individual like, comment, and share counts and leaves the rate calculation to you. It's pre-calculated in this response.content_categoryis a broader content-type classification computed from the page's post history. The Graph API has acategoryfield for business type (e.g., "Science Website"), but this is different: it classifies what the page actually publishes.
The x-api-key header replaces the Graph API's OAuth flow entirely. No token expiry to manage, no scope negotiation, no refresh dance.
Step 2: Pull Posts and Comments at Scale with Cursor Pagination
Fetching one page profile is a warmup. The real pattern for extracting Facebook data at scale is pulling hundreds of posts, for content monitoring, competitor analysis, or sentiment tracking. The API uses cursor-based pagination: each response includes a next_cursor value you pass back on the next request.
import os
import time
import requests
API_KEY = os.environ["SOCIALCRAWL_API_KEY"]
BASE_URL = "https://www.socialcrawl.dev"
HEADERS = {"x-api-key": API_KEY}
def fetch_all_posts(page_username: str, max_pages: int = 10) -> list[dict]:
"""Fetch posts from a Facebook page using cursor pagination."""
all_posts = []
cursor = None
page_num = 0
while page_num < max_pages:
params = {"url": f"https://www.facebook.com/{page_username}", "limit": 25}
if cursor:
# Pass the cursor from the previous response to get the next page
params["cursor"] = cursor
response = requests.get(
f"{BASE_URL}/v1/facebook/profile/posts",
headers=HEADERS,
params=params
)
result = response.json()
posts = result.get("data", {}).get("items", [])
all_posts.extend(posts)
# next_cursor is None when you've reached the end of available data
cursor = result.get("data", {}).get("next_cursor")
if not cursor:
break
page_num += 1
# Rate-conscious pause between pages: keeps the pattern from
# looking like a burst. Actual retry logic is in Step 3.
time.sleep(0.5)
return all_posts
posts = fetch_all_posts("nasa", max_pages=5)
print(f"Fetched {len(posts)} posts")
The limit parameter controls items per page; 25 is a reasonable default. The cursor parameter accepts the next_cursor value from the previous response. When next_cursor is None or absent, you've reached the end of available data.
The time.sleep(0.5) is not rate limit handling; it's a basic courtesy pause between cursor pages. Full exponential backoff lives in Step 3.
Step 3: How Do You Handle Rate Limits Without Breaking Your Pipeline?
Graph API throttle errors arrive as specific error codes: 4 (app limit), 32 (Pages API limit), 80001 (Pages API with page or system user token). The X-App-Usage response header shows you call_count, total_cputime, and total_time as percentages; preemptive throttling when any of those approaches 100% is smarter than reactive backoff after an error.
For the credit-based path: credit deduction is transparent per request in the response envelope. No opaque sliding window math: check your credit balance before a large pull, not after.
This pattern handles both: retries on 429 with exponential backoff, logs X-App-Usage for Graph API monitoring, and hard-stops on client errors rather than retrying indefinitely:
import os
import time
import random
import requests
API_KEY = os.environ["SOCIALCRAWL_API_KEY"]
BASE_URL = "https://www.socialcrawl.dev"
HEADERS = {"x-api-key": API_KEY}
def fetch_with_retry(
url: str,
params: dict,
max_retries: int = 5
) -> dict | None:
"""Fetch with exponential backoff on rate limits."""
for attempt in range(max_retries):
response = requests.get(url, headers=HEADERS, params=params)
# Log X-App-Usage when present: Graph API pass-through header
usage = response.headers.get("X-App-Usage")
if usage:
print(f"Graph API usage: {usage}")
if response.status_code == 200:
return response.json()
if response.status_code == 429:
# Jitter prevents thundering herd when multiple workers
# hit the limit at exactly the same moment
wait = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limited. Waiting {wait:.1f}s (attempt {attempt + 1}/{max_retries})")
time.sleep(wait)
continue
# 4xx other than 429 are caller errors, don't retry
if 400 <= response.status_code < 500:
print(f"Client error {response.status_code}: {response.text[:200]}")
return None
# 5xx: transient server error, retry with backoff
wait = (2 ** attempt) + random.uniform(0, 1)
print(f"Server error {response.status_code}. Waiting {wait:.1f}s")
time.sleep(wait)
print(f"Exhausted {max_retries} retries")
return None
The key distinction: 429 is a rate limit, so back off and retry. A Graph API error code 80001 means the Pages API throttle was hit with a page or system user token; the same exponential backoff applies. Any 4xx other than 429 is a caller error (wrong endpoint, missing field, expired version) and should not be retried automatically.
What Could Go Wrong?
These are the specific failure modes, each with a one-line diagnosis.
Empty data array returned
For Graph API: Page Public Content Access is not yet approved. Check your app's Feature Review status in the Meta developer dashboard. For the unified API path: verify the endpoint matches the resource type you're targeting (page vs. posts vs. comments).
401 / invalid token
For the x-api-key path: your key is missing from the header or was regenerated in the dashboard. Copy the current key and retry. For Graph API: your access token expired. Graph API tokens from the three-legged OAuth flow have finite lifespans and require proactive renewal.
Requests failing silently after May 19, 2026
You were relying on metadata=1 for field discovery. It was removed across every Graph API version on that date. Switch to the Graph API Explorer or the field reference for discovery.
400 errors on v18 or v19 endpoint calls Both versions expired in 2026 (v18.0 on January 26, v19.0 on May 21). Update your base URL to v22.0 or higher. v25.0 is current as of February 2026.
Rate limit error code 80001
Pages API throttle on a page or system user token. Implement exponential backoff: the pattern in Step 3 handles this. If you're hitting it repeatedly, add X-App-Usage logging to catch the approach before the wall.
What's Next? Extend to Instagram, LinkedIn, and Beyond
If you're querying Facebook pages, you're probably querying Instagram too. The Instagram data guide covers the same pattern (Reels, Stories, and profile data) under the same key. No separate app review per platform.
The unified social media API complete guide covers the architecture decision in full: when a unified layer makes sense over platform-specific integrations, and how schema normalization works across 42 platforms under one API key.
For the rest of the series: the LinkedIn Data API guide covers the restricted official API and what's available via third-party paths; the X/Twitter API guide covers the tiered pricing shift and what each tier actually returns; the YouTube Data API guide covers quota math and the endpoints that cost the most; and the Reddit Data API guide covers programmatic access to posts, comments, and subreddit data after the 2023 API access changes.
The visual explorer lets you see a Facebook page's full response before you write a single line of code. The Explorer is the fastest way to confirm which fields are available for your use case.
Frequently Asked Questions
What data can I get from the Facebook Data API?
Via the official Graph API with Page Public Content Access approved: public page posts, comments, reactions (with breakdown by type: like, love, haha, wow, care), follower count, page category, engagement metrics, media URLs, and post timestamps. Officially off-limits: personal user profiles, group content, friend graphs (closed since 2015), and audience demographics beyond what the page owns (removed after 2018).
Via a unified social data API: page profile data including follower count, category, and post history; individual posts with engagement counts; and comment threads. Computed fields (engagement_rate and content_category) are pre-calculated in the response rather than left as raw counts to aggregate yourself.
How do I get a Facebook Data API key?
Official Graph API path: Create a Meta developer account → create an app at developers.facebook.com → request Page Public Content Access → complete App Review → complete Business Verification → generate a system user access token. This process typically takes several weeks. Apps in development mode can only access Pages where the same person holds both the Page admin role and a developer or tester role on the app.
Alternative path: Sign up at socialcrawl.dev → your API key appears in the dashboard immediately. No App Review, no Business Verification, no OAuth dance. Pass the key in the x-api-key header. That's the entire authentication model.
Is scraping Facebook data legal?
The Ninth Circuit's 2022 ruling in hiQ v. LinkedIn held that scraping publicly accessible data likely does not violate the Computer Fraud and Abuse Act. However, most Facebook data sits behind a login wall, which distinguishes it from the fully public LinkedIn profiles at issue in hiQ and leaves the legal picture for Facebook specifically less settled.
Meta's Platform Terms require App Review and explicitly prohibit unauthorized automated data collection. GDPR applies to any collection of data from EU users regardless of technical method. The lower-risk routes are the official Graph API (if you qualify) and unified APIs with published Terms of Service. This is not legal advice. Consult qualified counsel for your specific situation.
Why does Facebook API return empty data?
Four common causes, each with a one-line diagnosis:
- Insufficient permissions: Page Public Content Access not yet approved. Check your app's Feature Review status in the Meta developer dashboard.
- Deprecated version: v18.0 and v19.0 calls return
400errors. Update your base URL to v22.0 or higher. - Rate limit hit: check the
X-App-Usageheader. Ifcall_countis at or near 100%, you're throttled. Wait for the rolling window to reset and implement backoff (see Step 3). - Field access tier: some fields require a higher-tier app review than what you've completed. Check the specific permission requirements in Meta's Features Reference.
What's the best Facebook scraper API in 2026?
It depends on the use case:
- Apify ($29/mo Starter, ~$5–8/1,000 pages all-in) suits one-off Facebook jobs or developer exploration, with solid community coverage, browser automation, and no minimum order.
- Bright Data ($0.0025/record, $250 minimum) works for bulk pre-collected datasets at scale: sentiment analysis across thousands of pages, academic research, large-scale brand monitoring. Not a per-request API.
- A unified social data API is the right fit when you need Facebook alongside Instagram, LinkedIn, X, or YouTube under one key: consistent schema, credit-based pricing, no minimum order, no separate auth per platform.
Match the tool to the use case. There's no single best answer across all scenarios.
How do I handle Facebook API rate limits in production?
For the official Graph API: Monitor the X-App-Usage response header before you hit the wall: call_count, total_cputime, and total_time are returned as percentages. When any approaches 100%, pause proactively. Implement exponential backoff with jitter on error codes 4, 32, and 80001. For Pages API at scale, a system user access token is recommended over a standard page access token.
For the credit-based path: Credit deduction is transparent per request in the response envelope. Check your credit balance before a large pull. The Step 3 pattern above handles 429 responses with exponential backoff if you encounter a temporary rate limit on the upstream fetch.
Related posts

The Reddit API in 2026: Pricing, Rate Limits & What Still Works
The Reddit API is free at 100 QPM, but commercial use needs a $0.24/1K contract. Pricing, rate limits, Pushshift's replacement, and what still works in 2026.

The X (Twitter) API in 2026: Pricing, Rate Limits & What Still Works
X killed its free API and now bills per request — credits, not tiers. The 2026 X (Twitter) API pricing, rate limits, what changed, and cheaper alternatives.

LinkedIn API in 2026: A Developer's Reality Check
The LinkedIn API gives you three scopes. If you need more — lead enrichment, recruiting data, company intel — here's exactly what your options are in 2026.
