Instagram Stories API: Publish Stories and Read Insights

By Nick ReyesPublished 8 min read

The short answer

The Instagram Stories API is the content publishing flow with media_type=STORIES: create a container from a public JPEG or video URL, wait for video to finish processing, then call media_publish. Stories take no stickers or captions, video runs 3 to 60 seconds, and Story insights vanish after 24 hours. Adeli publishes image and video Stories through one API.

The Instagram Stories API is Meta's content publishing flow with media_type=STORIES: you create a container from a public image or video URL, wait for the video to process, then publish it with media_publish. A Story goes live for 24 hours, and its insights disappear on the same clock.

Most of the trouble comes from what the API won't do. Developers keep finding out that stickers, links, and polls can't be added, that Creator accounts hit walls, and that Story metrics expire before a daily report job gets to them. This guide covers the publishing calls, the spec, which accounts can post, mentions, and Story insights. Our guide to posting to Instagram via API compares all four formats side by side, and the Instagram Reels API post covers Reels.

What do you need to publish an Instagram Story through the API?

Publishing an Instagram Story needs a professional Instagram account, a token with the content publishing permission, and the media at a public URL (or uploaded through Meta's resumable upload). Meta's content publishing guide lists three setups:

Instagram Login Facebook Login Unified Login
Host graph.instagram.com graph.facebook.com graph.facebook.com
Token Instagram User access token Facebook Page access token Business Integration System User access token
Permissions instagram_business_basic, instagram_business_content_publish instagram_basic, instagram_content_publish, pages_read_engagement instagram_basic, instagram_content_publish
Resumable file upload No Yes Yes

Use a Business account if you can. Meta opened the Content Publishing API to Creator accounts in June 2023, a month after Stories arrived. But developers on Meta's forum report that Story containers fail for Creator accounts while Reels and images from the same account work. The current reference doesn't state a rule either way. If your users include creators, run a Story through a Creator account in testing before you promise the feature.

Publishing for accounts you don't own also needs Advanced Access, which means Meta app review. The Instagram API permissions guide explains each scope.

What are the Instagram Story specs?

Instagram Story images must be JPEG up to 8 MB, and Story videos must be MP4 or MOV, 3 to 60 seconds, up to 100 MB. Meta recommends 9:16 for both. The full spec comes from the IG User media reference:

Spec Image Story Video Story
Format JPEG only MP4 or MOV with the moov atom first and no edit lists
File size 8 MB maximum 100 MB maximum
Duration — 3 to 60 seconds
Aspect ratio 9:16 recommended 0.1:1 to 10:1 allowed, 9:16 recommended
Codecs sRGB (other color spaces get converted) HEVC or H.264, AAC audio at 48 kHz max, 128 kbps
Frame rate and width — 23 to 60 FPS, 1,920 pixels wide at most
Bitrate — VBR, 25 Mbps maximum

Two limits are tighter than the feed: a Story video caps at 60 seconds, where a Reel can run 15 minutes, and at 100 MB, a third of the Reels ceiling. Trim long clips before you create the container, because Meta rejects the file rather than cutting it.

Step 1: Create a Story container

POST to /<IG_ID>/media with media_type=STORIES and either image_url or video_url. This is the "Instagram API for posting stories" call. It returns a container ID, not a live Story.

curl -X POST "https://graph.facebook.com/v26.0/<IG_ID>/media" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -d '{
    "media_type": "STORIES",
    "video_url": "https://example.com/story.mp4"
  }'
{ "id": "<IG_CONTAINER_ID>" }

For an image Story, swap video_url for image_url with a JPEG. With Instagram Login, call graph.instagram.com with an Instagram User access token instead.

Step 2: Wait for the video to finish processing

For a video Story, GET the container's status_code until it reads FINISHED. Meta's guide suggests checking once a minute for no more than 5 minutes.

curl "https://graph.facebook.com/v26.0/<IG_CONTAINER_ID>?fields=status_code" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

ERROR means the file broke the spec. EXPIRED means nobody published the container within 24 hours, so create a new one. The Reels guide has the full status table and the upload error subcodes, which are the same for Stories.

