blog

Instagram API Content Publishing: A TypeScript Guide

How Instagram API content publishing works for professional accounts: Meta's requirements, limits, the container flow, and a TypeScript walkthrough with Social SDK. · updated

Instagram API content publishing lets your app post images, videos, Reels and carousels to Instagram Business and Creator accounts through a two-step flow: create a media container, then publish it. Personal accounts are out of scope. The flow is simple on paper, and most production pain comes from what surrounds it: permissions, public media URLs, rate limits and results that look like success but are not live yet.

This guide separates three things. What Meta requires, what limits you must design around, and what Social SDK, an open-source, MIT-licensed TypeScript toolkit for building social features into an app, actually does for you. The code comes straight from the Social SDK docs.

What the Instagram API content publishing flow actually is

The Instagram API content publishing flow is a two-step process that works only on professional accounts, meaning Business or Creator accounts. You first create a media container, then publish that container. Meta's documentation describes publishing single images, videos, Reels and carousel posts this way.

The two endpoints do different jobs. The media endpoint creates a container and tells Instagram where to fetch your media. The media_publish endpoint turns that container into a post. Every publish is at least two API calls.

That split matters for design. A container is a pending object, not a post. Between the two calls Instagram may still be fetching and processing your media, and that gap is where the honest-outcome problem later in this guide comes from.

Meta's requirements before you write code

Before any code runs, you need a professional account, the right permissions, publicly hosted media and, in some cases, Page Publishing Authorization. These are Meta's rules, not an SDK's, and no library removes them.

Account type. Publishing works against Instagram Business or Creator accounts. A personal account cannot be published to through this API.

Permissions. Under Meta's Instagram API with Instagram Login, publishing is gated by an app-review-approved permission, instagram_business_content_publish. Meta expects a working demonstration of the full connect-and-publish flow, typically a screencast, before it grants the permission to your app.

Public media URLs. Meta fetches your media with cURL at the time of the attempt, so the file must sit on a publicly accessible server. A signed URL that expires in a minute or a localhost path will fail.

Page Publishing Authorization. If the professional account is connected to a Page that requires PPA, you cannot publish until PPA is completed.

If you serve businesses and creators, build your onboarding around these four checks. Most failed first publishes trace back to one of them.

Platform limits to design around

Three limits shape any Instagram publishing queue: supported media, a rolling rate limit, and container expiry.

Supported media. Meta's docs state that JPEG is the only supported image format. Convert PNGs and WebP files before they reach the API instead of finding out at publish time.

Rate limit. An Instagram account is limited to 100 API-published posts within a 24-hour moving period. It is a moving window, not a midnight reset. Meta exposes a content_publishing_limit field you can check before publishing, so a scheduler can defer posts instead of burning failed calls.

Container expiry and status. A container that is not published within 24 hours expires, which changes how you design queues: create containers close to publish time, not days ahead. Video containers are not immediately publishable because Meta transcodes first. Poll the container's status_code until it reports a ready state before calling publish.

The practical rule: treat container creation as the start of a short-lived job, not a row you can park.

Publishing from TypeScript with Social SDK

Social SDK is an open-source, MIT-licensed TypeScript toolkit that gives your app one typed interface for publishing, reading, analytics and comments across X, Threads, Bluesky, YouTube, TikTok, Instagram and LinkedIn. It is an SDK you install, not a hosted API.

The package is @opencoredev/social-sdk. Install it from npm, then configure the Instagram integration and publish. Use the exact install command, imports and image example from the Social SDK docs, which cover the Publish content capability and the API overview. The shape of the flow is:

  1. Install @opencoredev/social-sdk.

  2. Configure the Instagram integration with credentials you control.

  3. Publish an image post using a publicly reachable media URL.

  4. Read the result before you tell your user anything.

Social SDK's direct integration route fits when you want to call a platform with credentials you control. Teams that prefer not to handle tokens can route through a managed backend instead: Zernio, Post for Me, PostFast and Postiz are supported.

Copy the code from the docs rather than from a blog post, including this one. The docs are where the current signatures live.

Reading the result honestly: processing is not published

A successful call to a publish endpoint is not the same as a live post, and your code should say so. Because Instagram works through containers and media processing, a request can be accepted while the post is still processing. Reporting that as published is how apps end up telling users their post is live when it isn't.

