Instagram API · post · schedule · analyze

The Instagram API, explained - and made one call

Everything the Instagram Graph API asks of you: access prerequisites, the create-container → poll → publish flow, the 50-post daily ceiling, the error codes and the 60-day tokens. Then the shortcut - one POST that publishes Reels, carousels, Stories and photos for you.

ReelsCarouselsStoriesSchedulingAnalytics

5 minutes to first post ✓ 99.92% uptime ✓ Reels, carousels & Stories

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "New drop is live 🔥 #launch",
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/reel.mp4", "filename": "reel.mp4" }]
  }'

A video publishes as a Reel automatically. One image → a feed photo. Two-to-ten → a carousel.

Instagram's official API is powerful - and painful

Instagram has no simple "post" endpoint. Publishing through the Instagram Graph API means a Business or Creator account, Meta App Review, a two-step create-container → poll → publish flow, publicly-hosted media URLs and tokens that quietly expire. Outstand turns all of it into a single request.

Business/Creator account, Facebook Page link and Meta App Review
Connect once via OAuth - we manage the app and permissions, or bring your own
Create a media container, poll its status, then publish - per item
One POST /v1/posts/ - we create, poll and publish the container for you
Media must be a public HTTPS URL you host yourself
Pass a URL; we fetch it and hand it to Instagram correctly per media type
60-day long-lived tokens that expire silently
Automatic token refresh - you never see a 401
Carousels need N child containers assembled in order
Send 2–10 media items in one array; we assemble the carousel
Undocumented rate limits and 429s
We queue, throttle and retry - you never see a 429

Instagram Graph API reference

What the official API actually requires, in the order you hit it. Written against the endpoints our own integration calls in production (Graph API v24.0 at the time of writing) - Meta moves fast, so check their changelog before you rely on a version.

Two routes into the same API

Instagram API with Instagram Login

graph.instagram.com

Instagram Professional accounts that log in with Instagram directly. This is the route Outstand uses.

instagram_business_basic, instagram_business_content_publish, instagram_business_manage_comments, instagram_business_manage_insights

Instagram API with Facebook Login

graph.facebook.com

Apps that already sit on the Meta Business stack and need Page-level access alongside Instagram.

instagram_basic, instagram_content_publish, pages_show_list, pages_read_engagement, business_management

Prerequisites before your first post

An Instagram Professional account - Business or Creator. Personal accounts cannot publish through any Instagram API.
A linked Facebook Page. Required for the Facebook Login route; Meta still expects a Page relationship for most business features.
A Meta app in the Meta Developer dashboard, with the Instagram product added and a valid OAuth redirect URI.
App Review for the publishing permissions. Development-mode apps can only act on accounts with a role on the app.
Business Verification for the Meta business that owns the app before advanced access is granted.
Publicly reachable HTTPS media. Meta downloads your image or video from a URL you host - there is no multipart post endpoint.

The content publishing flow

There is no single "post to Instagram" endpoint. Publishing is always two calls with a wait in between, and carousels multiply that by the number of items.

1. Create a media container

POST /{ig-user-id}/media with image_url or video_url, the caption, and media_type=REELS for video. Returns a creation ID.

2. Poll the container

GET /{container-id}?fields=status_code until it reports FINISHED. ERROR and EXPIRED are terminal - large videos can transcode for ten minutes or more.

3. Publish it

POST /{ig-user-id}/media_publish with creation_id set to the container. Only then does the post exist on Instagram.

Carousels

Create one child container per item with is_carousel_item=true, then a parent container with media_type=CAROUSEL and the children array, then publish the parent. Meta documents a maximum of 10 items.

Reels

media_type=REELS. You can set cover_url or thumb_offset (not both - Meta ignores thumb_offset when cover_url is present) and invite up to 3 collaborators.

Stories

media_type=STORIES with a single image or video, no caption and no carousel. In our own integration Meta rejects Stories for Creator accounts - Business only.

bash
# 1. Create the container
curl -X POST "https://graph.instagram.com/v24.0/{ig-user-id}/media" \
  -d "media_type=REELS" \
  -d "video_url=https://yourcdn.com/launch.mp4" \
  -d "caption=Our Q2 launch is live" \
  -d "access_token=$IG_LONG_LIVED_TOKEN"
# → { "id": "17..." }

# 2. Poll until the container finishes transcoding
curl "https://graph.instagram.com/v24.0/17...?fields=status_code&access_token=$IG_LONG_LIVED_TOKEN"
# → IN_PROGRESS … FINISHED | ERROR | EXPIRED