Step 3: Publish the Story

POST the container ID to /<IG_ID>/media_publish as creation_id. The response holds the Instagram Media ID of the live Story.

curl -X POST "https://graph.facebook.com/v26.0/<IG_ID>/media_publish" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -d '{"creation_id": "<IG_CONTAINER_ID>"}'

Save that media ID right away. You need it for Story insights, and Meta stops serving the Story after 24 hours. When you read it back, media_product_type returns STORY, while media_type only says IMAGE or VIDEO.

Can I upload a Story file instead of a URL?

Yes, with Facebook Login or Unified Login, through Meta's resumable upload on rupload.facebook.com. Create the container with upload_type=resumable, then send the file's bytes to the upload URL Meta returns. Meta's publishing guide says every media type shares that same video upload flow, Stories included.

With Instagram Login, there is no upload endpoint. Host the file somewhere Meta can fetch it, such as a short-lived signed URL from your storage bucket, and pass it as video_url or image_url. Meta has to reach the file when you create the container, so a link that expires in seconds fails.

Can I add stickers, links, or mentions to a Story?

The Instagram API publishes mentions on Stories but not stickers. Meta's IG User media reference says publishing link, poll, and location stickers is not supported. Here's what a Story container accepts:

Feature Through the API? Notes
Link sticker No No API field adds a link to a Story
Poll, quiz, question stickers No Add them in the Instagram app instead
Location sticker No Covered by the same sticker restriction
Mentions Yes user_tags with a username; x and y are optional on Stories (added July 2025)
Collaborators No Meta marks collaborators as not supported for Stories
Alt text No alt_text excludes Reels and Stories
Shopping tags and filters No Not supported on any API-published media

A mention looks like this. Include coordinates only if you want to place the tag:

{
  "media_type": "STORIES",
  "image_url": "https://example.com/story.jpg",
  "user_tags": [{ "username": "partneraccount", "x": 0.5, "y": 0.8 }]
}

If your product needs a swipe-up link, put it somewhere the API can reach: the caption of a feed post or Reel, or the account's bio. A Story can't carry it.

Common mistakes with the Instagram Stories API

Most failed Stories in developer threads come from three things: features the API doesn't publish, the account type, and old forum answers that predate Meta's changes.

Posting a story via graph.instagram.com works fine - but as soon as I add the parameter "user_tags" I get an error

— Eric on the Meta Developer Community

same problem, i cannot manage to add any info (location, user tags...) on story, only a plain photo.

— Grégoire on the Meta Developer Community

Old but in the actual documentation facebook is expliciting that's only available for business accounts

— Manoel, answering a Creator account Stories question on the Meta Developer Community

Those threads predate the July 2025 change that made Story mentions work, so tagging a username is fine now; location still isn't. The account type issue hasn't gone away: test Creator accounts before you rely on them, as covered in the prerequisites above.

How do I list an account's live Stories?

Call GET /<IG_ID>/stories on an account that authorized your app. The stories edge reference returns the Story media IDs that are still live. The regular /media edge leaves Stories out.

curl -G "https://graph.facebook.com/v26.0/<IG_ID>/stories" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  --data-urlencode "fields=id,media_type,media_product_type,timestamp,permalink"

The edge has gaps worth knowing:

  • No Live Video Stories. Meta leaves them out of the response.
  • No reshared Stories. A Story the account created by resharing another Story isn't returned.
  • No updates or deletes through this edge. It only reads.
  • No other accounts. You can only read Stories for accounts that authorized your app. Business discovery, the endpoint for reading other accounts, has no Stories field; see our Instagram business discovery API guide for what it does return.

How does the Instagram story insights API work?

The Instagram story insights API is the media insights endpoint, GET /<IG_MEDIA_ID>/insights, called with a Story's media ID within 24 hours of posting. It needs instagram_manage_insights (or instagram_business_manage_insights with Instagram Login). Our Instagram insights API guide covers account metrics and feed posts; this section stays on Stories.

curl -G "https://graph.facebook.com/v26.0/<IG_MEDIA_ID>/insights" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  --data-urlencode "metric=views,reach,replies,shares,link_clicks"

