Social Media APIs: A Builder's Guide to Publishing Programmatically
Most pages ranking for "social media API" are selling something, and about a third are selling the wrong thing entirely: scraping products that read a profile, pull comments, harvest hashtags. If you searched this term, you probably wanted the opposite, which is to put a post onto a platform from your own code. Those are two product categories with different auth models, different legal exposure, and almost no overlapping endpoints.
This guide is about the publishing side, built bottom-up from platform documentation rather than any vendor's marketing page. All platform numbers below were read on 2026-08-23 from official developer docs, and where a widely cited third-party page contradicts the platform, the platform wins. Two examples repeated across page one of Google right now: Instagram's API publishing limit is documented at 100 posts per 24 hours, not 50, and X has moved off named subscription tiers to per-request consumption pricing.
The question this guide really answers is the one nobody has published an auditable number for: how much engineering time do seven independently breaking platform APIs cost you per month, and which parts of that a unified provider can and cannot absorb.
Read APIs and publishing APIs are different products, so which do you need?
- You want to publish: create posts, schedule them, upload video, reply to comments as the account. You need OAuth from the account owner, platform-granted scopes such as
instagram_content_publishor TikTok'svideo.publish, and in almost every case an app review before anyone outside your own team can use it. This is the path the rest of this guide covers. - You want first-party analytics: impressions, reach, and video views for accounts that have authorized you. Same OAuth, usually a different scope, and the same review gate.
- You want third-party data: competitor posts, public profiles, hashtag firehoses. This is where the scraping vendors live. It usually violates platform terms when done without a licensed access program, and the official routes (Meta Content Library, X academic and enterprise access) are narrow and application-gated.
The practical tell is authorization. If your product needs a user to click "connect account," you are building a publishing integration. If it does not, you are buying scraped data and inheriting whatever that vendor's compliance story is.
What can each platform actually publish, and under what conditions?
- X: single posts, threads, media. OAuth 2.0 with PKCE. Pay-per-usage rather than a subscription tier: post reads $0.005, user reads $0.010, owned reads $0.001, post creation $0.015, and $0.200 for a post containing a URL. The same resource requested twice inside a 24-hour UTC window is billed once, and pay-per-usage plans cap at 3 million post reads per monthly cycle before Enterprise is required (X API pricing, read 2026-08-23). Rate limiting is effectively your budget.
- Instagram: images, video, Reels, carousels, Stories. Facebook Login with
instagram_basic,instagram_content_publishandpages_read_engagement. 100 API-published posts per rolling 24 hours. Two-step container flow. Long-lived tokens last 60 days. App Review plus business verification required (Meta content publishing docs, read 2026-08-23). - Facebook Pages: posts, links, photos, video. Page access token derived from a user token. Rate limit is engagement-derived, not fixed.
- Threads: text, image, video, carousels. 250 posts and 1,000 replies per rolling 24 hours. Scopes
threads_basic,threads_content_publish, andthreads_manage_replies. Container flow, and Meta recommends waiting on average 30 seconds before publishing a container. - LinkedIn: member and organization posts, images, video, documents, articles. Requires
Linkedin-Version: {YYYYMM}andX-Restli-Protocol-Version: 2.0.0headers on every call, plusw_member_socialorw_organization_social(the latter restricted to ADMINISTRATOR, DIRECT_SPONSORED_CONTENT_POSTER or CONTENT_ADMIN page roles). Media uploads separately to obtain a URN (LinkedIn Posts API, read 2026-08-23). - TikTok: video and photo posts via the Content Posting API. Requires the approved
video.publishscope, an audit, and domain or URL-prefix verification before media can be pulled from a URL. Direct Post is capped at 6 requests per minute per user access token. - YouTube: video upload via
videos.insert. 10,000 quota units per day shared across the Data API, withvideos.inserton a separate bucket of 100 calls per day and a 256GB file ceiling (YouTube videos.insert, read 2026-08-23).
There is no shared shape here: different auth, different limit currency, different review process, different media rules. That absence of a shape is the entire cost story.
Why does one post take three API calls on some platforms?

