# Instagram Story Scraper | Stories & Highlights (`silentflow/instagram-story-scraper`) Actor

Extract Instagram stories and highlights from any public account: image and video links, exact posting time, expiry, swipe-up links and mentions, plus followers, following, posts, bio and website on every row. Track competitors, creators and news accounts daily with no login or account needed.

- **URL**: https://apify.com/silentflow/instagram-story-scraper.md
- **Developed by:** [SilentFlow](https://apify.com/silentflow) (community)
- **Categories:** Social media, Marketing
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.82 / 1,000 stories

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Story Scraper

**Every active story and every highlight of a public Instagram account, as a table: image and video links, exact posting time, expiry, swipe-up link, mentions, and the account's followers on each row.** Three news accounts, 43 stories, in 24 seconds. No login.

### How it works

![How it works](https://api.apify.com/v2/key-value-stores/YXm81xySHg6uRkewS/records/instagram-story-scraper-how-it-works-v1.png)

1. **You paste one or more accounts, or story links.** A username, an `@handle` or a profile link all name an account; a story link names one precise story.
2. **Each account is read once.** Its active stories come back in one call. If you ask for highlights, each album pinned on the profile is opened, newest first, up to the cap you set.
3. **One row comes back per story or highlight item.** 26 fields: the media with its links and exact time, and the account it belongs to with followers, name, bio and website. Ready for a spreadsheet, a database or an AI pipeline.

### ✨ Why teams choose this over other Instagram story scrapers

Taking screenshots of competitors' stories every morning before they vanish? Asked by a client to prove that a sponsored story went live at the right time with the right link? Getting back 150 raw keys per story and a unix timestamp when all you wanted was a date and a follower count?

- 📊 **20 fields filled on every row, not 11.** The other flat story scraper on the Store fills 11 keys per row; the most used ones return the raw Instagram object with 150 nested keys and unix timestamps. Here every story row carries 20 filled columns, measured on the default run of 22 September 2026 (43 rows, 21 columns filled on the majority of rows, the swipe-up `link` on 25 of them). No other story scraper puts `followersCount`, `followingCount`, `postsCount`, `biography` and `externalUrl` on the row.
- 👤 **The account on every row.** Followers, following, posts, name, bio, website, verified badge and avatar come with each story. One dataset answers both "what did they post" and "how big are they", with no second scraper to join.
- ⏰ **Exact time and expiry, in a format that sorts.** `takenAt` and `expiringAt` are RFC 3339 (`2026-09-21T22:07:02Z`), not `1758492422`. Sort a day of stories, prove a posting window, schedule the next run before anything expires.
- 🔗 **Accounts or precise story links.** Name an account by username, `@handle` or profile link, or paste the link of one story (`instagram.com/stories/cnn/3992904485714001336/`) and get exactly that story with its account's figures, to prove a sponsored story went live. The most used scraper of the niche accepts plain usernames only, and no field here is required: accounts, links or both.
- 🎞️ **Stories and highlights, chosen per run.** Read what is live now, the permanent albums pinned on the profile, or both, with a cap on albums. The two most used story scrapers read stories only; highlights here return rows even at 3 a.m. when nothing is live.
- 🖼️ **Direct media links and a permalink.** `imageUrl` for photos and posters, `videoUrl` for the mp4 of video stories, `thumbnailUrl` for a preview, and a stable `url` per row. Download what you want to keep.
- 🧹 **No error rows.** One row is one real story or highlight item. An unknown or private account produces no row and a clear message on the run, where other scrapers write an error item into your export. Unknown values are `null`, never an empty string, and no item appears twice.
- 🔑 **No login, no account to connect.** Public accounts only. Paste a username and press Start.

### 🎯 What you can do with Instagram story data

| Team | What they build |
|------|-----------------|
| Influencer marketing | Proof of delivery for a paid story: the row shows when it went live, the link it carried and the media, taken by a schedule before it expired |
| Competitive research | A daily archive of every story a list of rival brands posted, with links, mentions and media, searchable months later |
| Social media agencies | A morning digest of what each client's competitors pushed overnight, ready for Slack or a spreadsheet |
| Affiliate and e-commerce | A tracker of the swipe-up links and promo codes creators post in stories, with the UTM tags as they appear |
| Newsrooms and PR | A timeline of the stories a public figure or a news account published around an event, with exact times |
| Research and archives | A dataset of a brand's highlight albums, item by item, with posting dates that span years |
| Creator platforms | A vetting card per creator: followers, posting cadence in stories, share of video versus image, links pushed |

### 📥 Input parameters

#### Essentials

| Field | Type | Description |
|-------|------|-------------|
| `usernames` | array | Public accounts to read, one per line. Accepts a username (`cnn`), a handle (`@cnn`) or a profile link (`https://www.instagram.com/cnn/`). |
| `startUrls` | array | Links of precise stories (`https://www.instagram.com/stories/cnn/3992904485714001336/`): each gives exactly that story while it is live (24 hours). A profile link here reads the whole account. Highlight links do not name their account: add the account and choose highlights instead. Fill `usernames`, `startUrls` or both. |
| `maxItems` | integer, default `100` | Maximum rows for the whole run, stories and highlight items together. |

#### 🎞️ Content

| Field | Type | Description |
|-------|------|-------------|
| `contentType` | string, default `stories` | `stories` reads what the account posted in the last 24 hours, one call per account. `highlights` reads the permanent albums pinned on the profile, one call per album. `both` reads the two. |
| `maxHighlights` | integer, default `5` | How many highlight albums to open per account, newest first. Each album returns all its items. Ignored when `contentType` is `stories`. |

#### ⚙️ Advanced

| Field | Type | Description |
|-------|------|-------------|
| `debugMode` | boolean, default `false` | Adds detailed lines to the run log. Leave it off for normal runs. |

### 📊 Output data

Each row is one story or one highlight item. An active story of a news account looks like this (long media links shortened here):

```json
{
  "id": "3989588439640364857_217723373",
  "url": "https://www.instagram.com/stories/cnn/3989588439640364857/",
  "type": "story",
  "mediaType": "image",
  "highlightId": null,
  "highlightTitle": null,
  "link": "https://www.cnn.com/2026/09/19/style/cfda-fashion-boss-resigns-kolb-protesters-hnk-intl?utm_medium=social&utm_source=igstoryCNN",
  "mentions": [],
  "username": "cnn",
  "userId": "217723373",
  "fullName": "CNN",
  "biography": "Asking the hard questions and bringing unique perspective from across the globe. This is CNN.",
  "externalUrl": "http://cnn.com/linkinbio",
  "isVerified": true,
  "followersCount": 23592848,
  "followingCount": 323,
  "postsCount": 29599,
  "profilePicUrl": "https://scontent-lga3-2.cdninstagram.com/v/t51.2885-19/353448964_228072746694866_3965541026640463359_n.jpg?…",
  "takenAt": "2026-09-19T11:07:04Z",
  "expiringAt": "2026-09-20T11:07:04Z",
  "highlightCreatedAt": null,
  "imageUrl": "https://scontent-lga3-2.cdninstagram.com/v/t51.82787-15/818122990_18633735430059374_6730580538173429432_n.jpg?…",
  "videoUrl": null,
  "thumbnailUrl": "https://scontent-lga3-2.cdninstagram.com/v/t51.82787-15/818122990_18633735430059374_6730580538173429432_n.jpg?…",
  "input": "cnn",
  "scrapedAt": "2026-09-20T03:38:17Z"
}
```

A video item of a highlight album keeps the same 26 columns. It carries the mp4 in `videoUrl`, its poster in `imageUrl`, the album in `highlightId` and `highlightTitle`, and no `expiringAt` since highlights do not expire (account block shortened here):

```json
{
  "id": "3797974848153407573_217723373",
  "url": "https://www.instagram.com/s/aGlnaGxpZ2h0OjE4NTQ3NjI4MzIwMDE2NTQy?story_media_id=3797974848153407573",
  "type": "highlight",
  "mediaType": "video",
  "highlightId": "18547628320016542",
  "highlightTitle": "🎇",
  "link": null,
  "mentions": [],
  "username": "cnn",
  "userId": "217723373",
  "fullName": "CNN",
  "followersCount": 23592848,
  "takenAt": "2025-12-29T02:05:04Z",
  "expiringAt": null,
  "highlightCreatedAt": "2025-12-29T02:06:51Z",
  "imageUrl": "https://scontent-lga3-2.cdninstagram.com/v/t51.71878-15/…jpg?…",
  "videoUrl": "https://scontent-lga3-2.cdninstagram.com/o1/v/t2/f2/m78/…mp4?…",
  "thumbnailUrl": "https://scontent-lga3-2.cdninstagram.com/v/t51.71878-15/…jpg?…",
  "input": "https://www.instagram.com/cnn/",
  "scrapedAt": "2026-09-20T03:47:33Z"
}
```

### 🗂️ Data fields

26 fields per row: 4 identity, 4 content, 10 account, 3 time, 3 media, 2 meta. `mentions` is the only list, the usernames tagged in the story.

| Group | Fields |
|-------|--------|
| Identity | `id` (Instagram media id), `url` (permalink), `type` (`story` or `highlight`), `mediaType` (`image` or `video`) |
| Content | `highlightId`, `highlightTitle`, `link` (the swipe-up link), `mentions` |
| Account | `username`, `userId`, `fullName`, `biography`, `externalUrl`, `isVerified`, `followersCount`, `followingCount`, `postsCount`, `profilePicUrl` |
| Time | `takenAt` (RFC 3339, UTC), `expiringAt` (stories only, 24 hours after `takenAt`), `highlightCreatedAt` (highlight items only) |
| Media | `imageUrl` (the photo, or the poster of a video), `videoUrl` (mp4, videos only), `thumbnailUrl` |
| Meta | `input` (the account as you typed it), `scrapedAt` (RFC 3339, UTC) |

Good to know when you store the data:

- `id` is Instagram's own media id and never changes. `url` is built from it: the story permalink for a story, the share link of the album item for a highlight.
- `takenAt` is the moment the story was posted. `expiringAt` is when Instagram removes it from the profile. A highlight item keeps its original `takenAt`, which can be years old, and `highlightCreatedAt` tells when the album was created.
- `imageUrl`, `videoUrl`, `thumbnailUrl` and `profilePicUrl` point to Instagram's own media servers. They stay valid for a few days, then Instagram rotates them: download the files you want to keep, `url` stays.
- `link` is set only when the story carries a swipe-up link, `mentions` is an empty list when nobody is tagged.
- `followersCount`, `followingCount` and `postsCount` are the numbers shown on the profile at run time.
- The account block is identical on every row of an account, so the first row of each `username` is the account's profile.

### 🚀 Examples

#### Get the active stories of three news accounts

```json
{
  "usernames": ["cnn", "bbcnews", "skynews"]
}
```

#### Watch a list of competitors every morning

Put this on a daily schedule. Each run returns what is live at that moment, with time, link and media.

```json
{
  "usernames": ["@nike", "@adidas", "@puma", "@newbalance"],
  "maxItems": 200
}
```

#### Export the highlight albums of a brand

```json
{
  "usernames": ["https://www.instagram.com/cnn/"],
  "contentType": "highlights",
  "maxHighlights": 10,
  "maxItems": 500
}
```

#### Read stories and the latest album together

```json
{
  "usernames": ["foxnews", "skynews"],
  "contentType": "both",
  "maxHighlights": 1,
  "maxItems": 100
}
```

#### Check that a sponsored story is live on a creator's account

```json
{
  "usernames": ["https://www.instagram.com/bleacherreport/"],
  "maxItems": 20
}
```

#### Sample a large watchlist quickly

```json
{
  "usernames": ["cnn", "bbcnews", "skynews", "foxnews", "bleacherreport", "natgeo"],
  "maxItems": 30
}
```

### 🤖 Copy to your AI assistant

Paste this block into Claude, ChatGPT or Cursor to give it full context about this scraper:

```
You have access to the Instagram Story Scraper on Apify: silentflow/instagram-story-scraper

Input schema:
- usernames (array of strings): Instagram usernames, @handles or profile links of public accounts
- startUrls (array of {url}): links of precise stories, each returning exactly that story while it is live; fill usernames, startUrls or both
- maxItems (integer, default 100): max rows for the whole run
- contentType (string, default "stories"): "stories" (last 24 hours), "highlights" (permanent albums) or "both"
- maxHighlights (integer, default 5): albums opened per account, newest first
- debugMode (boolean, default false)

Output, one row per story or highlight item (26 fields, null when unknown):
- id (string), url (string), type ("story" | "highlight"), mediaType ("image" | "video")
- highlightId (string), highlightTitle (string), link (string), mentions (string[])
- username, userId, fullName, biography, externalUrl, profilePicUrl (strings)
- isVerified (boolean), followersCount, followingCount, postsCount (integers)
- takenAt, expiringAt, highlightCreatedAt (RFC 3339 UTC)
- imageUrl, videoUrl, thumbnailUrl (strings, Instagram media links valid a few days)
- input (string), scrapedAt (RFC 3339 UTC)

Private accounts and unknown usernames return no row. No login needed. Use apify-client for Python or JavaScript.
```

### 💻 Integrations

#### Keep a daily archive of competitors' stories (Python)

```python
import csv
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("silentflow/instagram-story-scraper").call(run_input={
    "usernames": ["nike", "adidas", "puma"],
    "maxItems": 200,
})
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())

with open("stories-archive.csv", "a", newline="") as f:
    writer = csv.writer(f)
    for r in rows:
        writer.writerow([r["takenAt"], r["username"], r["mediaType"], r["link"], ",".join(r["mentions"]), r["url"], r["videoUrl"] or r["imageUrl"]])
print(f"{len(rows)} stories archived")
```

#### Alert Slack when a creator posts a story with a link (JavaScript)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('silentflow/instagram-story-scraper').call({
    usernames: ['bleacherreport', 'espn'],
    maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

for (const story of items.filter((s) => s.link)) {
    await fetch(process.env.SLACK_WEBHOOK_URL, {
        method: 'POST',
        body: JSON.stringify({ text: `@${story.username} posted a story at ${story.takenAt} linking to ${story.link}` }),
    });
}
```

#### Download the media of a highlight album (Python)

```python
import requests
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("silentflow/instagram-story-scraper").call(run_input={
    "usernames": ["cnn"],
    "contentType": "highlights",
    "maxHighlights": 1,
    "maxItems": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    media_url = item["videoUrl"] or item["imageUrl"]
    ext = "mp4" if item["videoUrl"] else "jpg"
    with open(f'{item["username"]}-{item["id"]}.{ext}', "wb") as f:
        f.write(requests.get(media_url, timeout=60).content)
```

### 📈 Performance

Measured on 22 September 2026 on real accounts.

| Run | Rows | Time |
|-----|------|------|
| 3 news accounts, active stories (the default input) | 43 | 24 seconds |
| 1 account by profile link, its 2 latest highlight albums | 28 | 23 seconds |
| 3 accounts, stories and 1 album each, one unknown account, capped at 25 | 25 | 25 seconds |
| 2 sports accounts by profile link, active stories | 13 | 42 seconds |
| 2 news accounts, capped at 5 | 5 | 12 seconds |

| Metric | Value |
|--------|-------|
| Fields per row | 26 |
| Calls per account | 1 for stories, plus 1 per highlight album |
| Time per call | about 10 seconds, the pace the source allows |
| Columns filled on the default run | all, except `link` and `mentions` when the story carries none, and the highlight columns on stories |
| Limit per run | no fixed limit: `maxItems` is yours to set |

### 💾 Data export

Every run stores its rows in a dataset you can download as JSON, CSV, Excel, XML or HTML from the Storage tab, or pull from the API:

```
https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=csv&token=YOUR_TOKEN
```

The dataset has two ready-made table views: **Stories** (account, type, media, highlight, posted, swipe-up link, story URL, image) and **Accounts** (account, name, followers, following, posts, verified, website, avatar). Schedules, webhooks and the Apify integrations (Google Sheets, Slack, Zapier, Make, n8n) work on top of the same dataset.

### 💡 Tips for best results

1. **Schedule twice a day for a complete archive.** Stories last 24 hours. A run every 12 hours sees every story at least once; `expiringAt` tells you how much margin you had.
2. **Start with accounts that post daily.** News and sports accounts have stories around the clock. A brand that posts twice a week returns no story row on most runs, which is normal: switch to `both` to always get rows.
3. **Use `highlights` for permanent content.** Campaign albums, product albums and press albums stay on the profile for years. `maxHighlights` decides how many albums open, newest first.
4. **Download the media you want to keep.** Instagram rotates its media links after a few days. `url` stays valid, the files do not.
5. **Size `maxItems` for the whole run.** Ten accounts with about 8 stories each need `maxItems: 100`. With highlights, count up to 100 items per album.
6. **Group rows by `username` for account reports.** The account block is identical on every row of an account.

### ❓ FAQ

**What does this scraper extract?**
The active stories and the highlight albums of public Instagram accounts, one row per item, with 26 fields: the media (type, image, video, thumbnail, permalink), its exact posting time and expiry, the swipe-up link and mentions, the album it belongs to, and the account (name, bio, website, verified badge, followers, following, posts, avatar).

**What can I type in the accounts field?**
A username (`cnn`), a handle (`@cnn`), a profile link in any form (`https://www.instagram.com/cnn/`, `instagram.com/cnn`), or a story link (`instagram.com/stories/cnn/…`). A link to a post or a reel is skipped and named in the run log.

**Do I need an Instagram account?**
No. The scraper reads public accounts. There is no login, no key and no session to refresh.

**Why does an account return no story?**
Stories last 24 hours. If the account posted nothing in that window, there is nothing to read, and the run log says so. Run again later, put the run on a schedule, or set `contentType` to `both` to get the highlight albums as well.

**What about private accounts?**
Their stories are not public, so the scraper skips them, names them in the run log, and writes no row. Your dataset never contains error rows.

**How fresh is the data?**
Live. Every run reads the accounts at run time. `scrapedAt` tells you when each row was read, `takenAt` when the story was posted.

**Are the media links permanent?**
`url` is permanent. `imageUrl`, `videoUrl`, `thumbnailUrl` and `profilePicUrl` are links to Instagram's media servers and stay valid for a few days. Download the files you want to keep.

**Can I scrape many accounts in one run?**
Yes. List as many accounts as you need. An account named twice is read once, and no item is delivered twice in a run. Each account takes about ten seconds, plus about ten seconds per highlight album.

**How do highlights work?**
Highlights are the albums pinned under the bio of a profile. With `contentType` set to `highlights` or `both`, the scraper opens up to `maxHighlights` albums, newest first, and returns every item of each album with the album's id, title and creation date.

**Does it get story views, replies or the viewers list?**
No. Those numbers are only visible to the account owner. The scraper returns what a visitor of the profile can see.

**Is there a limit on the number of rows?**
No fixed limit. `maxItems` caps the whole run and you choose it.

**Can I get the text written on a story?**
Not as a field: Instagram does not publish the text of stickers and captions. You get the image or video, which you can pass to an OCR or vision model.

### ⚖️ Legal

This Actor extracts publicly available data from Instagram. It does not bypass any login, paywall or CAPTCHA, and it only reads public accounts. Users are responsible for complying with Instagram's terms of service and with applicable data protection laws (GDPR, CCPA, and PIPL where relevant). The output contains account information that account owners publish themselves (username, name, bio, website, follower counts, avatar); when you process it as personal data, handle it accordingly. The data returned is informational; verify accuracy for regulated use cases.

### 🔗 Related scrapers

- [Instagram Engagement Scraper](https://apify.com/silentflow/instagram-engagement-scraper): likes and comments behind Instagram posts.
- [TikTok Scraper](https://apify.com/silentflow/tiktok-scraper): videos and profiles from TikTok.
- [Youtube Channel Scraper](https://apify.com/silentflow/youtube-channel-scraper): every video of a channel with exact dates, views and likes.
- [Facebook Search Scraper](https://apify.com/silentflow/facebook-search-scraper): posts, pages and videos from Facebook search.

### 📬 Support

Need something this scraper does not do yet? We ship features fast.

- Feature requests go straight to our backlog
- Enterprise needs? We do custom integrations and high-volume plans
- Pricing details live on the Monetization tab of the actor page

Response time: usually under 24 hours.

Check out our other scrapers: [silentflow on Apify](https://apify.com/silentflow)

# Actor input Schema

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

The public accounts to read, one per line. Paste a username (<code>cnn</code>), a handle (<code>@cnn</code>) or a profile link (<code>https://www.instagram.com/cnn/</code>). Stories live 24 hours, so an account that posted nothing today returns no story row: news and sports accounts post around the clock and are a safe first test. Private accounts are skipped.

## `startUrls` (type: `array`):

Links of precise stories, as Instagram shares them (<code>https://www.instagram.com/stories/cnn/3989588439640364857/</code>): each link gives exactly that story, with its account's figures, while it is still live (24 hours). A profile link here reads the whole account like a username. Highlight links do not name their account: add the account above and choose highlights instead.

## `maxItems` (type: `integer`):

How many rows to save for the whole run, stories and highlight items together. A busy news account has 5 to 15 active stories at any time; a highlight holds up to 100 items.

## `contentType` (type: `string`):

<b>Stories</b> are what the account posted in the last 24 hours, one call per account, the fastest option. <b>Highlights</b> are the permanent story albums pinned on the profile, one extra call per album, and always return rows even when nothing is live. <b>Both</b> reads the two.

## `maxHighlights` (type: `integer`):

How many highlight albums to open on each account, newest first, when the content type includes highlights. Each album is one extra call and returns all its items (often 10 to 100). Ignored for stories only.

## `debugMode` (type: `boolean`):

Adds detailed lines to the run log. Leave it off for normal runs.

## Actor input object example

```json
{
  "usernames": [
    "cnn",
    "bbcnews",
    "skynews"
  ],
  "maxItems": 100,
  "contentType": "stories",
  "maxHighlights": 5,
  "debugMode": false
}
```

# Actor output Schema

## `stories` (type: `string`):

Every row: id, url, type, mediaType, highlightId, highlightTitle, link, mentions, username, userId, fullName, biography, externalUrl, isVerified, followersCount, followingCount, postsCount, profilePicUrl, takenAt, expiringAt, highlightCreatedAt, imageUrl, videoUrl, thumbnailUrl, input, scrapedAt.

## `accounts` (type: `string`):

The same rows seen by account: name, followers, following, posts, verified badge, website and avatar.

# 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": [
        "cnn",
        "bbcnews",
        "skynews"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("silentflow/instagram-story-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 = { "usernames": [
        "cnn",
        "bbcnews",
        "skynews",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("silentflow/instagram-story-scraper").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": [
    "cnn",
    "bbcnews",
    "skynews"
  ]
}' |
apify call silentflow/instagram-story-scraper --silent --output-dataset

```

## MCP server setup

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

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/JKVy5Y2JdZp3cJx9V/builds/hEbQwQNyjc9itVQ9Z/openapi.json