# 3. Publish it
curl -X POST "https://graph.instagram.com/v24.0/{ig-user-id}/media_publish" \
  -d "creation_id=17..." \
  -d "access_token=$IG_LONG_LIVED_TOKEN"

# Check what is left of today's 50-post allowance
curl "https://graph.instagram.com/v24.0/{ig-user-id}/content_publishing_limit?access_token=$IG_LONG_LIVED_TOKEN"

Large videos can stay IN_PROGRESS for ten minutes or more, so poll with backoff rather than a fixed sleep. Meta also offers a resumable upload endpoint for reels when you would rather push bytes than host a public URL.

Instagram API rate limits

Content Publishing Limit
50 published posts per rolling 24 hours, per Instagram account
Carousels count as one post. Check remaining quota with GET /{ig-user-id}/content_publishing_limit before you queue.
Platform rate limiting
Per app, not per account (Business Use Case rate limits)
Meta meters calls against your app across every account it serves, so one noisy tenant can throttle all of them.
Container lifetime
Meta documents container expiry at 24 hours
A container you never publish expires and comes back as EXPIRED on the status poll - you have to rebuild it.
Long-lived token
60 days, refreshable
Short-lived tokens exchange for a 60-day token; refreshing requires a token at least 24 hours old and not yet expired.

Common Instagram API error codes

190
Invalid or expired access token
The long-lived token lapsed or the user revoked access. Re-run OAuth, and refresh tokens before day 60 rather than after.
4 / 613
Application request limit reached / rate limit hit
Back off exponentially. These are app-level, so throttle across all your tenants, not just the one that tripped it.
100
Invalid parameter
The catch-all. Usually an unreachable media URL, a bad field name, or a media object that no longer exists (expired Stories return this).
200 / 10
Permission denied
The permission was never approved in App Review, or the user did not grant it. Re-check the scopes on the token.
9007
Media not ready to publish
You called media_publish before the container reached FINISHED. Poll status_code first instead of sleeping a fixed interval.
2207026
Unsupported video format
Re-encode to what Meta accepts for the media type - Reels and feed video have different codec, aspect-ratio and duration rules.

Meta returns these inside an error object with an optional error_subcode, and the message text is often more useful than the code. Log both - the same code 100 covers a typo in a field name and a Story that has already expired.

Access tokens and expiry

OAuth hands you a short-lived token. You exchange it for a long-lived token that lasts 60 days, then refresh that token to get another 60 - a refresh only works on a token that is at least 24 hours old and has not already expired. Miss the window and every call comes back as error 190 and your user has to reauthorize. This is the single most common way an Instagram integration breaks in production, because nothing fails until two months after you ship. Outstand refreshes tokens for every connected account so you never see a 190.

Or skip Meta App Review entirely

Instagram is one of the networks Outstand ships a reviewed OAuth app for. Your users authorize against it, and every requirement above becomes our problem.

Going direct to Meta

  1. 1Convert the account to Instagram Professional and link a Facebook Page
  2. 2Create a Meta app, add the Instagram product, configure OAuth redirects
  3. 3Submit App Review for the publishing permissions and pass Business Verification
  4. 4Build the OAuth exchange, store the long-lived token and refresh it before 60 days
  5. 5Host the media on public HTTPS and build create-container → poll → publish, per item
  6. 6Handle 190s, 4/613 rate limits, EXPIRED containers and the 50-post daily ceiling

Weeks, and the review clock is not yours to control.

Going through Outstand

bash
curl -X POST https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "containers": [
      {
        "content": "Our Q2 launch is live 🚀",
        "media": [
          { "url": "https://media.outstand.so/org_abc/med_abc.mp4", "filename": "launch.mp4" }
        ]
      }
    ],
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"]
  }'

One call. We create the container, poll it, publish it, count it against the daily limit and refresh the token. Already through App Review yourself? Drop your own Meta app credentials in and the OAuth screen says your brand instead of ours - the same setup behind our white label social media management platform.

Building an agent instead of an app? The same account works with our Instagram MCP server and our social media API for AI agents.

Everything Instagram supports, through one endpoint

Every content type and capability available on Instagram via Outstand today.

Feed photos

Carousels (2–10)

Reels

Stories (24h)

PublishingSchedulingAnalyticsMedia handlingComments

Plus collaborators (invite up to 3), user tags, location and alt text. Reposting and deleting feed posts are not supported by Instagram's API.

Copy, paste, ship

The same accounts array also fans out to X, LinkedIn, TikTok and 8 more - one request, many platforms.

Publish a Reel

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Behind the scenes of the shoot 🎬 #reels",
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/bts.mp4", "filename": "bts.mp4" }],
    "instagram": { "reelThumbOffset": 1500 }
  }'

