Why social media APIs should be boring

If your product relies on social data, stop building brittle scrapers. Predictable JSON APIs are how you scale social pipelines.

Luke Askew

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.

Request
bash

TypeScript version. Keys go in the x-api-key header (server-side only, not a browser token):

Request
typescript

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.

Boring plumbing. Interesting products on top. That is the split we want.