Social SDK returns a real, per-platform outcome on every call, not a blanket success. Handle that outcome explicitly:

  • Published: tell the user it is live.

  • Processing: show a pending state and check again later.

  • Failed: surface the platform's reason, such as an unfetchable media URL or an unsupported format.

The failure mode to avoid is subtle. Bundle Social notes that media_publish can succeed on Meta's side and still return a 500 to you, for example after a timeout. If you blindly retry, you can double-post. Record the outcome you received, and verify state before retrying a publish.

Never map "request returned" to "post is live." Map the reported outcome to your UI, and let processing stay visibly unfinished.

Platform requirements vs SDK capabilities: who owns what

Meta's requirements stay your responsibility. Social SDK gives you a typed way to publish and read outcomes, and it does not replace the setup Meta demands.

Concern Owner Notes
Business or Creator account Meta rule, your onboarding Personal accounts cannot publish
App review and publishing permission You Meta reviews your app and demo
Access tokens and refresh You, or a managed backend Direct route uses credentials you control; Zernio, Post for Me, PostFast and Postiz exist for teams avoiding token handling
Public media hosting You Meta must be able to fetch the URL
JPEG conversion, 100-post window You Design your queue around them
Typed publish call and per-platform outcome Social SDK Typed publish call with an honest result
Adding other platforms later Social SDK Same interface across seven platforms

Read that table as a scoping tool. If someone promises a library that removes app review or hosts your media, be skeptical. What an SDK should remove is the glue code and the guesswork about what happened.

Where Social SDK fits: direct integration vs managed backends

Choose direct integration when you want to own credentials and the full flow. Choose a managed backend when token handling is the part you want to hand off. Social SDK supports both, which is the point of putting a typed interface in front of the choice.

Raw Graph API calls give you maximum control and maximum glue code: container creation, status polling, error mapping and a separate integration per platform. A standalone Instagram wrapper solves Instagram once, then you repeat the work for LinkedIn or Bluesky.

Social SDK trades that repetition for one interface. You write the Instagram publish today, and when a customer asks for Threads, YouTube or TikTok, you extend the same code path instead of starting another integration. It is MIT licensed and on npm now, so evaluating it costs an install, not a contract.

If your product only ever posts to Instagram and you want to live in Meta's raw endpoints, direct Graph API calls are a fair choice. If you expect a second platform within a year, a shared typed interface pays for itself early.

Start with one Instagram publish and read its real outcome

Instagram publishing fails at the edges: account type, permissions, public URLs and results that mean less than they claim. Fix those in your own onboarding, then let the code report truthfully. Install @opencoredev/social-sdk, copy the Instagram image example from the Social SDK docs, run one publish against a test professional account, and branch your UI on the returned outcome, with processing treated as unfinished.

Frequently asked questions

Which Instagram accounts can use the content publishing API?
Only professional accounts, meaning Instagram Business or Creator accounts, can be published to through the API. Personal accounts cannot. Your app also needs Meta's approved publishing permission. Social SDK publishes to Instagram from TypeScript, but account type and app review remain Meta requirements you handle in your own onboarding.
What is the Instagram API rate limit for publishing?
Instagram accounts are subject to daily publishing limits, per Meta's content publishing documentation. You can check the content_publishing_limit field before publishing to avoid failed calls. Build your scheduler to defer posts near the limit, whichever library you use, including Social SDK.
Why does my Instagram post say processing instead of published?
Instagram publishes through containers, and media may still be processing after a request is accepted, especially video. Treat processing as unfinished, not live. Social SDK returns a real per-platform outcome on each call, so your app can show a pending state and check again instead of claiming success.
Do I need to host my own media to publish to Instagram?
Yes. Meta fetches media with cURL at the time of the publish attempt, so files must sit on a publicly accessible server. Images must be JPEG. Social SDK does not host media for you, so upload to storage with a stable public URL before publishing.
What are the best content publishing tools for Instagram developers?
Developers usually choose between raw Graph API calls, single-platform wrappers and multi-platform toolkits. Social SDK is an open-source, MIT-licensed TypeScript toolkit covering Instagram plus X, Threads, Bluesky, YouTube, TikTok and LinkedIn, with direct integration or managed backends like Zernio, Post for Me, PostFast and Postiz.

Sources