Export accessible Instagram Stories and Highlights with direct image/video URLs, timestamps, captions, links, mentions, hashtags, stickers, music, profile metrics, and highlight context. Download results as CSV, Excel, JSON, XML, or RSS, or use them through the Apify API and MCP server.
Instagram requires a logged-in session for story and highlight access. Supply your own authorized sessionid value or full Cookie header. This Actor does not log in for you, bypass private-profile permissions, or expose the cookie in output.
What can it do?
- Collect active 24-hour Stories and saved Highlight items.
- Return direct image/video variants, thumbnails, dimensions, duration, audio presence, and accessibility captions.
- Extract visible captions, links, mentions, hashtags, sticker types, and music title/artist/ID.
- Preserve highlight ID, title, cover, order, item order, and item count.
- Add profile ID, name, biography, verification/privacy status, picture, follower/following/post counts, business category, and external URL when Instagram returns them.
- Filter returned media by
sinceDateand prevent duplicate rows by stable ID. - Keep valid results when another profile or one media source fails.
- Distinguish a verified no-media profile from an expired cookie, private/missing profile, rate limit, changed response, or deadline stop in
RUN_SUMMARY.
Who is it for
This scraper is for social media analysts, brand owners, agencies, journalists, and compliance teams that need structured exports of Instagram Stories and Highlights they are authorized to view.
Access and permitted use
Only export Instagram content you are allowed to access and process. Respect Instagram's terms, privacy rules, copyright, and local data-protection laws. Do not use exported media or profile data for spam, harassment, or unauthorized surveillance.
Use cases
- Archive authorized campaign Stories before their 24-hour expiry.
- Monitor accessible brand or creator Highlights for additions and changes.
- Verify influencer Story links, mentions, media, and timestamps.
- Compare Highlight themes, titles, covers, and content across public profiles.
- Feed scheduled media snapshots into spreadsheets, warehouses, alerts, dashboards, or research agents.
Session cookie and privacy
Use a secondary Instagram account dedicated to authorized research where possible. In your logged-in browser, copy either the sessionid cookie value or the full Cookie header and paste it into the secret instagramCookies input.
The session can access only content that account is allowed to view. This Actor rejects private profiles instead of attempting to bypass privacy. Instagram may expire the session, request a checkpoint, or restrict a session/IP; renew the cookie in your browser when that happens. Never paste a cookie into an issue, task title, log, README, or public message.
Input settings
| Setting | JSON field | Description |
|---|---|---|
| Profiles | targets |
One or more usernames, @handles, or exact Instagram profile URLs. Duplicate profiles run once. |
| Maximum profiles | maxProfiles |
Process 1-1,000 unique profiles. |
| Active Stories | includeStories |
Collect active Stories visible to the session. |
| Highlights | includeHighlights |
Collect saved Highlight collections/items visible to the session. |
| Highlight limit | maxHighlightsPerProfile |
Process 0-200 Highlights per profile. |
| Item limit | maxItemsPerHighlight |
Export 1-500 items per Highlight. |
| Date filter | sinceDate |
Optional ISO date/timestamp; older returned media is filtered. |
| No-media row | saveProfileOnNoMedia |
Save a status row after an authorized check confirms no matching media. When false, a valid no-media result has no dataset row to carry the hidden recovery anchor; after an unclean stop before the checkpoint is saved, that profile can be checked and charged again on retry. Exact-once recovery applies only when an output row exists. |
| Raw data | includeRaw |
Preserve the source media object. Defaults to true for backward compatibility. |
| Session cookie | instagramCookies |
Required authorized sessionid value or full Cookie header. Stored as a secret input. |
| Proxy | proxyConfiguration |
Apify Proxy configuration; residential/ISP routes are usually more reliable. |
| Reliability | retryCount, initialRetryDelayMillis, requestPacingMillis, runTimeSecs |
Optional retry, pacing, and safe-deadline controls. |
The backward-compatible startUrls input remains accepted through API calls even though targets is the preferred UI field.
Input example
{
"targets": ["natgeo", "https://www.instagram.com/instagram/"],
"instagramCookies": "sessionid=YOUR_AUTHORIZED_SESSION_ID",
"includeStories": true,
"includeHighlights": true,
"maxProfiles": 2,
"maxHighlightsPerProfile": 5,
"maxItemsPerHighlight": 20,
"sinceDate": "2026-07-01T00:00:00Z",
"includeRaw": false,
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": ["RESIDENTIAL"]
}
}
Output example
{
"kind": "highlight_item",
"username": "natgeo",
"profileUrl": "https://www.instagram.com/natgeo/",
"profileId": "787132",
"fullName": "National Geographic",
"isVerified": true,
"status": "ok",
"sourceUrl": "https://www.instagram.com/stories/highlights/123456/",
"stableId": "787132:highlight_item:123456:987654",
"mediaId": "987654",
"mediaType": "video",
"mediaUrl": "https://scontent.cdninstagram.com/video.mp4",
"thumbnailUrl": "https://scontent.cdninstagram.com/image.jpg",
"imageUrls": ["https://scontent.cdninstagram.com/image.jpg"],
"videoUrls": ["https://scontent.cdninstagram.com/video.mp4"],
"caption": "Field notes #Wildlife",
"takenAt": "2026-07-14T10:00:00.000Z",
"durationSeconds": 8.5,
"width": 1080,
"height": 1920,
"linkUrls": ["https://example.org/story"],
"mentions": ["example_creator"],
"hashtags": ["Wildlife"],
"stickerTypes": ["link"],
"musicTitle": "Example track",
"musicArtist": "Example artist",
"highlightId": "123456",
"highlightTitle": "Expeditions",
"highlightIndex": 1,
"highlightItemIndex": 2,
"highlightItemCount": 12,
"scrapedAt": "2026-07-14T10:05:00.000Z",
"raw": null
}
Direct CDN media URLs can expire or require compatible session context later. Archive authorized media promptly if long-term retention is part of your workflow.
Reliability and charging behavior
- Input and cookie format are validated before the start event.
- The start charge is fatal; it is never silently ignored.
- A
profileevent is charged only after an authorized profile check produces media or confirms a valid no-media result. - Missing, private, authentication-rejected, rate-limited, deadline, and other failed profiles produce diagnostic rows without a
profileevent. - If every profile fails, the platform run fails instead of appearing green with paid error rows.
- Mixed runs preserve successful media and finish with
PARTIALinRUN_SUMMARY. - Bounded retries use profile-specific proxy sessions, exponential backoff, and
Retry-Afterwhen Instagram supplies it. - Highlight items are requested in bounded batches; repeated media IDs are removed.
- A safe work deadline leaves time to persist rows and
RUN_SUMMARYbefore the platform timeout.
API usage
JavaScript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/instagram-stories-highlights-scraper').call({
targets: ['natgeo'],
instagramCookies: process.env.INSTAGRAM_COOKIE,
includeStories: true,
includeHighlights: true,
maxHighlightsPerProfile: 5,
includeRaw: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/instagram-stories-highlights-scraper').call(run_input={
'targets': ['natgeo'],
'instagramCookies': os.environ['INSTAGRAM_COOKIE'],
'includeStories': True,
'includeHighlights': True,
'maxHighlightsPerProfile': 5,
'includeRaw': False,
})
print(client.dataset(run['defaultDatasetId']).list_items().items)
cURL
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~instagram-stories-highlights-scraper/runs?token=YOUR_APIFY_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"targets":["natgeo"],"instagramCookies":"sessionid=YOUR_AUTHORIZED_SESSION_ID","includeStories":true,"includeHighlights":true}'
Keep cookies in environment variables or secret inputs rather than source code or shell history.
MCP and AI agents
Use the Actor through the Apify MCP server:
https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper
Add it to Claude Code:
claude mcp add apify-instagram-stories 'https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper'
Example MCP JSON configuration:
{
"mcpServers": {
"apify-instagram-stories": {
"url": "https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper"
}
}
}
Example prompts:
- “Using my secret Instagram session input, export the accessible Stories from these three public brand profiles.”
- “Collect the first five Highlights for this profile and list external Story links and mentions.”
- “Return media posted since yesterday and summarize music and sticker usage.”
Support
If a run behaves unexpectedly, open an Actor issue with:
- The run ID or run URL.
- The input JSON with
instagramCookies, proxy URLs, and all secrets removed. - The expected output and actual output returned by the dataset.
- An example reproducible public URL, when possible.
Never post a session cookie. RUN_SUMMARY is designed to show whether the problem was input validation, an expired/rejected session, a private/missing profile, source response change, rate limit, partial source failure, or deadline.
Privacy and data handling
Use this Actor only for content your session is authorized to view and for a lawful purpose. Inputs and outputs remain in your Apify account storage according to your settings. Requests go to Instagram and, when enabled, through Apify Proxy; FetchCat does not send them to advertising networks, data brokers, or model-training services.