Publish a carousel (2–10 items)

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Swipe for the full lookbook →",
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"],
    "media": [
      { "url": "https://media.outstand.so/1.jpg", "filename": "1.jpg" },
      { "url": "https://media.outstand.so/2.jpg", "filename": "2.jpg" },
      { "url": "https://media.outstand.so/3.jpg", "filename": "3.jpg" }
    ],
    "instagram": { "collaborators": ["partner_brand"] }
  }'

Publish a Story

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "",
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/story.jpg", "filename": "story.jpg" }],
    "instagram": { "publishAsStory": true }
  }'

Schedule a post (up to 30 days out)

bash
curl https://api.outstand.so/v1/posts/ \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Drops Friday at noon ⏰",
    "accounts": ["YOUR_INSTAGRAM_ACCOUNT_ID"],
    "media": [{ "url": "https://media.outstand.so/teaser.jpg", "filename": "teaser.jpg" }],
    "scheduledAt": "2026-07-03T16:00:00Z"
  }'

Read analytics

bash
curl https://api.outstand.so/v1/posts/{id}/analytics \
  -H "Authorization: Bearer $OUTSTAND_API_KEY"
# → impressions, reach, likes, comments, saves, shares, views, engagement_rate

Read & reply to comments

bash
# Read the comments on a published Instagram post
curl "https://api.outstand.so/v1/posts/{id}/replies?network=instagram" \
  -H "Authorization: Bearer $OUTSTAND_API_KEY"

# Reply to a comment (or comment on your own post)
curl https://api.outstand.so/v1/posts/{id}/replies \
  -H "Authorization: Bearer $OUTSTAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Thanks for the love! 🙌", "account_username": "yourbrand" }'

Live in three steps

From signup to your first published Reel in about five minutes.

1

Connect Instagram

Your user authorizes via OAuth. We store and refresh the long-lived token. Use our Managed Keys, or bring your own Meta app for white-label.

2

Call POST /v1/posts/

Send text and media with accounts: ["YOUR_INSTAGRAM_ACCOUNT_ID"]. Add scheduledAt to schedule it for later.

3

We do the Graph API work

Container creation, status polling, retries and rate-limit handling - returned as a unified response with the published post ID.

Instagram API pricing and access

Meta does not bill you for the Instagram Graph API. It bills you in review cycles, account prerequisites and container plumbing - here is what each route actually costs.

What Meta charges
Nothing. The Instagram Graph API carries no licence fee or per-request cost. What gates you is App Review and account setup, not price.
Going direct to Meta
A Business or Creator account, a linked Facebook Page, a Meta app, and App Review for instagram_content_publish before you can post at all. Then you build the create-container → poll → publish flow and refresh long-lived tokens every 60 days.
Going through Outstand
An Outstand API key. Your users authorize with OAuth against our reviewed app, and one POST /v1/posts/ publishes a photo, carousel, Reel or Story.
Outstand pricing
$19/month including 3,000 posts, then $0.007/post - dropping to $0.005/post at volume. No per-seat fees and no annual lock-in.
Bringing your own app
Already through App Review? Drop your Meta app credentials in and Outstand runs OAuth under your brand, so your users never see ours.

Instagram caps content publishing at 50 posts per rolling 24 hours per account. Outstand queues against that ceiling rather than burning your quota on retries.

More than an Instagram wrapper

One integration that grows with everything you ship next.

One API, 12 platforms

The same request publishes to Instagram, X, LinkedIn, TikTok and the rest. Same JSON shape everywhere.

Managed Keys or BYOK

Skip Meta App Review with our keys, or bring your own app for white-label OAuth under your brand.

Built for scale

Intelligent rate limiting, automatic token refresh, webhook events and media processing.

Honest pricing

$19/mo includes 3,000 posts, then from $0.007/post. No seats, no annual lock-in.

What you can build

Same endpoints, same data shapes - pick what you ship.

Social schedulers

Let your users queue and auto-publish Instagram content from your app.

AI agents

Give Claude or GPT a tool to post to Instagram. MCP server included.

Analytics dashboards

Pull Instagram reach and engagement alongside every other platform.

Agencies & white-label

Run Instagram posting for clients under your own brand and Meta app.

Instagram API FAQ

The questions developers ask before they build.

Is the Instagram API free?

Meta charges no licence fee and no per-request price for the Instagram API - in that sense it is free. The cost is access: an Instagram Professional account, a Meta app, App Review for the publishing permissions and Business Verification before your first post goes out, then the engineering time around containers, polling and 60-day tokens.

How do I get Instagram API access?