- Direct POST. One request, one live post. X text posts, LinkedIn text posts. Idempotency is your problem: a timeout that actually succeeded will double-post if you naively retry.
- Container and publish. Meta's pattern. You
POST /mediato build a container, thenPOST /media_publishwith that ID ascreation_id. Unpublished containers expire after 24 hours, and carousels are three steps. Your state machine needs a persisted container ID and a resumable second leg, because the two calls can be minutes apart while Meta processes the video. - Chunked upload. TikTok and YouTube. TikTok requires sequential chunks, each at least 5MB and no more than 64MB, except the final chunk which can run to 128MB, maximum 1,000 chunks, a 4GB file ceiling and 10 minutes as the longest video sendable via the initialize endpoint. Sequential means you cannot parallelize to go faster.
A scheduler built only for shape one will work for a week and then quietly fail every video job.
Who is actually allowed to see your first API post?
This is the gate that surprises teams, because the sandbox works fine and then nothing is public.
- TikTok: unaudited API clients can allow up to 5 users to post in a 24-hour window, and can only post in
SELF_ONLYviewership, with the user account required to be private at the time of posting. After the audit you still face a per-creator cap of roughly 15 posts per day and a 24-hour active-creator cap set from the usage estimates in your audit application (TikTok content sharing guidelines, read 2026-08-23). - YouTube: videos uploaded via
videos.insertfrom unverified API projects created after 28 July 2020 are restricted to private viewing until the project passes a Terms of Service compliance audit. - Meta: if your app will be used by anyone without a role on the app, it must go through App Review, and business verification is a separate document-submission process. Meta tests your app directly, and if reviewers cannot access it to test, the entire submission is rejected.
Budget weeks, not days, and budget them before you promise a launch date. A demo account with a screen recording of the exact scope in use is the single highest-leverage artifact in any of these submissions.
Why do tokens break more often than your code does?
Token lifetime is a support cost, not an engineering one, which is why it never makes the estimate.
Instagram is the sharp case. The authorization code is valid for one hour and single-use. The long-lived token lasts 60 days. It can only be refreshed once it is at least 24 hours old, and tokens that have not been refreshed in 60 days expire and can no longer be refreshed (Meta business login docs, read 2026-08-23).
Read that last clause carefully. There is no recovery path. If your refresh job is down for a weekend across a cohort of accounts whose tokens were near expiry, those users must re-authorize by hand. That is not a cron failure, it is a support queue and a churn event. The design implications:
- Refresh at day 30, not day 55. You get 30 days of retry headroom for free.
- Alert on refresh failure rate, not on job completion. A job that runs and refreshes zero tokens looks healthy.
- Store per-connection expiry and surface it in your own UI, so a user sees "reconnect Instagram" before a scheduled post silently fails.
- Treat a scope change as a re-auth. Adding
threads_manage_replieslater means going back to every connected user.
If you are mapping this against a manual workflow first, our walkthrough of how to schedule social media posts on every major platform covers what the native tools do before you automate it.
Why can't one scheduler satisfy all seven rate limits?
Because they are not the same kind of number. There are four incompatible models, and you cannot express them in a single tokens-per-second bucket.

