# Instagram Stories & Highlights Scraper - Media Export (`fetch_cat/instagram-stories-highlights-scraper`) Actor

Export accessible Instagram Stories and Highlights with direct media URLs, timestamps, captions, links, mentions, hashtags, stickers, music, profile metrics, and Highlight context. Use usernames, profile URLs, date filters, CSV, Excel, JSON, API, or MCP. Authorized session cookie required.

- **URL**: https://apify.com/fetch\_cat/instagram-stories-highlights-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Videos, Lead generation
- **Stats:** 10 total users, 2 monthly users, 84.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Instagram Stories & Highlights Scraper

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.

### Ready-to-run examples

These examples prefill public profiles and limits. Add your authorized Instagram session cookie before running them.

- [Check Media Brand Instagram Stories and Highlights](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-media-brand-stories-highlights)
- [Export Retail Brand Instagram Highlights](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-retail-brand-highlights-export)
- [Check Tech Company Instagram Stories](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-tech-company-stories-check)
- [Scrape Football Club Instagram Highlights](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-football-club-highlights)
- [Export Music Artist Instagram Highlights](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-music-artist-highlights-export)
- [Monitor Automotive Brand Instagram Highlights](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/examples/instagram-automotive-highlights-monitor)

### 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 `sinceDate` and 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. |
| 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

