Instagram Stories Scraper
Scrape public Instagram stories with media URLs, type, timestamp and expiry using your own session cookie. $0.40 per 1,000 stories, flat.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
profiles,maxStoriesPerProfile,sessionCookies(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.0004 per result = $0.4 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Result returned | Charged once per genuine result row. Samples, diagnostics and blocked runs are never charged. | $0.0004 |
| Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.001 |
Pay-per-event pricing: you are billed per result, not per subscription — a run that returns nothing costs nothing beyond the start fee. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-04, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
profiles | Up to five public Instagram usernames, @handles, or profile URLs. Empty input or no configured account session returns exactly one labeled, uncharged sample row. | array |
maxStoriesPerProfile | Maximum currently available story rows returned for each profile. Stories are limited by Instagram's current-story window. | integer |
sessionCookies | Optional, and normally not needed — runs work with no cookie at all. Supply your own Instagram account cookie here to run on your own account's rate limit, and to reach feeds the no-setup route does not cover. In Chrome: F12 -> Application -> Cookies -> https://www.instagram.com -> copy the sessionid value. Use an account you own and are authorized to automate. Cookie values are never logged or written to output. | array |
maxAttempts | Bounded retries across rotating configured accounts and sticky proxy sessions. | integer |
requestTimeoutSeconds | Timeout for each authenticated Instagram request. | integer |
maxRunSeconds | Hard wall-clock bound for profile resolution and story retrieval. | integer |
What you get
A structured dataset — each result includes fields like:
sourceUsernamestoryIdmediaTypetakenAtexpiresAtcaptionstoryUrlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
14 ready-to-run use cases
Track automotive brand stories
Track automotive brand stories. Runs on @bmw and @audi and @mercedesbenz — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Track a brand’s Instagram stories before they expire
Track a brand’s Instagram stories before they expire. Runs on @starbucks — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Monitor Competitor Instagram Stories
Track competitor Instagram stories before they expire — media URLs, type, timestamp, mentions and links as structured JSON. No login, no cookie, no app review.
Track food and beverage brand stories
Track food and beverage brand stories. Runs on @starbucks and @mcdonalds — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Archive an influencer’s stories for campaign proof
Archive an influencer’s stories for campaign proof. Runs on @cristiano — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Prove influencer story deliverables for a campaign
Prove influencer story deliverables for a campaign. Runs on @kyliejenner — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Capture breaking-news accounts’ Instagram stories
Capture breaking-news accounts’ Instagram stories. Runs on @bbcnews and @cnn. No login needed.
Watch product-launch stories from major brands
Watch product-launch stories from major brands. Runs on @apple and @samsung. No login needed.
Archive retail brand stories every day
Archive retail brand stories every day. Runs on @zara and @hm — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Follow sports teams’ matchday Instagram stories
Follow sports teams’ matchday Instagram stories. Runs on @fcbarcelona and @realmadrid. No login needed.
Benchmark how often competitors post stories
Benchmark how often competitors post stories. Runs on @nike, @adidas, @puma and more. No login needed.
Extract link stickers from brand stories
Extract link stickers from brand stories. Runs on @sephora and @asos — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Capture story polls and question stickers
Capture story polls and question stickers. Runs on @netflix — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Capture promo codes shared in stories
Capture promo codes shared in stories. Runs on @gymshark — media URLs, story type, timestamp, mentions, links and hashtags. No login needed.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos or users and export clean rows: stars, forks, language, topics, license, plus user bio, company, location and follower count.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tags. Get structured questions with score, answers, views, tags, author, and link as JSON or CSV.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata - version, license, repo, keywords, and npm download counts. Search by keyword or look up exact names. No API key needed.
arXiv Scraper
Search arXiv and get clean JSON: titles, abstracts, authors, categories, DOI, dates and PDF links. No API key. Sort by relevance or date; push to Notion.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers by keyword. Get titles, authors, venue, year, citations, concepts, OA links and full abstracts as structured JSON. No API key.
Crossref Scholarly Works Scraper
Search 150M+ scholarly works on Crossref and export DOI, authors, journal, citation count, and abstracts as JSON or CSV. Filter by type and date.
Where this tool sits
- Categories
- Developer & Research Tools
Instagram Stories Scraper
Extract the currently available stories from public Instagram accounts. Runs work with no setup: no login, no cookie, no app review, nothing to supply.
It returns story metadata and direct media URLs. It does not download media binaries, read private accounts, or reach expired stories or viewer lists.
What you need to know before you run it
Story trays work out of the box. A story is ephemeral and never indexed, so Instagram serves a live tray only to a signed-in caller — there is no logged-out route to it at any price. This actor reads the tray through a licensed data source. You supply nothing.
A run is a snapshot. Stories expire about 24 hours after they are posted, so you get exactly what was live at the moment the run happened, and nothing older. There is no archive to go back to. An account with no live stories right now returns nothing, and that is a correct answer, not an error — it arrives as an uncharged NO_CURRENT_STORIES row and costs you nothing.
Two fields the licensed source does not carry. This is the one real limitation and it is worth knowing before you start: on rows served by the licensed source, expiresAt and dimensions come back null. The source publishes no expiry timestamp — and a story's 24-hour lifetime is a rule of thumb, not data, so it is left empty rather than computed and sold to you as a fact — and the payload carries no media width or height at all. Every other field on the row is populated as documented. If you need those two fields, supply your own cookie: read directly from Instagram, they are present.
To use your own account — for those two fields, or to run on your own account's rate limit — put your cookie in sessionCookies:
- In Chrome:
F12→ Application → Cookies →https://www.instagram.com→ copy thesessionid
value. Pasting the whole cookie string works too.
- Your cookie takes priority over everything else. The run reads Instagram directly with it, and
reaches for the licensed source only for accounts that lane could not answer at all.
- A session cookie is equivalent to an active login. Use an account you own and are authorized to
automate, keep the value in Apify secrets rather than in a saved task, and revoke it through your normal account process when you are done.
Cookie values, proxy URLs, and request headers are never logged, written to the dataset, stored in this repository, or included in diagnostic rows.
Input
| Field | Purpose |
|---|---|
profiles | Up to five public usernames, @handles, or Instagram profile URLs. |
maxStoriesPerProfile | 1-50 current story rows for each profile; default 25. |
sessionCookies | Optional. Your own Instagram account cookie. Leave it empty and the run uses the licensed data source. |
proxyConfiguration | Egress for requests sent to Instagram directly, i.e. the lane your own cookie uses; the default is Apify datacenter (BUYPROXIES94952). Metered groups (RESIDENTIAL, GOOGLE_SERP) are not offered and are replaced with datacenter addresses. Your own proxyUrls are used verbatim. |
maxAttempts | 1-12 bounded account/IP attempts on that same direct lane; default 6. |
requestTimeoutSeconds | 5-30 seconds for each Instagram request; default 15. |
maxRunSeconds | 20-180 seconds hard run deadline; default 120. |
With empty input the actor returns exactly one clearly labeled _sample row. The sample makes no Instagram request, no proxy connection, no credential use, and no billing event.
Method and reliability
Without a cookie, each requested username is sent straight to the licensed source, which is addressed by username and returns the whole live tray in a single lookup. That means one lookup per account, whatever maxStoriesPerProfile is set to — the tray is not paged.
With your cookie, the username is first resolved to its numeric profile id from the public, logged-out profile endpoint, because a profile page answers a guest request and costs nothing; your cookie is spent on that step only if the guest attempt comes back gated. The tray itself is then read with the cookie, paired one-to-one with a sticky datacenter IP. A 403, 429, server error, or network failure rotates to a fresh sticky proxy session up to the configured bound. If Instagram challenges datacenter addresses, supply your own residential endpoints in proxyUrls — they are honoured exactly as given.
If that direct lane returns no stories at all, the run retries only the accounts it never got an answer for, through the licensed source. Accounts it did answer — including the ones that answered "nothing live right now" — are not looked up a second time, and no story can be billed twice: rows are deduplicated on storyId and charged once each.
Private accounts are out of reach on both paths, because nobody outside the follower list can read those stories. They are reported as an uncharged PRIVATE_OR_RESTRICTED row and no further lookup is spent on them.
Failures are named for what they are rather than flattened into one generic error: a rate limit reads as a rate limit, an upstream outage as an upstream outage, and a problem on our side is never reported as a problem on yours.
When a run stops early
A run can stop before every account is checked — the run deadline passes, or the actor reaches the per-run lookup budget set on the licensed source. That is a soft landing, never a crash: every story already collected is delivered and correct, and one uncharged PARTIAL or DEADLINE_EXCEEDED row tells you it stopped and why. Re-run to pick up the rest.
Story rows are written to the dataset before the billing event is charged. Samples, private-profile records, empty story trays, early stops, and all other diagnostics are never charged.
Output
Each genuine row contains:
storyId,sourceUsername,sourceProfileId, andownerUsernamemediaType,imageUrl,videoUrl, anddurationSecondstakenAt, caption, paid-partnership flag, and location when presentexpiresAtanddimensions— populated when the run used your own cookie,nullon the licensed
source (see the limitation above)
- A canonical
storyUrl
Stories are ephemeral. NO_CURRENT_STORIES means the lookup completed normally and the public account simply had nothing live at that moment.
Pricing
$0.40 per 1,000 stories ($0.0004 each), plus $0.001 each time a run starts. Flat rate — no volume tiers, no plan gates — and you are charged only for stories actually returned.
The billed event fires once per unique story row, and only after that row has been written to the dataset. Samples, private-profile records, empty story trays, early stops, and every other diagnostic are never charged — a run that returns no stories costs only the $0.001 start fee.