Skip to main content

socialapis — Python SDK for Facebook + Instagram public data

PyPI Python versions License

The modern alternative to kevinzg/facebook-scraper and arc298/instagram-scraper — real-time Facebook + Instagram data via REST, no OAuth dance, no app review, no scraper maintenance. Powered by hosted infrastructure at socialapis.io.

pip install socialapis-sdk
from socialapis import Facebook, Instagram

fb = Facebook(api_token="...")
page = fb.get_page_info("EngenSA")
print(page.title, page.followers_count, page.category)

ig = Instagram(api_token="...")
profile = ig.get_profile_details("instagram")
print(profile.username, profile.followers_count)

Get a free API token → — 200 calls/month, no credit card

One-line migration

If your code currently uses kevinzg/facebook-scraper or arc298/instagram-scraper, the migration is literally one import line:

# Before — kevinzg/facebook-scraper (abandoned since 2022)
from facebook_scraper import get_page_info, get_posts

# After — socialapis (alias preserves the name)
from socialapis import FacebookScraper

fb = FacebookScraper(api_token="...")
fb.get_page_info("EngenSA")
fb.get_page_posts("EngenSA")

# Same for Instagram
from socialapis import InstagramScraper

ig = InstagramScraper(api_token="...")

FacebookScraper and InstagramScraper are exact aliases of Facebook and Instagram — identical behavior, identical type signatures. They exist purely to keep the import line greppable during migration.


Why this exists

kevinzg/facebook-scraper has 9.5k+ GitHub stars and was the default Python library for scraping Facebook for years. It's been abandoned since 2022. arc298/instagram-scraper (8.5k stars) is in similar shape. Every Meta DOM change breaks them; fixes pile up in unmerged PRs; downloads drift to forks that fix one bug and break two.

This SDK is the drop-in successor:

kevinzg/facebook-scraper (2018-era) socialapis (2026)
Maintenance Abandoned 2022 Active; we run prod for 7M+ calls/mo
Reliability Breaks on every Meta HTML change Hosted backend; we absorb breakage
Type hints None Strict throughout
Async support No Facebook + AsyncFacebook classes
HTTP client requests httpx
Validation Manual dict parsing Pydantic v2 models
Auth None (scrapes anonymously) Single x-api-token header
Pagination Generator with edge-case bugs Cursor-based; API decides page size
Error handling Generic exceptions Typed hierarchy (RateLimitError, etc.)
CI / tests Manual against live FB Recorded HTTP fixtures, Python 3.10–3.13
Coverage Page posts, group posts only 50 endpoints across FB + IG

The trade-off: instead of running a scraper yourself, you make a REST call to our hosted API. 200 calls/month free, no credit card. Paid plans start at $4.99/mo for 1,500 calls.

What's covered (v0.1)

Facebook (Facebook / AsyncFacebook)

Pages

  • get_page_id(page) — resolve a URL/slug to numeric ID
  • get_page_info(page) → PageInfo — page metadata (typed model)
  • get_page_posts(page) — recent posts
  • get_page_reels(page) — short-form videos
  • get_page_videos(page) — long-form videos

Groups

  • get_group_id(group)
  • get_group_details(group) → GroupInfo (typed model)
  • get_group_posts(group)
  • get_group_videos(group_id)

Posts

  • get_post_id(post) — extract numeric ID from URL
  • get_post_details(post) — reactions, media, author
  • get_post_details_extended(post) — + views, video URLs, author verification
  • get_post_comments(post) — pass include_reply_info="true" for reply cursors
  • get_comment_replies(comment_feedback_id, expansion_token)
  • get_post_attachments(post_id)
  • get_video_post_details(video_id)

Search

  • search_pages(query) — supports location_id for geo-filtering
  • search_people(query)
  • search_locations(query) — returns location IDs for use in other endpoints
  • search_posts(query) — supports recency + location filters
  • search_videos(query)

Meta Ads Library

  • get_ads_countries() — supported countries
  • search_ads(query) — by keyword + country + activeStatus
  • get_ads_page_details(page_id)
  • get_ad_archive_details(ad_archive_id, page_id)
  • search_ads_by_keywords(query)

Marketplace

  • search_marketplace(query) — supports lat/lng, price, condition filters
  • get_listing_details(listing_id)
  • get_seller_details(seller_id)
  • get_marketplace_categories()
  • get_city_coordinates(city) — for lat/lng filtering
  • search_vehicles() — bedrooms-style filters; lat/lng required
  • search_rentals()

Media

  • download_media(url) — resolve to direct downloadable URL

Instagram (Instagram / AsyncInstagram)

