# Instagram Stories Downloader (`khadinakbar/instagram-stories-downloader`) Actor

Download active Instagram stories (24h tray) and highlight reels for any public profile. Returns original-resolution direct media URLs, captions, music, mentions and expiry timestamps. No Instagram login or cookies required. MCP-ready. $0.01 per profile.

- **URL**: https://apify.com/khadinakbar/instagram-stories-downloader.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, Videos, MCP servers
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 profile scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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 Downloader - Stories & Highlights

Download active Instagram stories (the 24-hour tray) and highlight reels from any public profile. The actor returns one record per story or highlight item with a direct, original-resolution media URL plus caption, mentions, link stickers, music, posting time and story expiry — before the story disappears. No Instagram login, no cookies, no API key from you.

Built for social media managers, journalists, archivists and AI agents that need to preserve or analyze ephemeral Instagram content on a schedule.

### What it returns

One dataset row per media item, flat and MCP-friendly:

| Field | Meaning |
|---|---|
| `mediaUrl` | Direct original-resolution URL (progressive MP4 for video, full-size JPEG for photo) |
| `imageUrl` | Highest-resolution still image |
| `itemType` | `story`, `highlight` (cover row) or `highlight-item` (media inside an expanded highlight) |
| `username` / `highlightId` / `highlightTitle` | Profile and highlight context |
| `takenAt` / `expiresAt` | ISO timestamps — stories expire ~24h after posting, highlights are permanent |
| `caption`, `mentions[]`, `linkUrls[]` | Story text, tagged handles, outbound link stickers |
| `musicTitle` / `musicArtist` | Attached audio when present |
| `sourceUrl` / `provider` / `scrapedAt` | Canonical Instagram URL, data provider, collection time |

Media URLs are Instagram CDN links and expire after a few days — download or mirror the files promptly for permanent archives.

### When to use it

- Archiving your brand's or a competitor's stories before they vanish (schedule the actor hourly or daily).
- Monitoring campaigns, announcements or breaking-news stories across a watchlist of public profiles.
- Collecting highlight reels with every photo and video inside them for content audits.
- Agent workflows that need structured story data (media + metadata) as JSON instead of screenshots.

For Instagram posts, reels, profile stats or followers, start with the dedicated actors listed under Related actors. This actor reads public profiles only; private accounts and close-friends stories stay outside its public-data scope.

### Workflow: from watchlist to archived stories

A typical workflow starts with a watchlist of public handles. You provide the list once, schedule the run, and then every execution exports the current story tray to your dataset: first the actor resolves each handle, then it collects every active item with direct media URLs, and finally you download the media files or feed the JSON into your archive, dashboard or AI analysis. Because stories expire about 24 hours after posting, scheduled runs preserve each day's tray before it disappears; highlights, by contrast, are permanent and one expansion pass covers them.

### Input

```json
{
  "usernames": ["bbcnews", "https://www.instagram.com/nasa/"],
  "includeStories": true,
  "includeHighlights": false,
  "expandHighlightItems": false,
  "maxHighlightsPerUser": 5,
  "maxItemsPerRun": 200
}
```

- `usernames` (required): bare handles, `@handles`, profile URLs or stories URLs. Up to 100 profiles per run, deduplicated.
- `includeStories` (default `true`): the active 24h story tray.
- `includeHighlights` (default `false`): highlight covers with titles.
- `expandHighlightItems` (default `false`): download every item inside each highlight (billed per highlight, bounded by `maxHighlightsPerUser`).
- `maxItemsPerRun` (default 200): hard row cap; the run stops gracefully with a `PARTIAL` outcome when reached.

### Output example

```json
{
  "itemId": "3867341342972145022",
  "itemType": "story",
  "username": "bbcnews",
  "highlightId": null,
  "highlightTitle": null,
  "mediaType": "video",
  "mediaUrl": "https://scontent.cdninstagram.com/o1/v/t16/f2/m69/example.mp4",
  "imageUrl": "https://scontent.cdninstagram.com/v/t51/story.jpg",
  "width": 1080,
  "height": 1920,
  "durationSeconds": 14.8,
  "takenAt": "2026-08-17T09:12:00.000Z",
  "expiresAt": "2026-08-18T09:12:00.000Z",
  "caption": "Launch coverage tonight",
  "mentions": ["nasa"],
  "linkUrls": ["https://www.bbc.com/news"],
  "musicTitle": null,
  "musicArtist": null,
  "sourceUrl": "https://www.instagram.com/stories/bbcnews/3867341342972145022/",
  "provider": "scrapecreators",
  "scrapedAt": "2026-08-17T12:00:00.000Z"
}
```

