A post lives on a profile indefinitely — pull it today, pull it again next month, same data. A Story doesn't work that way. It's live for roughly 24 hours, and once it expires there's no public record of it left to fetch. If a competitor posts a discount code, a flash-sale link, or a product teaser to Stories only, the only window to capture it is while it's actually live.
That's a different data problem than tracking posts. It's not about how much history you can pull — it's about how often you check, and whether you check before the thing you're watching disappears.
If you're an agent (or building one) reading this rather than a human, the full machine-readable schema for every endpoint below lives at mindcase.co/skills.md.
Why does Stories data need different handling than posts?
Posts, followers, and profile data are all durable — pull them whenever, the record's still there tomorrow. Stories are the one Instagram surface where "I'll check it later" is a real failure mode, not just a delay. A tool built to poll posts once a day, on the same schedule, will miss every Story that goes up and comes down inside that gap.
The practical effect: if you care about Stories at all — a competitor's promo drops, an influencer's sponsored placements, a brand's behind-the- scenes content — the polling interval isn't a performance detail, it's the feature. Check every few hours and you catch most of what goes up. Check once a day and you're relying on luck.
What does the Instagram Stories API actually return?
Instagram Stories API takes one or more usernames and returns each account's currently-active Stories — nothing more, nothing retroactive. An account with no live Story returns no rows for that pull; there's no way to ask for what someone posted yesterday.
Each row is 21 fields: storyId, shortcode, username, profileUrl,
fullName, isVerified, mediaType, imageUrl, videoUrl,
videoDuration, hasAudio, width, height, takenAt, expiringAt,
isPaidPartnership, linkUrl, linkTitle, musicTitle, musicArtist,
posterProfilePic. Two of those are the ones that matter most for
scheduling: takenAt tells you when it actually went up, and expiringAt
tells you exactly when it's gone — not an assumed 24 hours, but the real
timestamp Instagram is enforcing for that specific Story.
How do you pull an account's active Stories?
Say you're tracking a competitor's promotional activity and they've started running flash sales through Stories instead of the main feed.
curl -X POST "https://api.mindcase.co/v1/data/instagram/stories/run?wait=true" \
-H "Authorization: Bearer $MINDCASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"params": {
"usernames": ["competitorbrand"]
}
}'
# $0.01 per storyusernames accepts an array, so one call covers a whole watchlist — a
handful of competitors, or every account in a sponsorship deal you're
auditing — not one account per request. linkUrl and linkTitle are
where a Story's swipe-up/link-sticker destination shows up, which is
usually the actual payload you're after in a promo-tracking pull: the
discount code or landing page a competitor only ever put in front of their
Story audience, not the main feed.
How often should you poll, and why does it matter?
There's no webhook or push notification for a new Story — the only way to
know one exists is to ask. That makes the polling interval a direct
trade-off against $0.01 per story returned: poll every hour and you'll
catch nearly everything but pay for a lot of empty checks against accounts
that haven't posted; poll once a day and you'll miss anything that went up
and expired inside that window.
A reasonable middle ground for competitor or influencer monitoring is
checking every 2-4 hours during the hours an account is actually active —
takenAt on what you do catch tells you their real posting pattern, so the
schedule can tighten around it after the first few pulls instead of
guessing upfront. expiringAt is also worth storing even when you can't
capture the media itself — a log of when an account posted Stories, and
how many, is its own signal about posting cadence and campaign timing.
What can't you get from Mindcase?
Two cases.
You don't already know the account. usernames is the only way in —
there's no keyword or hashtag search across everyone currently posting
Stories about a topic. You need the specific handle before you can check
it, same as you'd need to open the app and know whose Story you're tapping.
A Story that already expired. Once expiringAt passes, that Story is
gone from Instagram's own servers, not just from this endpoint — no vendor
can return media Instagram itself no longer serves. If a pull runs late,
the miss is permanent for that Story; the fix is a tighter polling
schedule going forward, not a longer lookback window.
Which endpoint should you use for which job?
| Endpoint | Input | Price | Best for |
|---|---|---|---|
| Instagram Stories | Username(s) | $0.01 / story | Time-sensitive content that won't exist tomorrow — promos, link stickers, sponsored placements |
| Instagram Posts & Reels | Handle, post URL, hashtag, or keyword | $0.002 / post | Durable content you can pull on any schedule and still get full history |
FAQ
Instagram's default is roughly 24 hours from posting, but the exact figure comes back on every row as expiringAt — treat that timestamp as the real deadline, not an assumed 24-hour window, since highlighted or pinned content on the account's side can behave differently.
Yes. The usernames input takes an array, so a watchlist of competitor or influencer accounts is one request, not one per account.
That account returns no rows for that pull. It's not an error — it just means nothing is currently live, and there's no historical fallback to return instead.
No. This endpoint only returns what's currently active. Once a Story expires it's gone from Instagram's side, and no API can return media the platform itself no longer serves.
$0.01 per story row returned on each call — an account with an active Story returns and bills that row every time you check while it's still live, not once per Story. A 10-account watchlist checked four times a day costs at most $0.40 for that day, whether one account posted a Story or all ten did — the real cost driver is how many checks you run, not how many unique Stories existed.