- Fixed request window. TikTok Direct Post allows 6 requests per minute per user access token. Simple, per-credential, predictable.
- Cost-weighted quota. YouTube spends from 10,000 units per day across all Data API calls, with uploads metered separately at 100 per day. Here a read can starve a write.
- Engagement-derived. Meta's Business Use Case limits are a function of your customer's audience: calls within 24 hours equal 4800 multiplied by engaged users for the Pages API, and 4800 multiplied by impressions for the Instagram Platform. Throttling begins when
total_cputimeortotal_timein theX-Business-Use-Case-Usageheader reaches 100 (Meta rate limiting docs, read 2026-08-23). Your ceiling can shrink when a client has a quiet week. - Pay-per-request. X. There is no limit, there is a bill. Your throttle is a spend policy.
The queue design that survives all four: one job queue per platform per credential, never a global one. Each queue carries a pluggable limiter with a single method, reserve(cost), where cost is expressed in that platform's own currency: requests for TikTok, units for YouTube, estimated CPU-time percentage for Meta, dollars for X. Meta's limiter reads the response header after every call and adjusts the ceiling downward rather than assuming a static number. Jobs carry a scheduled time and a deadline, and when a reservation cannot be granted before the deadline, the job fails loudly to the user instead of drifting an hour late.
What does the media pipeline you did not plan to build cost?
You are building an ffmpeg pipeline. Decide that now rather than in week six.
- Instagram images: JPEG only, 8MB maximum, aspect ratio within a 4:5 to 1.91:1 range; extended JPEG formats such as MPO and JPS are not supported. Your users will upload PNG and HEIC constantly.
- Instagram Reels: 300MB maximum, 3 seconds to 15 minutes, aspect ratio between 0.01:1 and 10:1 with 9:16 recommended, HEVC or H264 with progressive scan, closed GOP and 4:2:0 chroma subsampling, 23 to 60 FPS, up to 25Mbps VBR, AAC audio at up to 48khz, and a MOV or MP4 container with the moov atom at the front of the file.
- Threads: images JPEG or PNG at 8MB and up to 10:1 aspect, width 320 to 1440 pixels; video MOV or MP4, 300 seconds and 1GB maximum, 100Mbps maximum bitrate.
- TikTok: MP4 recommended plus WebM and MOV; H.264 recommended plus H.265, VP8, VP9; 23 to 60 FPS; 360 to 4096 pixels per side. Images WebP or JPEG, max 1080p, 20MB each.
That moov-atom requirement alone means ffmpeg -movflags faststart on effectively every video, because most phone and editor exports place the atom at the end. The realistic pipeline is: probe with ffprobe, branch on codec and container, transcode or remux, re-encode audio if the sample rate is wrong, pad or crop to a legal aspect ratio, then verify size against each destination's ceiling before you start a chunked upload you cannot abort cheaply.
What does the same post look like across four platforms?
X first, a single call:
curl -X POST https://api.x.com/2/tweets \
-H "Authorization: Bearer $X_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"We shipped chunked uploads. Notes in the changelog."}'
LinkedIn, one call but with two mandatory headers and a URN-shaped author:
curl -X POST https://api.linkedin.com/rest/posts \
-H "Authorization: Bearer $LI_TOKEN" \
-H "LinkedIn-Version: 202508" \
-H "X-Restli-Protocol-Version: 2.0.0" \
-d '{"author":"urn:li:organization:1234567",
"commentary":"We shipped chunked uploads.",
"visibility":"PUBLIC",
"distribution":{"feedDistribution":"MAIN_FEED"},
"lifecycleState":"PUBLISHED"}'
Instagram, two calls, with a container ID you must persist between them:
CONTAINER=$(curl -s -X POST \
"https://graph.facebook.com/v23.0/$IG_USER_ID/media" \
-d "image_url=https://cdn.example.com/ship.jpg" \
-d "caption=We shipped chunked uploads." \
-d "access_token=$IG_TOKEN" | jq -r .id)
curl -X POST "https://graph.facebook.com/v23.0/$IG_USER_ID/media_publish" \
-d "creation_id=$CONTAINER" -d "access_token=$IG_TOKEN"
TikTok, initialize then upload chunks then poll for status:
curl -X POST https://open.tiktokapis.com/v2/post/publish/video/init/ \
-H "Authorization: Bearer $TT_TOKEN" \
-d '{"post_info":{"title":"We shipped chunked uploads.",
"privacy_level":"SELF_ONLY"},
"source_info":{"source":"FILE_UPLOAD","video_size":41943040,
"chunk_size":10485760,"total_chunk_count":4}}'
Four platforms, four auth headers, four body schemas, one to three round trips, and SELF_ONLY hardcoded on TikTok until your audit clears. Multiply by error handling and you have the integration layer.
Why will your analytics never match the native dashboard?
Because the definitions and the windows differ. Instagram counts a Reel view differently from how the app surfaces plays. Meta backfills late. LinkedIn's organic metrics settle over roughly 48 hours. Timezone boundaries are per-platform, so a "yesterday" total will legitimately disagree by a few percent.
What you can control is your error taxonomy. LinkedIn documents the split cleanly: retryable failures include 429 TOO_MANY_REQUESTS, 409 CONFLICT and 503 SERVICE_UNAVAILABLE, while terminal ones include the 400-class INVALID_URN_TYPE, MISSING_FIELD and FIELD_LENGTH_TOO_LONG, plus 403 ACCESS_DENIED. Retrying a terminal error burns quota and, on X, money. Classify once at the adapter boundary into transient, terminal, and re-auth-required, then let the queue treat those three categories identically across all seven platforms. Our breakdown of what social media analytics tools actually measure goes further into where the numbers legitimately diverge.
What does maintaining seven publishing APIs cost per month?

