Instagram Stories Scraper - Live Stories, Own Cookie
Pricing
from $2.50 / 1,000 result returneds
Instagram Stories Scraper - Live Stories, Own Cookie
Scrape stories from public Instagram profiles. Each row has media URLs, type, timestamp, mentions, links, hashtags and the poster. A story is gone 24 hours after it goes up. So a run only shows what is live right now. No login, no cookie, no app review. $2.50 per 1,000 stories.
Pricing
from $2.50 / 1,000 result returneds
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
15
Total users
7
Monthly active users
3 days ago
Last modified
Categories
Share
Instagram Stories Scraper: live stories and pinned highlights from public profiles
Name up to five public Instagram handles and get their stories back as rows. Media type, the image or video link, when it was posted, the caption, any location tag, and the sponsored flag.
Here is the thing that decides whether this is useful to you. A story is gone 24 hours after it goes up, so a run only sees what is live at the moment you press Start. If you want the older material, that is what highlights are: the trays an account pins to its profile, which do not expire. They are switched on by default.
| Input | Up to 5 public handles, @handles or profile URLs |
| Output | One row per story or highlight item |
| Ceiling | 100 rows per profile, 5 profiles per run |
| Account needed | None from you |
| Price | $2.50 per 1,000 rows, flat on every plan |
🔍 What Instagram Stories Scraper does
It reads what is live on each handle right now, plus the pinned highlight trays if you leave those
on, and writes one row per item. Stories and highlights come back in the same shape, and
recordType tells you which you are looking at. Highlight rows also carry the tray they came from
in highlightTitle.
Nothing to log into. No API key, no cookie, no app review.
maxStoriesPerProfile is applied to current stories and to highlights separately. Set it to 25
and a profile with both can return up to 50 rows, and you pay per row. Set it low while you are
working out how much a handle actually has.
If you do supply your own cookie in sessionCookies, the run uses your account's own rate limit,
and it returns current stories only. Highlights come back on the default route.
📥 What you give it
{"profiles": ["nasa", "natgeo"],"maxStoriesPerProfile": 25,"includeHighlights": true}
| Field | Default | What it is |
|---|---|---|
profiles | none | nasa, @nasa or a full profile URL. Up to 5 in one run. |
maxStoriesPerProfile | 25 | Rows per profile, 1 to 100, counted separately for current stories and for highlights. |
includeHighlights | true | The pinned trays. Untick it to get only what is live today. A profile with nothing pinned simply returns nothing extra. |
maxRunSeconds | 120 | Wall-clock ceiling for the whole run, 20 to 180. |
requestTimeoutSeconds | 15 | How long one request may take, 5 to 30. |
maxAttempts | 6 | How many times a refused request is retried before the run gives up on it. 1 to 12. |
sessionCookies | none | Optional. Your own Instagram sessionid, for your own rate limit. Current stories only on this route. |
proxyConfiguration | Apify default | Leave it alone. Put servers of your own in proxyUrls inside it if you have them. |
Start a run with no profiles and you get one labelled sample row showing the output shape. That row is not charged.
📤 What you get back
A real row from a real run, with the long media links cut short:
{"ok": true,"recordType": "story","storyId": "3978846251986655690","sourceUsername": "nasa","sourceProfileId": "528817151","ownerUsername": "nasa","mediaType": "video","takenAt": "2026-09-04T15:23:44.000Z","expiresAt": null,"caption": null,"imageUrl": "https://scontent-xxc1-1.cdninstagram.com/v/t51.82787-15/...","videoUrl": "https://scontent-xxc1-1.cdninstagram.com/o1/v/t2/f2/m78/...","durationSeconds": 15,"dimensions": null,"isSponsored": false,"location": null,"storyUrl": "https://www.instagram.com/stories/nasa/3978846251986655690/"}
A highlight row is the same shape with recordType: "highlight" and two extra fields, highlightId
and highlightTitle, naming the tray it was pinned into.
| Field | What it is |
|---|---|
storyId | Unique per item. Use it as your dedupe key across runs. |
mediaType | image, video or carousel. A video row carries both imageUrl (the cover frame) and videoUrl. |
imageUrl, videoUrl | Signed links that expire within hours. Download anything you want to keep, in the same job. |
takenAt | When the item was posted. null when Instagram did not supply it, never a made-up date. |
expiresAt, dimensions | Frequently null. They arrive when Instagram sends them and are left empty when it does not, so do not build on them. |
location | An object with the place id, name, address and coordinates when the item carries a location sticker. null otherwise. |
isSponsored | Instagram's own paid-partnership flag on the item. |
Nothing is guessed or padded.
🧾 Reading the output
Three kinds of row land in your dataset, and only the first kind is billed.
| Row | How to spot it | Billed |
|---|---|---|
| A story or a highlight item | ok: true and a storyId | yes |
| The sample row | _sample: true, and only on a run with no profiles | no |
| A diagnostic | ok: false and an errorCode | no |
Filter on ok == true and you have your media. Every diagnostic row names the handle it belongs to
in sourceUsername, so you always know which profile it is about.
| Code | What it means |
|---|---|
NO_CURRENT_STORIES | Nothing was live on that profile at the moment of the run. |
NOT_FOUND | No such account. |
PRIVATE_OR_RESTRICTED | The account is private, or closed to a reader who is not following it. |
BAD_INPUT | Nothing in profiles looked like a handle. |
PARTIAL | The run delivered some rows and then stopped. What arrived is complete and correct. |
DEADLINE_EXCEEDED | The run hit maxRunSeconds before reaching that profile. Raise it. |
RATE_LIMITED | Too many requests too close together. Space the runs out. |
AUTHENTICATION_FAILED, SESSION_EXHAUSTED | If you supplied a cookie, check it is still valid. |
PROXY_GROUP_IGNORED | A setting in proxyConfiguration could not be used as written. |
SERVER_ERROR, NETWORK | Instagram was unreachable or answered badly. Re-run it. |
No diagnostic row is billed as a result.
▶️ How to run it
- Open Instagram Stories Scraper and click Try for free.
- Put your handles into Public Instagram profiles, up to five.
- Set Maximum current stories per profile. Start at 5 while you look at the output shape.
- Leave Also get story highlights on if you want the older pinned material.
- Click Start, then download the dataset as JSON, CSV or Excel.
💰 How much does it cost?
$2.50 per 1,000 rows. Flat on every Apify plan, no volume tiers.
One charge per row delivered, whether it is a live story or a highlight item. Sample rows and diagnostic rows are not billed, and a profile with nothing live is not billed for results.
Remember the cap counts twice, once for current stories and once for highlights. A five-profile run at 25 can come back with 250 rows rather than 125 if every profile has both.
💡 What people use it for
- Checking daily whether a set of brands is running stories, and archiving them before they vanish.
- Pulling a competitor's highlight trays as a snapshot of how they present themselves.
- Collecting story links and sponsored flags to see which creators are running paid placements.
- Keeping a record of a campaign's stories, since nobody can go back for them the next day.
🚧 What it does not do
- No expired stories. Once the 24 hours are up the item is gone, and highlights are the only way back to older material.
- No private accounts, and no accounts that only show stories to followers.
- No viewer lists, no reply counts, no poll or quiz results. Those are visible only to the account that posted.
- Highlights need the default route. Supply your own cookie and you get current stories only.
expiresAtanddimensionsare often empty, so do not build a pipeline that requires them.- Media links expire within hours. Download the files in the same job.
- Five profiles per run, 100 rows per profile on each of the two kinds.
🧭 Which Instagram scraper do you need?
| If you want | Use |
|---|---|
| Live stories and pinned highlights | This one |
| Posts and reels from a profile | Instagram Scraper |
| Follower counts, bio, email and links | Instagram Profile Scraper |
| Reels from a profile's reels tab | Instagram Reel Scraper |
| Posts other people made about a handle | Instagram Mentions Scraper |
❓ Questions people ask
Do I need an Instagram account? No. The cookie field is optional and gives you a rate limit nobody else shares.
Why did I get nothing back? Most likely nobody had a story live at that moment. The
NO_CURRENT_STORIES row in your dataset says so, and it is not billed.
Can I get stories from yesterday? Only if the account pinned them into a highlight. Instagram deletes the rest after 24 hours.
Can the account see that I read its story? No. Nothing is viewed as an account, so nothing turns up in its viewer list.
How often should I schedule it? Every few hours if you want to catch everything, since stories come and go inside a day.
Is scraping Instagram legal? This reads public profiles only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
🆘 If something breaks
Open the Issues tab on the actor page. Send the handle you used and the run ID. The errorCode
on the diagnostic row usually explains it on its own.