# Instagram Stories Scraper (`maximedupre/instagram-story-viewer`) Actor

Collect active Stories from public Instagram usernames, @handles, or full profile URLs without an Instagram login. Get one row per Story with source media links, owner details, timestamps, and optional Story context.

- **URL**: https://apify.com/maximedupre/instagram-story-viewer.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Videos, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.80 / 1,000 instagram stories

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

### 📸 See active Instagram Stories from public profiles

Instagram teams, creators, researchers, and developers can use this Instagram story viewer to collect active Stories from public accounts. The Actor saves one dataset row per Story with source-hosted media links, owner details, the posting time, and an expiration time when available, plus extra Story context when Instagram provides it. This gives you structured data to review, archive, or use in your own workflow without an Instagram login.

- View active Stories from a public Instagram account without an Instagram login with **[View Instagram Anonymously](https://apify.com/maximedupre/instagram-story-viewer/examples/view-instagram-anonymously)**.
- Review Story media and metadata from a public profile with **[Instagram Story Viewer Anonymous](https://apify.com/maximedupre/instagram-story-viewer/examples/instagram-story-viewer-anonymous)**.
- Collect Story rows from several public accounts with **[Instagram Stories Viewers Free](https://apify.com/maximedupre/instagram-story-viewer/examples/instagram-stories-viewers-free)**.
- Check whether a public account has active Stories with **[Anonymous Stories Viewer](https://apify.com/maximedupre/instagram-story-viewer/examples/anonymous-stories-viewer)**.
- Find a way to view a public Story without an Instagram login with **[How to View Someone's Instagram Story Without It Showing](https://apify.com/maximedupre/instagram-story-viewer/examples/how-to-view-someone-s-instagram-story-without-it-showing)**.

#### 🧾 Active Story rows

Each saved dataset row represents one active Instagram Story found for a submitted public account. A row includes a Story ID, an owner object, media with a source URL and available size variants, and the time the Story was posted. The row can also include an expiration time, audio status, mentions, stickers, and media shared inside the Story when Instagram provides those fields. Source-hosted media URLs can expire or change.

#### ▶️ Check accounts and collect Stories

**Run steps**

1. Add one or more public Instagram usernames, `@handles`, or full Instagram profile URLs.
2. Put one account value on each line. The prefilled `nasa` value is a valid starting point.
3. Start the run and open the `datasetItems` link to view the `overview` dataset.

The Actor saves each eligible Story as it finds it. If the same source Story appears again from another submitted account value, the first saved match is kept and later repeats are ignored. If one account has no active Stories or cannot be retrieved, the Actor continues with the other submitted accounts.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `instagramAccounts` | array of strings | Required. Adds one or more public Instagram usernames, `@handles`, or full Instagram profile URLs, with one value per line. Private accounts and login-only Stories are not supported. |

The list must contain at least one non-empty value. Use a username such as `nasa`, an `@handle` such as `@leomessi`, or a full profile URL such as `https://www.instagram.com/nasa/`.

**Example input**

This is the public input from the successful current-beta run for `nasa`:

```json
{
  "instagramAccounts": [
    "nasa"
  ]
}
```

#### 🧾 Output

**Output link**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetItems` | string | Opens the `overview` view of the run dataset with active Instagram Story rows. |

Every dataset row has one active Story shape. Optional fields are present when Instagram provides them.

**Dataset row fields**

| Field | Type | What it does |
| --- | --- | --- |
| `storyId` | string | Stable ID for the active Story. |
| `owner` | object | Account that published the Story. |
| `owner.username` | string | Username of the Story owner. |
| `owner.accountId` | string | Stable account ID of the Story owner. |
| `owner.profileImageUrl` | string, optional | Source profile image URL when available. |
| `owner.displayName` | string, optional | Display name of the Story owner when available. |
| `owner.isVerified` | boolean, optional | Whether the source marks the owner as verified. |
| `media` | object | Story media and its source links. |
| `media.type` | string | Media type, either `image` or `video`. |
| `media.url` | string | Main source URL for viewing or downloading the media. |
| `media.variants` | array of objects, optional | Other source versions of the media with their sizes. |
| `media.variants[].url` | string | Source URL for one media version. |
| `media.variants[].width` | integer | Width of one media version in pixels. |
| `media.variants[].height` | integer | Height of one media version in pixels. |
| `postedAt` | string | Source time when the Story was posted, in date-time format. |
| `expiresAt` | string, optional | Source expiration time for the Story when available. |
| `hasAudio` | boolean, optional | Whether the source says the Story has audio. |
| `mentions` | array of objects, optional | Accounts mentioned in the Story. |
| `mentions[].username` | string | Username of a mentioned account. |
| `mentions[].accountId` | string, optional | Stable ID of a mentioned account when available. |
| `mentions[].displayName` | string, optional | Display name of a mentioned account when available. |
| `mentions[].placement` | object, optional | Position of the mention in the Story when available. |
| `mentions[].placement.x` | number | Horizontal position from the source. |
| `mentions[].placement.y` | number | Vertical position from the source. |
| `mentions[].placement.width` | number, optional | Width of the mention from the source. |
| `mentions[].placement.height` | number, optional | Height of the mention from the source. |
| `mentions[].placement.rotation` | number, optional | Rotation of the mention from the source when available. |
| `stickers` | array of objects, optional | Stickers detected in the Story. |
| `stickers[].type` | string | Sticker type from the source. |
| `stickers[].text` | string, optional | Text shown by the sticker when available. |
| `stickers[].placement` | object, optional | Position of the sticker in the Story when available. |
| `stickers[].placement.x` | number | Horizontal position from the source. |
| `stickers[].placement.y` | number | Vertical position from the source. |
| `stickers[].placement.width` | number, optional | Width of the sticker from the source. |
| `stickers[].placement.height` | number, optional | Height of the sticker from the source. |
| `stickers[].placement.rotation` | number, optional | Rotation of the sticker from the source when available. |
| `sharedMedia` | array of objects, optional | Media shared inside the Story. |
| `sharedMedia[].id` | string | Stable ID of the shared media. |
| `sharedMedia[].mediaType` | string, optional | Type of the shared media when available. |
| `sharedMedia[].placement` | object, optional | Position of the shared media in the Story when available. |
| `sharedMedia[].placement.x` | number | Horizontal position from the source. |
| `sharedMedia[].placement.y` | number | Vertical position from the source. |
| `sharedMedia[].placement.width` | number, optional | Width of the shared media from the source. |
| `sharedMedia[].placement.height` | number, optional | Height of the shared media from the source. |
| `sharedMedia[].placement.rotation` | number, optional | Rotation of the shared media from the source when available. |

**Example row**

This genuine row is from the successful current-beta run for `nasa`. It is shortened because the source returned many media variants. The first variant is real, and the JSON string value `"..."` marks the remaining variants.

```json
{
  "storyId": "3977574916672105312_528817151",
  "owner": {
    "username": "nasa",
    "accountId": "528817151",
    "displayName": "NASA",
    "isVerified": true,
    "profileImageUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/29090066_159271188110124_1152068159029641216_n.jpg?stp=dst-jpg_s150x150_tt6&_nc_cat=1&ccb=7-5&_nc_sid=f7ccc5&efg=eyJ2ZW5jb2RlX3RhZyI6InByb2ZpbGVfcGljLnd3dy4xMDgwLkMzIn0%3D&_nc_ohc=HN7dW-2GxfIQ7kNvwEx8w7W&_nc_oc=AdrY1tDpeAwiXjAiTZvQTUNGbr-uqNBjmKvZHsvRa355NDm2GC6S97ONMBjnqurKErg&_nc_zt=24&_nc_ht=scontent.cdninstagram.com&_nc_ss=70689&oh=00_AQKqIub7VTk2pjDUNDhQHUIR33s6cKOOub_VVo3IE1T2ag&oe=6A9F8829"
  },
  "media": {
    "type": "image",
    "url": "https://scontent-ams2-1.cdninstagram.com/v/t51.82787-15/790879851_18643910530049152_4352367034286246463_n.jpg?stp=dst-jpg_e35_tt6&_nc_cat=1&ig_cache_key=Mzk3NzU3NDkxNjY3MjEwNTMxMg%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IlNUT1JZLnhwaWRzLjEyMDYuc2RyLnJlZ3VsYXJfcGhvdG8uQzMifQ%3D%3D&_nc_ohc=E8wXEei9x-UQ7kNvwFR1xdw&_nc_oc=Adpetu6Bobxo_IPipjXICgWhXK84PobPACw4CFgpr_OEsMweBVco6eCYHIx_EF6-sjA&_nc_zt=23&_nc_ht=scontent-ams2-1.cdninstagram.com&_nc_gid=FS5L5BLuYNrnEjRkLfo77Q&_nc_ss=736a8&oh=00_AQIfirr0ynGgtfIFS3_b0---ryEQv0nOcWqmgsSaiqKi3Q&oe=6A9F833B",
    "variants": [
      {
        "url": "https://scontent-ams2-1.cdninstagram.com/v/t51.82787-15/790879851_18643910530049152_4352367034286246463_n.jpg?stp=dst-jpg_e35_tt6&_nc_cat=1&ig_cache_key=Mzk3NzU3NDkxNjY3MjEwNTMxMg%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IlNUT1JZLnhwaWRzLjEyMDYuc2RyLnJlZ3VsYXJfcGhvdG8uQzMifQ%3D%3D&_nc_ohc=E8wXEei9x-UQ7kNvwFR1xdw&_nc_oc=Adpetu6Bobxo_IPipjXICgWhXK84PobPACw4CFgpr_OEsMweBVco6eCYHIx_EF6-sjA&_nc_zt=23&_nc_ht=scontent-ams2-1.cdninstagram.com&_nc_gid=FS5L5BLuYNrnEjRkLfo77Q&_nc_ss=736a8&oh=00_AQIfirr0ynGgtfIFS3_b0---ryEQv0nOcWqmgsSaiqKi3Q&oe=6A9F833B",
        "width": 1206,
        "height": 2144
      },
      "..."
    ]
  },
  "postedAt": "2026-09-02T21:17:50.000Z",
  "expiresAt": "2026-09-03T21:17:50.000Z",
  "sharedMedia": [
    {
      "id": "18028196120853919",
      "mediaType": "feed",
      "placement": {
        "x": 0.5,
        "y": 0.5,
        "width": 0.5,
        "height": 0.33022388059701,
        "rotation": 0
      }
    }
  ]
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. The charged event applies to each successfully retrieved active Instagram Story saved to the dataset. The current price is shown on the Pricing tab before you run.

#### 🔌 Integrations

Open the `datasetItems` link in Apify or read the `overview` dataset through the Apify API. Use the source-hosted media URLs from each row in your own workflow. These URLs may expire, so use or store them soon after the run.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens if one account has no active Stories?

No row is saved for that account, and the Actor continues with the other submitted accounts.

##### Can I enter a username, @handle, or full profile URL?

Yes. Add a bare username, an `@handle`, or a full Instagram profile URL. Put one value on each line.

##### Does the Actor need my Instagram login or API key?

No. It reads Stories from public accounts without an Instagram login or an Instagram API key.

##### Can it access private accounts or login-only Stories?

No. Private accounts and login-only Stories are outside the supported public-access boundary.

##### What does `expiresAt` tell me?

It is the source expiration time for the Story when Instagram provides it. The source-hosted media links may also expire or change.

##### What do the optional arrays contain?

`mentions` lists mentioned accounts and available placement data. `stickers` lists Story stickers and their available placement data. `sharedMedia` lists media shared inside the Story with source details when available.

##### Can I use this like an Instagram story viewer website?

This is an Apify Actor, not an interactive Instagram page. It returns structured dataset rows and direct source-hosted media URLs that you can open or download.

##### Can I use it for Reels, posts, or Story Highlights?

No. This Actor is for active Stories from public accounts. Posts, Reels, Story Highlights, and standalone profile scraping are outside this product.

##### Is the same Story saved more than once?

When the same source Story appears again from another submitted account value, the first eligible match saved is kept and later repeats are ignored.

### 📝 Changelog

**v0.0**

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~instagram-story-viewer/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Instagram Downloader API](https://apify.com/maximedupre/instagram-downloader-api) collects media links from known public Instagram posts, reels, and TV pages.
- [Instagram Profile Stats Scraper](https://apify.com/maximedupre/instagram-profile-stats-scraper) collects public profile counts, account flags, and profile details for known accounts.
- [TikTok Story Viewer](https://apify.com/maximedupre/tiktok-story-viewer) checks active public TikTok Stories from profile targets.
- [Snapchat Story Viewer](https://apify.com/maximedupre/snapchat-story-viewer) collects public Snapchat Stories and Highlights with source media links.
- [Instagram User Search](https://apify.com/maximedupre/instagram-user-search-scraper) finds public Instagram accounts by keyword so you can choose profiles to check.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `instagramAccounts` (type: `array`):

Add one public Instagram username, @handle, or full profile URL per line. Private accounts and login-only Stories are not supported.

## Actor input object example

```json
{
  "instagramAccounts": [
    "instagram"
  ]
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Open the active Story rows from this run.

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

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/instagram-story-viewer").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 = { "instagramAccounts": ["nasa"] }

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/instagram-story-viewer").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 '{
  "instagramAccounts": [
    "nasa"
  ]
}' |
apify call maximedupre/instagram-story-viewer --silent --output-dataset

```

## MCP server setup

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

```

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/5SkJ0YsbFZUrWco8K/builds/mYY1ywOxat2cdrJtJ/openapi.json