Initial integration, one time, per platform: 20 to 40 hours for a direct-POST platform such as X or LinkedIn text posts; 60 to 100 hours for a container-flow or chunked-upload platform such as Instagram, TikTok or YouTube, because of media handling and audit paperwork. Seven platforms lands roughly in the 350 to 550 hour range, plus 40 to 80 hours of shared queue, token store and error taxonomy work.
Recurring, monthly:
- Version deprecations: 3 to 6 hours. LinkedIn sunsets Marketing API versions on a rolling schedule, with version 202508 sunset on 2026-08-17. Meta ships Graph API versions continuously. Roughly one forced migration per quarter across the set.
- Token and re-auth support load: 2 to 8 hours, scaling with connected accounts, driven mostly by Instagram's 60-day cliff.
- Media pipeline upkeep: 2 to 5 hours. New codec edge cases, spec changes, ffmpeg upgrades.
- On-call for seven independently breaking APIs: 4 to 10 hours. These outages do not correlate, so the incident count adds rather than overlaps.
That is roughly 11 to 29 engineering hours per month, ongoing, forever. At a fully loaded $120 per hour that is about $1,300 to $3,500 monthly, and at $200 per hour about $2,200 to $5,800. The often-quoted "$10k to $30k per month" figure circulating on vendor pages is unsourced and, on this arithmetic, high unless you are also counting the amortized build.
What a unified API does absorb: the seven adapters, version migrations, media transcoding, the four limiter implementations, and the on-call. What it does not: users still authorize per platform, one connect flow each. App review is still yours if you use your own app credentials. And your analytics still will not reconcile with native dashboards, because that is a definitional problem.
Build direct when: you target one or two platforms, you need a deep platform-specific surface (Shopping tags, YouTube captions, ad-adjacent endpoints) that no aggregator exposes, or data residency rules prevent content passing through a third party. Buy when: breadth matters more than depth, and publishing is a feature of your product rather than the product. Our pricing is where you can check that trade against the hour numbers above.
Why should one publish operation be exposed over REST, CLI, and MCP?
Most vendors treat MCP as a fourth channel bolted onto a REST product. That is the wrong architecture, and the difference shows up in production.
The right model is one publish operation defined once, with a single permission model, exposed through three surfaces. Your product calls REST, your CI job calls the CLI, your AI agent calls MCP, and all three resolve to the same operation: same validation, same approval rules, same idempotency keys, and critically the same rate-limit accounting. If an agent queues six Instagram posts, those six count against the same 100-per-24-hours ledger your dashboard sees.
When MCP is a separate integration path, you get two ledgers, two definitions of "scheduled," and an agent that can quietly exhaust a limit your UI believes is untouched. You also get two permission models, which is how an agent ends up publishing to a client account that was supposed to be approval-gated. OctoSpark's multi-platform publishing is built the other way around: one operation, three surfaces, one accounting.
FAQ
Is there a free social media API?
Partly. LinkedIn, Meta (Facebook, Instagram, Threads), TikTok and YouTube do not charge for API access itself, though all gate it behind app review and quotas. X is the exception: it charges per request, with post creation at $0.015 and a post containing a URL at $0.200. So "free" usually means "no invoice, but you pay in review cycles and quota."
Is Instagram's API free?
Yes, there is no fee for the Instagram Platform API. The costs are indirect: a Meta app, business verification, App Review approval for instagram_content_publish, and a cap of 100 API-published posts per 24-hour rolling period per account. Your effective call ceiling is also engagement-derived at 4800 multiplied by impressions per 24 hours.
Is TikTok an API?
TikTok is a platform that offers several APIs. For publishing you want the Content Posting API with the video.publish scope, which requires an audit before posts are publicly visible. There are also Display and Research APIs for reading data, each with their own application process.
What is a social media API?
An HTTP interface a platform publishes so that authorized applications can act on an account: create posts, upload media, read the account's own metrics, and manage comments. Access is granted by the account owner through OAuth and scoped to specific permissions, with quotas and review processes on top.
How many platforms should a first integration cover?
Two. Ship one direct-POST platform and one container-flow platform, because that combination forces you to build the persisted-state machine and the media pipeline correctly from the start. Adding a third and fourth after that is mostly adapter work. If you want the buy path instead, you can connect accounts and publish without writing any of it, and our comparison of social media management tools covers where each option fits.