Terminal `OUTPUT` and `RUN_SUMMARY` records in the key-value store carry the run outcome (`COMPLETE`, `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, `UPSTREAM_FAILED`, `CONFIG_ERROR`), per-profile statuses, provider telemetry and billing counts.

### Pricing

Pay per event plus platform usage. Event charges:

| Event | Price | When |
|---|---|---|
| Actor start | $0.00005 | Once per valid run |
| Profile scraped | $0.01 | Per profile whose tray/highlights were read (all active story items included) |
| Highlight expanded | $0.005 | Per highlight whose items were downloaded (only when `expandHighlightItems` is on) |

A one-profile stories run costs **$0.01005** in events; Apify bills the small compute usage separately. A 10-profile watchlist with default settings costs about $0.10 per run. Current prices are always shown on the actor's Pricing tab.

### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~instagram-stories-downloader/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"usernames":["bbcnews"],"includeStories":true,"includeHighlights":false,"maxItemsPerRun":50}'
```

Then read the dataset: `https://api.apify.com/v2/datasets/{DATASET_ID}/items?clean=true`.

### Using with AI agents

This actor is MCP-ready through `mcp.apify.com`. Agent prompt card:

> Use instagram-stories-downloader when you need current Instagram stories or highlight media for public profiles. Pass usernames (handles or profile URLs, up to 100 per run). It returns one JSON record per item with direct media URLs, captions, mentions, links, music, and expiry timestamps. For posts, reels or follower lists, pair this actor with the dedicated Instagram siblings. Cost: $0.01 per profile + $0.00005 start; $0.005 per expanded highlight.

### Best results and practical guidance

- Provide public profiles: active stories come from a managed public-data provider (ScrapeCreators) with a second provider (SociaVault) as automatic fallback for profile resolution and highlights, so the highlights route keeps working even when the primary route degrades.
- Profiles with no active stories return zero rows and a `VALID_EMPTY` outcome — a charged profile-scraped event still applies because the lookup was performed.
- When the upstream route is down for every requested profile, the actor reports `UPSTREAM_FAILED` honestly; partial outcomes keep every collected row with a `PARTIAL` result.
- Rate-limited provider calls are retried with backoff, and a circuit breaker ends the pass early to protect your budget; item and highlight caps bound every run's spend upfront.
- Schedule runs hourly or daily for the freshest trays, and download the current media files promptly — CDN links age out after a few days even though the metadata rows persist.

### Related actors

- [Instagram Video Downloader](https://apify.com/khadinakbar/instagram-video-downloader) — single reels/posts/IGTV videos by URL; use it when you have a specific post link rather than a profile watchlist.
- [Instagram Profile Scraper](https://apify.com/khadinakbar/instagram-profile-scraper) — profile stats, bio and recent posts; pair it with this actor when a watchlist also needs profile context.
- [Instagram Posts Scraper](https://apify.com/khadinakbar/instagram-posts-scraper) — permanent feed posts and carousels; stories this actor collects are the ephemeral complement.
- [Facebook Video Downloader](https://apify.com/khadinakbar/facebook-video-downloader) — the same direct-media-link workflow for public Facebook videos and Reels.

### Builder's note

The active-stories route turned out to be the hard part: I found that most managed providers expose highlight reels only and keep the live 24h tray hidden. In my testing I probed ScrapeCreators, SociaVault and TikHub live before writing any code, and I learned that only ScrapeCreators exposes a working tray endpoint — and it needs the numeric profile ID, so the actor looks up each handle first. I also found raw control characters inside provider captions that break strict JSON parsers; the actor sanitizes them before parsing. Highlights are dual-provider, stories are single-provider by necessity, and this README reflects that asymmetry openly.

### Legal

This actor retrieves publicly available Instagram content through managed public-data providers. You are responsible for complying with Instagram's Terms of Service, copyright, and local laws when storing or reusing downloaded media. It does not access private accounts, encrypted media or login-only content.

# Actor input Schema

## `usernames` (type: `array`):

List of public Instagram profiles to download stories from. Each entry can be a bare handle (e.g. "bbcnews"), "@bbcnews", a profile URL ("https://www.instagram.com/bbcnews/"), or a stories URL ("https://www.instagram.com/stories/bbcnews/"). Duplicates are removed and at most 100 profiles are processed per run. NOT post/reel URLs — use the Instagram Video Downloader actor for those.

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

Fetch the profile's currently active stories before they expire. Every item gets a direct original-resolution media URL plus caption, mentions, music and expiry timestamp. Turn off to collect only highlights.

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

Also fetch the profile's highlight reels. With expandHighlightItems off you get one row per highlight with its cover image, title and link; turn expansion on to download every media item inside each highlight.

## `expandHighlightItems` (type: `boolean`):

Download every media item inside each highlight reel (photos and videos), not just the cover. Each expanded highlight is charged as a highlight-expanded event. Requires includeHighlights to be true.

## `maxHighlightsPerUser` (type: `integer`):

Upper bound on how many highlight reels are fetched per profile. Between 1 and 50; default 5. Keeps provider calls and the highlight-expanded charges predictable for profiles with dozens of highlights.

## `maxItemsPerRun` (type: `integer`):

Hard cap on total dataset rows (story items, highlight rows) pushed in one run. Once reached the run stops gracefully with a PARTIAL outcome. Raise it for large batches; lower it to bound spend on trial runs.

## Actor input object example

```json
{
  "usernames": [
    "bbcnews",
    "https://www.instagram.com/nasa/"
  ],
  "includeStories": true,
  "includeHighlights": false,
  "expandHighlightItems": false,
  "maxHighlightsPerUser": 5,
  "maxItemsPerRun": 200
}
```

# Actor output Schema

## `items` (type: `string`):

Normalized Instagram story and highlight records with direct media URLs, captions, mentions, music, and expiry.

## `output` (type: `string`):

Stable terminal summary for agents and API consumers.

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

Detailed run diagnostics, per-profile statuses, and warnings.

# 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 = {
    "usernames": [
        "bbcnews"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/instagram-stories-downloader").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 = { "usernames": ["bbcnews"] }

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

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

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

```

## CLI example

```bash
echo '{
  "usernames": [
    "bbcnews"
  ]
}' |
apify call khadinakbar/instagram-stories-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/instagram-stories-downloader"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dqwQiwOBVQPvnYUih/builds/YgGuJonBU8TVjv3Cs/openapi.json