```json
{
  "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 fields

Each media item remains a flat dataset row for backward compatibility. Existing fields are preserved; new fields are additive.

| Field group | Fields |
| --- | --- |
| Row and profile | `kind`, `username`, `profileUrl`, `profileId`, `fullName`, `biography`, `isVerified`, `isPrivate`, `profilePicUrl`, `followerCount`, `followingCount`, `postsCount`, `businessCategory`, `externalUrl` |
| Status and provenance | `status`, `errorMessage`, `sourceUrl`, `stableId`, `scrapedAt` |
| Media | `mediaId`, `mediaType`, `mediaUrl`, `thumbnailUrl`, `imageUrls`, `videoUrls`, `caption`, `accessibilityCaption`, `takenAt`, `expiringAt`, `durationSeconds`, `width`, `height`, `hasAudio` |
| Story signals | `linkUrls`, `mentions`, `hashtags`, `stickerTypes`, `musicTitle`, `musicArtist`, `musicId` |
| Highlight context | `highlightId`, `highlightTitle`, `highlightCoverUrl`, `highlightIndex`, `highlightItemIndex`, `highlightItemCount`, `ownerId` |
| Source object | `raw` |

### Output example

```json
{
  "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 `profile` event 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 `profile` event.
- If every profile fails, the platform run fails instead of appearing green with paid error rows.
- Mixed runs preserve successful media and finish with `PARTIAL` in `RUN_SUMMARY`.
- Bounded retries use profile-specific proxy sessions, exponential backoff, and `Retry-After` when 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_SUMMARY` before the platform timeout.

### Pricing

This Actor uses Apify pay-per-event pricing. It charges a `start` event once a run begins after valid input is accepted, and a `profile` event for each successfully authorized profile check, including verified no-media results. Failed, private, missing, or authentication-rejected profiles do not receive the `profile` event.

See the live [Apify Pricing tab](https://apify.com/fetch_cat/instagram-stories-highlights-scraper/pricing) for current rates. Apify can separately charge platform usage for compute, storage, proxies, or data transfer. Your run and Pricing tabs show the exact amount for your account.

### API usage

#### JavaScript

```js
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

```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

```bash
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:

```text
https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper
```

Add it to Claude Code:

```bash
claude mcp add apify-instagram-stories 'https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper'
```

Example MCP JSON configuration:

```json
{
  "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.”

### FAQ

#### Why is a session cookie required for public profiles?

Instagram’s current story/highlight interfaces require a logged-in session even when the target profile is public. Anonymous third-party claims do not change the requirements of the direct Instagram interface used by this Actor.

#### Why did the run fail instead of returning an `auth_required` success row?

If every profile is rejected, a failed run prevents authentication errors from masquerading as successful paid extraction. The dataset and `RUN_SUMMARY` still explain the failure; no `profile` event is charged for the rejected target.

#### Can it access a private profile?

No. The Actor explicitly rejects private profiles and does not use session follows to bypass this rule.

#### Why are some media fields empty?

Instagram varies fields by image/video, sticker type, region, account, experiment, and content age. The Actor preserves available variants and raw data when requested, but does not invent missing values.

#### How should I schedule active Story monitoring?

Run at least daily because active Stories expire after roughly 24 hours. Use `sinceDate` and `stableId` to filter and deduplicate downstream archives.

### Related Actors

- [Instagram Profile Posts Scraper](https://apify.com/fetch_cat/instagram-profile-posts-scraper) — export public post/Reel rows from profiles.
- [Threads Profile & Posts Scraper](https://apify.com/fetch_cat/threads-profile-posts-scraper) — collect public Threads profile posts.
- [TikTok Profile Scraper](https://apify.com/fetch_cat/tiktok-profile-scraper) — export public TikTok profile data.
- [YouTube Channel Videos Scraper](https://apify.com/fetch_cat/youtube-channel-videos-scraper) — collect public YouTube channel videos.
- [Facebook Pages Scraper](https://apify.com/fetch_cat/facebook-pages-scraper) — export public Facebook Page data.

### 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.

# Actor input Schema

## `targets` (type: `array`):

Instagram usernames, @handles, or exact profile URLs. Private profiles are not supported. Duplicate profiles run once.

## `maxProfiles` (type: `integer`):

Safety cap for unique profiles processed in one run.

## `includeStories` (type: `boolean`):

Collect currently active story items visible to the provided Instagram session.

## `includeHighlights` (type: `boolean`):

Collect highlight collections and their accessible saved story items.

## `maxHighlightsPerProfile` (type: `integer`):

Limit highlight collections per profile. Use 0 to skip highlight items while retaining the option for backward-compatible inputs.

## `maxItemsPerHighlight` (type: `integer`):

Limit saved story items exported from each highlight collection.

## `sinceDate` (type: `string`):

Optional ISO date or timestamp. Older story/highlight items are filtered after Instagram returns them.

## `saveProfileOnNoMedia` (type: `boolean`):

Save one profile\_status row when authorized requests succeed but no matching story/highlight media is available.

## `includeRaw` (type: `boolean`):

Preserve the source media object in raw. Enabled by default for backward compatibility; disable it for smaller datasets.

## `instagramCookies` (type: `string`):

Required at runtime: enter a sessionid value or full Cookie header from an Instagram session authorized to view the requested public content. Public examples intentionally omit it. It is used only for this run. Never share it in issues or logs.

## `proxyConfiguration` (type: `object`):

Apify Proxy settings. Residential or ISP routes are usually more reliable for Instagram. Retries use bounded profile-specific sessions.

## `retryCount` (type: `integer`):

Retries for rate limits, blocks, transient server errors, and network failures.

## `initialRetryDelayMillis` (type: `integer`):

Initial backoff; later retries increase the delay and honor Retry-After when present.

## `requestPacingMillis` (type: `integer`):

Pacing between successful requests to reduce session pressure.

## `runTimeSecs` (type: `integer`):

Stop before the platform timeout so saved media and RUN\_SUMMARY can be finalized.

## Actor input object example

```json
{
  "targets": [
    "instagram",
    "natgeo"
  ],
  "maxProfiles": 2,
  "includeStories": true,
  "includeHighlights": true,
  "maxHighlightsPerProfile": 10,
  "maxItemsPerHighlight": 20,
  "saveProfileOnNoMedia": true,
  "includeRaw": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "retryCount": 3,
  "initialRetryDelayMillis": 1000,
  "requestPacingMillis": 350,
  "runTimeSecs": 1680
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `media` (type: `string`):

No description

## `status` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "targets": [
        "instagram",
        "natgeo"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/instagram-stories-highlights-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "targets": [
        "instagram",
        "natgeo",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/instagram-stories-highlights-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "targets": [
    "instagram",
    "natgeo"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call fetch_cat/instagram-stories-highlights-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fetch_cat/instagram-stories-highlights-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/o4sIFxMU5ieEuFeoa/builds/UhA3o7AyyAWqwT3IO/openapi.json