The navigation metric counts every action taken from the Story. Request it on its own with the story_navigation_action_type breakdown, which Meta says works only with navigation:

curl -G "https://graph.facebook.com/v26.0/<IG_MEDIA_ID>/insights" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  --data-urlencode "metric=navigation" \
  --data-urlencode "breakdown=story_navigation_action_type"

The response splits into the four actions Meta tracks, per the media insights reference. Added together, they equal the navigation total:

Breakdown value What the viewer did
TAP_FORWARD Tapped to the next frame
TAP_BACK Tapped back to the previous frame
TAP_EXIT Left the Stories viewer
SWIPE_FORWARD Swiped to the next Story

That breakdown replaced the old taps_forward, taps_back, and exits metrics. link_clicks arrived in June 2026 and counts taps on links in the Story, such as a link sticker added in the app.

Plan for these Story-specific rules:

  • 24-hour window. Story metrics stop being available after 24 hours. A nightly reporting job will miss Stories posted the previous morning.
  • The 5-viewer floor. A metric with a value under 5 returns error 10, (#10) Not enough viewers for the media to show insights. Show it as too small to report.
  • Regional zeros. Meta says replies doesn't include replies from users in some regions, and returns 0 for Stories created in those regions.

Getting Story insights before they expire

Subscribe to the story_insights webhook field so Meta pushes the numbers to you. Meta's insights reference recommends it for exactly this reason. Per Meta's webhook fields table, the field works with Facebook Login and Unified Login, and not with Instagram Login. On Instagram Login, poll each live Story's insights on a schedule shorter than 24 hours and store what you get.

Can the API show who viewed a Story?

No. The Instagram API returns Story view counts, not the viewers. The media insights reference documents views (how many times the Story played) and reach (an estimate of unique accounts that saw it). No endpoint in Meta's references returns the list of accounts that watched a Story, so the closest thing to a story viewers endpoint is the reach count.

Is there a faster way to publish Instagram Stories?

Yes. Adeli publishes image and video Stories to Instagram through one API call, with no Meta developer app, app review, or token refresh job on your side. Adeli connects accounts through Meta's Unified Login and holds the Meta app, so you hold one API key. The request uses the same endpoint as every other network:

curl -X POST "https://app.tryadeli.com/api/v1/posts" \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "instagram",
    "accountId": "<ADELI_ACCOUNT_ID>",
    "story": {
      "url": "https://media.example.com/story.mp4",
      "userTags": [{ "username": "partneraccount" }]
    }
  }'

What Adeli does with a Story, per the Instagram publishing reference:

  • Checks the spec first. A video Story must run 3 to 60 seconds, and fields Stories don't take (caption, collaborators, alt text) are rejected with a 400 instead of being silently dropped.
  • Handles the upload. Stage a local file with direct uploads and Adeli delivers it to Meta, so you don't host public URLs.
  • Reports status. Staged uploads return 202 with a status URL you poll while Meta processes the video.

Adeli's analytics API reads account-level Instagram insights, which include Story interactions. Per-Story metrics still come from Meta's insights endpoint within the 24-hour window. Adeli is free to start with no per-post fees; see pricing for the details.

faq

Frequently asked questions

Do Stories count toward the Instagram API daily publishing limit?

Yes. When Meta raised the cap in June 2023, it said the limit applies across all media types, Stories included. Read the account's content_publishing_limit edge to see how much of the 24-hour quota is left before you queue a batch of Stories.

Can I read another account's Stories through the API?

No. The stories edge only works on an Instagram account that authorized your app, and business discovery, the endpoint for other accounts' public data, has no Stories field. Competitor Stories are out of reach through Meta's official API.

Does a Story reached through a highlight keep its insights?

Sometimes. Meta says Story metrics are only available for 24 hours, but also that you may receive data after the Story expires if the account added it to a highlight. Don't build on that exception; capture metrics before the 24 hours run out.

Power your next project
with one ads & social media API

Give your users publishing, scheduling, and analytics through one integration your team can actually maintain.

Try with agents

Start with free credits. No credit card required.