Profiles

  • get_user_id(profile) — username/URL → numeric user_id
  • get_profile_details(username) → ProfileInfo (typed model)
  • get_profile_posts(username)
  • get_profile_reels(user_id)
  • get_profile_highlights(user_id)
  • get_highlight_details(highlight_id)

Posts

  • get_post_id(post) — extract shortcode from any post URL
  • get_post_details(shortcode)

Reels

  • get_reels_feed() — trending feed
  • get_reels_by_audio(audio_id) — all reels using a specific track

Search + Locations

  • search(keyword) — popular results (users / hashtags / places)
  • get_location_posts(location_id) — top or recent
  • get_nearby_locations(location_id)

Account (Account / AsyncAccount)

Free calls — don't consume credits.

  • get_usage() — credit balance, plan, billing period
  • get_top_ups() — auto top-up settings + history
  • get_limits() — rate limit, concurrent-task cap, allowed packages

Pagination — no limit=N, just cursors

Every endpoint that returns a list lets the API decide page size. To paginate, take the cursor from the response body and pass it back as a kwarg on the next call:

fb = Facebook(api_token="...")

# First page
result = fb.get_page_posts("EngenSA")
posts = result["posts"]
cursor = result.get("next_cursor")  # actual key varies by endpoint — check docs

# Next page
while cursor:
    result = fb.get_page_posts("EngenSA", cursor=cursor)
    posts.extend(result["posts"])
    cursor = result.get("next_cursor")

We deliberately don't impose a uniform limit=N parameter — it would drift from the API's actual semantics. The API's response always tells you whether there's more.

Forward-compat via **kwargs

Every method accepts arbitrary kwargs and forwards them as query params. If the API adds a new filter tomorrow, you can use it today — no SDK release required:

fb.search_ads("fitness", country="US", activeStatus="Active", some_new_filter="x")
# Sends: ?query=fitness&country=US&activeStatus=Active&some_new_filter=x

Error handling

import time
from socialapis import (
    Facebook,
    AuthenticationError,  # 401 — bad token
    InsufficientCreditsError,  # 402 — out of credits
    RateLimitError,  # 429 — slow down
    BadRequestError,  # 4xx — bad input
    APIServerError,  # 5xx — retry safely
    APIConnectionError,  # network — retry with backoff
)

fb = Facebook(api_token="...")
try:
    page = fb.get_page_info("EngenSA")
except RateLimitError as exc:
    time.sleep(exc.retry_after_seconds or 5)
    page = fb.get_page_info("EngenSA")
except InsufficientCreditsError:
    print("Out of credits. Upgrade at https://socialapis.io/pricing")
except AuthenticationError:
    print("Bad token. Get one at https://socialapis.io/auth/signup")

Every typed exception carries .status_code, .request_id, and .body for debugging. The request_id is the same value our backend logs — paste it into a support email and we can find the exact call.

Async

Same method surface; methods are coroutines.

import asyncio
from socialapis import AsyncFacebook


async def main():
    async with AsyncFacebook(api_token="...") as fb:
        pages = await asyncio.gather(
            *[fb.get_page_info(slug) for slug in ["EngenSA", "Microsoft", "GitHub"]]
        )
        for page in pages:
            print(page.title, page.followers_count)


asyncio.run(main())

Pricing

Tier Calls / month Price
Free 200 $0
Pro 1,500 $4.99
Ultra 30,000 $49
Mega 120,000 $179
Enterprise Custom Contact us

One credit per successful response. Failed calls (4xx caused by bad input) don't consume credits.

Other languages

Support

License

MIT — see LICENSE.

Metadata

Release files for socialapis-sdk 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for socialapis-sdk 0.1.2
File Size Uploaded
socialapis_sdk-0.1.2.tar.gz 29.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for socialapis-sdk 0.1.2
File Interpreter ABI Platform
socialapis_sdk-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 55.5 kB

Release files / socialapis_sdk-0.1.2.tar.gz

Download URL socialapis_sdk-0.1.2.tar.gz
Size 29.5 kB
Tags Source
SHA-256 checksum
How to use checksums
78d86c7af2ed051c64da0f42af583dc5f19626222965014a046479c808b11c1a
BLAKE2b-256 checksum
How to use checksums
7a3ba8bbb0c90cde083a20fb14b3eb124df793d34ad78364aee4eb41524be614
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / socialapis_sdk-0.1.2-py3-none-any.whl

Download URL socialapis_sdk-0.1.2-py3-none-any.whl
Size 25.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2677540870518a32648be06ab181c200d8de9edf04cfeac2e21644828717d032
BLAKE2b-256 checksum
How to use checksums
48ce10709c35fa76adbc4d42845160d86af34a09de2a97533d5c2f7185d093aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.3

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page