If your product touches social networks (marketing analytics, creator CRM, brand safety, AI research), you have probably watched "fetch public posts" turn into a permanent side project.
A CSS selector moves on Instagram and your ingestion job returns empty arrays. A platform renames a field inside a script tag and your TypeScript types lie for a week before anyone notices. You get paged at 2 a.m. for a parser you wrote six months ago and forgot existed.
We built Social Fetch because that maintenance work belongs in an API layer, not on your product roadmap forever. One REST surface covering 20 platforms. Stable JSON shapes. A requestId on every response so support can trace a call without guessing which worker ran it.
The boring API manifesto
"Exciting" social integrations usually mean headless browsers, proxy rotation, and schema drift you discover in production. What teams actually need is the opposite: field names that stay put, HTTP errors you can map to retries, API keys you rotate from a script, and billing that matches how lookups actually finish.
Product teams should ship features. They should not babysit scrapers. One integration path beats five slightly different hacks, especially when someone asks for a second platform by Friday. If we cannot debug a failed call from a request ID, the API is not finished.
The best social data pipeline is the one your future self does not recognize in
git blame, because it has not needed a fix in two years.
Smoke test before you spend credits
Before you hit a metered route, call GET /v1/whoami. It checks your API key and costs nothing. Same smoke test as the Quickstart.
TypeScript version. Keys go in the x-api-key header (server-side only, not a browser token):
Metered routes bill differently. Credits charge when a lookup completes, including not_found and private outcomes that come back as HTTP 200 with a lookupStatus in the body. Pre-send validation errors, lookup_failed, and 503 temporarily_unavailable do not bill the same way. Reconcile your ledger against meta.creditsCharged, not your request count. Full rules: Credits.
One envelope for success and errors
Successful responses wrap payloads in { data, meta }. meta carries requestId, creditsCharged, and the API version. Errors use the same shape so you always know what to paste into a support ticket.
Log meta.requestId on every call. We learned that the hard way; see The Scrape Job That Never Timed Out. Typed error bodies live in the Errors guide. Per-route credit costs are in the API reference; plan volume on Pricing.
Headers matter
API keys use the sfk_ prefix and travel in the x-api-key header. Details: Quickstart — authentication.
Do not ship keys to clients
Browser bundles and mobile apps are the wrong place for API secrets. Call Social Fetch from your backend, edge worker, or cron job.
When a custom scraper still makes sense
Sometimes a one-off script is the right tool. You need one obscure page, or you are proving something over a weekend. Fine.
Rule of thumb
Narrow, human scope: a custom script is fine. Core product on a schedule across platforms: you want versioning, SLAs, and someone else on pager duty when upstream HTML changes.
Where to go next
Check Pricing before you commit to a ship date. Wire auth and error handling before you parallelize heavy fetches (Quickstart, Errors). Skim route coverage in the API reference before you lock a database schema.
Quickstart Guide
curl examples, required headers, and the whoami smoke test.
Errors & Retries
The error envelope, HTTP codes, and exactly when to retry.
Full API Reference
Paths, query parameters, and generated JSON examples.
API Pricing
Credits, bulk packs, and how to model your volume.
Boring plumbing. Interesting products on top. That is the split we want.