Convert the account to Instagram Professional (Business or Creator), link a Facebook Page, create a Meta app with the Instagram product, then submit App Review for the publishing permissions and complete Business Verification. Until review passes, your app can only act on accounts that hold a role on it. Outstand ships an already-reviewed app, so your users can authorize with OAuth today.

Can I post to Instagram without app review?

Only to accounts that have a role on your own Meta app while it is in development mode - fine for testing, useless for customers. To publish for anyone else you either pass App Review yourself or authorize against an app that already has, which is what Outstand provides.

What is the Instagram Graph API rate limit?

Two separate ceilings. The Content Publishing Limit is 50 published posts per rolling 24 hours per Instagram account, readable at GET /{ig-user-id}/content_publishing_limit. On top of that, Meta applies platform rate limiting per app (Business Use Case rate limits), so all of your tenants share one budget. Exceeding either returns error 4 or 613.

Can I post Reels via the API?

Yes. Create the container with media_type=REELS and a public video_url, poll until status_code is FINISHED, then publish it. You can set a cover_url or a thumb_offset - not both - and invite up to 3 collaborators. Outstand does the whole sequence behind one POST /v1/posts/.

Does the Instagram API support Stories?

Yes, with media_type=STORIES and a single image or video - no captions and no carousels, and the story expires after 24 hours. In our own integration Meta rejects Story publishing for Creator accounts, so a Business account is the safe requirement.

Does Instagram have an official API?

Yes - the Instagram Graph API (part of the Meta Graph API) lets approved apps publish posts, Reels, Stories and read insights for Business and Creator accounts. Outstand is a managed layer on top of it, so you skip the setup.

Can I post Instagram Reels via API?

Yes. Send a video file to POST /v1/posts/ with accounts: ["YOUR_INSTAGRAM_ACCOUNT_ID"] and Outstand publishes it as a Reel - you can set a thumbnail offset and invite collaborators.

Can I schedule Instagram posts via the API?

Yes. Add a scheduledAt ISO-8601 timestamp (up to 30 days ahead) and Outstand publishes it automatically - no cron or queue on your side.

Do I need a Business or Creator account?

Yes - Instagram only allows API publishing for Business or Creator accounts (a Meta requirement, not ours). Personal accounts cannot publish via any Instagram API.

Can I post Instagram Stories via API?

Yes. Set instagram.publishAsStory: true with a single image or video. Stories do not support carousels or captions and expire after 24 hours.

How do I get an Instagram access token?

With Outstand you do not manage tokens manually - your user connects through OAuth and we store and auto-refresh the long-lived token. Bring your own Meta app for white-label, or use our Managed Keys.

What are the Instagram API rate limits?

Instagram caps content publishing at 50 published posts per rolling 24 hours per account, and separately applies app-level platform rate limits. Outstand queues and throttles requests under the hood, so you never handle a 429 yourself.

Can I read and reply to Instagram comments via the API?

Yes. Read the comments on a published post with GET /v1/posts/{id}/replies and post a reply with POST /v1/posts/{id}/replies. Comment management requires a Business or Creator account.

Can I post to Instagram without the Graph API?

Not officially - the Graph API is the only sanctioned way to publish. Outstand uses it for you so you get a clean REST endpoint instead of the container-and-polling flow.

How much does the Instagram API cost?

Meta charges no licence fee for the Instagram Graph API - the cost is App Review, a linked Facebook Page and the engineering time around the container flow. Outstand costs $19/month including 3,000 posts, then $0.007/post dropping to $0.005 at volume, on an app that is already reviewed.

Is the Instagram API free?

Free to call, not free to reach. Meta does not bill you per request, but publishing permissions require App Review, a Business or Creator account and a linked Facebook Page before a single post goes out. Outstand removes that setup - you get an API key and publish the same day.

How do I get an Instagram API key?

Instagram does not issue a plain API key. You create a Meta app, request the instagram_content_publish permission, pass App Review, then exchange OAuth codes for long-lived tokens that you refresh every 60 days. Outstand gives you one bearer token that works across Instagram and 11 other networks and refreshes the Meta tokens behind it.

What happened to the Instagram Basic Display API?

Meta shut it down in December 2024. Apps that relied on it had to move to the Instagram Graph API or the Instagram API with Instagram Login. Publishing has always run through the Graph API, which is what Outstand calls on your behalf.

Can I post an Instagram carousel via the API?

Yes. Send 2 to 10 media items in the media array and Outstand assembles the child containers in order and publishes them as one carousel - including mixed images and video.

Ship Instagram posting today

Grab an API key and publish your first Reel in the next five minutes. 3,000 posts included, then $0.007/post - dropping to $0.005 at volume.