# Instagram Stories & Highlights Scraper – No Login (`lance_api/instagram-stories-highlights-scraper-api`) Actor

Scrape current Instagram Stories and optional Highlights from public profiles. Get direct image and video URLs, links, mentions, hashtags, music, and clean JSON—no Instagram login or cookies required.

- **URL**: https://apify.com/lance\_api/instagram-stories-highlights-scraper-api.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:** AI, Social media, Videos
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 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 API

**Get current Instagram Stories, complete Highlight collections, and optional photos and videos saved inside Highlights—organized as one clean result per public profile.**

Enter Instagram usernames or profile URLs and receive direct image and MP4 URLs, timestamps, music, mentions, links, locations, and structured Highlight contents. Use the results in monitoring, research, authorized archival, and media workflows. No Instagram login or cookies are required.

- **One organized profile result** with `activeStories[]` and nested `highlights[].stories[]`
- **Direct image and MP4 URLs** with dimensions, timing, duration, and audio availability
- **Complete available Highlight discovery** with optional, cost-controlled Story expansion
- **Bulk public profiles** with automatic input normalization and duplicate removal
- **Pay per successful check—not per Story item** returned

### ✨ Key features

#### Active Stories and complete Highlight discovery

Retrieve current 24-hour Stories while discovering all available Highlight collections and following supported Highlight list pagination.

#### Optional Highlight expansion

Open only the Highlights you need. `maxHighlightsPerUser` controls expansion cost without hiding the rest of the discovered Highlight inventory.

#### Direct Story media URLs

Receive image and MP4 URLs for downstream authorized media, monitoring, and archival workflows. The Actor also returns dimensions, timestamps, video duration, and audio availability.

#### One organized result per profile

Stories and Highlights stay grouped naturally under their Instagram profile instead of being scattered across mixed Dataset rows.

#### Rich Story metadata

Extract useful links, mentions, hashtags, music, locations, captions, and selected interactive stickers without receiving a large raw data dump.

#### Simple, predictable pricing

Pay when a profile check, Highlight page, or Highlight opens successfully. A Highlight returning many Story items still produces only one Highlight-content charge.

### Stories, Highlights, and Highlight Stories

**Active Stories** are temporary photos and videos currently available in a user's 24-hour Story tray.

**Highlights** are collections of previous Stories that the profile owner saved on their profile.

**Highlight Stories** are the individual photos and videos saved inside one Highlight collection.

The output follows the same natural hierarchy:

```text
Profile
├── activeStories[]
└── highlights[]
    └── stories[]
```

Each unique username produces one Dataset item. You do not need to filter and reconnect separate Story and Highlight rows.

### 🚀 Quick start

#### Minimum input

```json
{
  "usernames": ["example_creator"]
}
```

The default behavior retrieves current Stories. To get Highlights or the Stories saved inside them, enable the corresponding input options.

1. Add usernames, `@usernames`, or public Instagram profile URLs.
2. Choose current Stories, Highlights, or both.
3. Enable **Get Stories inside Highlights** only when you need the media saved inside each collection.
4. Set how many Highlights may be opened, or use `0` to open all discovered Highlights.
5. Start the Actor and open the Dataset.

### Input examples

#### Current Stories only

```json
{
  "usernames": ["example_creator"],
  "includeStories": true,
  "includeHighlights": false
}
```

#### Highlight list only

```json
{
  "usernames": ["example_creator"],
  "includeStories": false,
  "includeHighlights": true,
  "expandHighlightItems": false
}
```

#### Current Stories and complete Highlight contents

```json
{
  "usernames": ["example_creator"],
  "includeStories": true,
  "includeHighlights": true,
  "expandHighlightItems": true,
  "maxHighlightsPerUser": 0
}
```

### Input options

| Field | Type | Required | Default | Limits | Description |
|---|---|---:|---:|---|---|
| `usernames` | `string[]` | Yes | `['nike']` | At least 1 item; no schema maximum | Usernames, `@usernames`, or public profile URLs. Duplicate profiles are processed once. |
| `includeStories` | `boolean` | No | `true` | — | Get Stories currently available in each profile's 24-hour Story tray. |
| `includeHighlights` | `boolean` | No | `false` | — | Discover Highlight collections and follow available list pages. |
| `expandHighlightItems` | `boolean` | No | `false` | — | Open selected Highlights and return their photos and videos in `stories[]`. |
| `maxHighlightsPerUser` | `integer` | No | `10` | `0–50`; `0` means all | Maximum discovered Highlights to open per profile. This does not limit discovery. |
| `compactOutput` | `boolean` | No | `false` | — | Omit Stories or Highlights sections that were not requested. Status fields always remain. |

The original `expandHighlightStories` input name remains accepted as a compatibility alias, but new integrations should use `expandHighlightItems`.

### Short output example

```json
{
  "schemaVersion": "2.0",
  "username": "example_creator",
  "status": "success",
  "activeStoryCount": 2,
  "activeStories": [
    {
      "id": "story_1001",
      "mediaType": "video",
      "mediaUrl": "https://example.com/story.mp4",
      "postedAt": "2026-08-13T10:00:00.000Z",
      "expiresAt": "2026-08-14T10:00:00.000Z"
    }
  ],
  "highlightCount": 0,
  "expandedHighlightCount": 0,
  "highlights": []
}
```

The shortened arrays above show the hierarchy only. Actual records use the complete Story and Highlight schemas below.

### Output

The default Dataset contains one item for each unique profile. With `compactOutput: false`, requested and unrequested modules keep stable status, count, and array fields. With `compactOutput: true`, modules that were not requested may be omitted.

Run-level totals are stored separately in the default Key-Value Store under `OUTPUT`; they are not mixed into the profile Dataset.

### Complete output field reference

#### Profile fields

| Field | Type | Nullable | Format / unit | Meaning |
|---|---|---:|---|---|
| `schemaVersion` | `string` | No | Currently `2.0` | Version of the nested output contract. |
| `input` | `string` | Yes | Original value | Original username or URL supplied for this result. |
| `username` | `string` | Yes | Lowercase username | Normalized Instagram username; null for invalid input. |
| `userId` | `string` | Yes | Platform ID | Profile ID when exposed by the available public response. |
| `profileUrl` | `string` | Yes | HTTPS URL | Public Instagram profile URL. |
| `status` | `string` | No | Enum | Overall status: `success`, `partial`, `private`, `not_found`, or `failed`. |
| `isPrivate` | `boolean` | Yes | — | Whether available profile data identifies the account as private. |
| `isAccessible` | `boolean` | No | — | Whether at least part of the requested public data was retrieved. |
| `reason` | `string` | Yes | Machine-readable code | Null on complete success; otherwise explains the result state. |
| `errorMessage` | `string` | Yes | Human-readable text | User-facing explanation corresponding to `reason`. |
| `storiesStatus` | `string` | No | Module enum | `success`, `partial`, `failed`, or `not_requested`; may be omitted in compact output when unrequested. |
| `activeStoryCount` | `integer` | No | Items | Number of Story objects actually returned in `activeStories`; may be omitted in compact output. |
| `activeStories` | `object[]` | No | Story objects | Current Story items; may be omitted in compact output when unrequested. |
| `highlightsStatus` | `string` | No | Module enum | Status of Highlight discovery and expansion; may be omitted in compact output when unrequested. |
| `highlightCount` | `integer` | No | Collections | Unique Highlights discovered after available pagination; may be omitted in compact output. |
| `expandedHighlightCount` | `integer` | No | Collections | Highlights whose `stories[]` were successfully retrieved. |
| `highlights` | `object[]` | No | Highlight objects | Discovered Highlight collections and optional nested Stories. |
| `requestedAt` | `string` | No | ISO 8601 UTC | Time this profile was processed. |

#### Story fields

Active Stories and Highlight Stories share one clean media schema.

| Field | Type | Nullable | Format / unit | Meaning |
|---|---|---:|---|---|
| `id` | `string` | Yes | Media ID | Story identifier when available. |
| `mediaType` | `string` | No | `image`, `video`, `unknown` | Normalized media type. |
| `postedAt` | `string` | Yes | ISO 8601 UTC | Story publication time. |
| `expiresAt` | `string` | Yes | ISO 8601 UTC | Current Story expiration; null for historical Highlight Stories. |
| `mediaUrl` | `string` | Yes | HTTPS CDN URL | Primary media URL: `imageUrl` for images and `videoUrl` for videos. |
| `imageUrl` | `string` | Yes | HTTPS CDN URL | Image or video-cover URL. |
| `videoUrl` | `string` | Yes | HTTPS MP4 URL | Direct video URL; null for image Stories. |
| `width` | `number` | Yes | Pixels | Selected media width. |
| `height` | `number` | Yes | Pixels | Selected media height. |
| `durationSeconds` | `number` | Yes | Seconds | Video duration; null for images or when unavailable. |
| `hasAudio` | `boolean` | Yes | — | Reported video-audio availability; null for images or when unavailable. It is not inferred from music. |
| `caption` | `string` | Yes | Text | Story caption when available. |
| `accessibilityCaption` | `string` | Yes | Text | Accessibility description when available. |
| `mentions` | `object[]` | No | Accounts | Structured account mentions with username and optional identity fields. |
| `hashtags` | `string[]` | No | Tags without `#` | Hashtags found in supported Story fields. |
| `links` | `object[]` | No | HTTPS URLs | Structured Story link stickers. |
| `locations` | `object[]` | No | Coordinates / text | Structured location metadata. |
| `music` | `object` | Yes | Title, artist, audio ID | Music metadata when available. |
| `stickers` | `object[]` | No | Selected sticker types | Useful supported interactive stickers without internal platform metadata. |

#### Highlight fields

| Field | Type | Nullable | Format / unit | Meaning |
|---|---|---:|---|---|
| `id` | `string` | Yes | Normalized Highlight ID | Highlight identifier without an internal prefix. |
| `title` | `string` | Yes | Text | Highlight title. |
| `coverImageUrl` | `string` | Yes | HTTPS CDN URL | Best available Highlight cover image. |
| `reportedMediaCount` | `number` | Yes | Informational items | Count reported in Highlight metadata; not an authoritative retrievable Story count. |
| `storiesExpanded` | `boolean` | No | — | Whether this Highlight was successfully opened during the run. |
| `storyCount` | `integer` | Yes | Items | Number of Story objects actually returned; null when not expanded. |
| `stories` | `object[]` | No | Story objects | Photos and videos returned from this Highlight. Empty when not expanded or when no items are available. |

### Why can `reportedMediaCount` differ from `storyCount`?

`reportedMediaCount` is the count reported by Instagram's Highlight metadata. When expansion is enabled, `storyCount` is calculated from the actual Highlight Story items returned.

The reported metadata count can be higher than the number of currently retrievable items. The Actor keeps these values separate instead of assuming they are equal. A difference does not by itself make the result partial or failed.

### Status values

#### Profile status

| Status | Meaning | Result behavior | Billing behavior |
|---|---|---|---|
| `success` | Every requested module completed successfully. | Arrays can contain data or be empty. An empty successful check is not a failure. | Each successful requested operation is charged. A valid empty operation is charged because the check completed. |
| `partial` | Some requested work succeeded while another module, page, or expansion did not complete. | Successfully retrieved data remains available; failed sections are identified by module status and `reason`. | Only operations that completed successfully are charged. Failed operations are not charged. |
| `private` | The requested public data is unavailable because the profile is private. | `isPrivate` is `true` when confirmed by available data and otherwise can be `null`; `isAccessible` is `false`, with empty result arrays. | No custom data event is charged for the failed private-profile operation. The small Actor-start charge may still apply. |
| `not_found` | The profile could not be found. | `isAccessible: false` with `reason: "user_not_found"`. | No custom data event is charged for the failed lookup. The small Actor-start charge may still apply. |
| `failed` | No requested module produced a successful usable result, or the input was invalid. | `reason` and `errorMessage` explain the failure. | Failed operations and invalid inputs do not create custom data-event charges. The small Actor-start charge may still apply. |

#### Module status

| Status | Meaning |
|---|---|
| `success` | The module completed, including a valid result containing zero items. |
| `partial` | Some available pages or Highlight expansions succeeded and some did not. |
| `failed` | The requested module did not produce a successful result. |
| `not_requested` | The module was disabled in the input and no corresponding retrieval was performed. |

Billing is based on completed checks, so top-level status alone does not determine the final run price. For example, a `partial` profile can contain several successfully charged checks and one uncharged failed check.

### Empty and unavailable result examples

#### Successful profile with no active Stories

```json
{
  "schemaVersion": "2.0",
  "input": "example_creator",
  "username": "example_creator",
  "status": "success",
  "isPrivate": false,
  "isAccessible": true,
  "reason": null,
  "errorMessage": null,
  "storiesStatus": "success",
  "activeStoryCount": 0,
  "activeStories": []
}
```

The successful current-Story check is charged even though it returns zero Stories.

#### Private profile

```json
{
  "schemaVersion": "2.0",
  "input": "private_example",
  "username": "private_example",
  "status": "private",
  "isPrivate": null,
  "isAccessible": false,
  "reason": "private_account",
  "errorMessage": "This profile is private or not publicly accessible.",
  "storiesStatus": "failed",
  "activeStoryCount": 0,
  "activeStories": []
}
```

#### Profile not found

```json
{
  "schemaVersion": "2.0",
  "input": "missing_example",
  "username": "missing_example",
  "status": "not_found",
  "isPrivate": null,
  "isAccessible": false,
  "reason": "user_not_found",
  "errorMessage": "The Instagram profile could not be found."
}
```

### Complete output example

```json
{
  "schemaVersion": "2.0",
  "input": "example_creator",
  "username": "example_creator",
  "userId": "1000000001",
  "profileUrl": "https://www.instagram.com/example_creator/",
  "status": "success",
  "isPrivate": false,
  "isAccessible": true,
  "reason": null,
  "errorMessage": null,
  "storiesStatus": "success",
  "activeStoryCount": 1,
  "activeStories": [
    {
      "id": "story_1001",
      "mediaType": "video",
      "postedAt": "2026-08-13T10:00:00.000Z",
      "expiresAt": "2026-08-14T10:00:00.000Z",
      "mediaUrl": "https://example.com/story-video.mp4",
      "imageUrl": "https://example.com/story-cover.jpg",
      "videoUrl": "https://example.com/story-video.mp4",
      "width": 720,
      "height": 1280,
      "durationSeconds": 8.2,
      "hasAudio": true,
      "caption": "New collection",
      "accessibilityCaption": null,
      "mentions": [
        {
          "username": "example_brand",
          "userId": "1000000002",
          "fullName": "Example Brand"
        }
      ],
      "hashtags": ["newcollection"],
      "links": [
        {
          "url": "https://example.com/collection",
          "text": "View collection",
          "type": "link_sticker"
        }
      ],
      "locations": [],
      "music": {
        "title": "Example Song",
        "artist": "Example Artist",
        "audioId": "audio_1001"
      },
      "stickers": []
    }
  ],
  "highlightsStatus": "success",
  "highlightCount": 1,
  "expandedHighlightCount": 1,
  "highlights": [
    {
      "id": "highlight_1001",
      "title": "Travel",
      "coverImageUrl": "https://example.com/highlight-cover.jpg",
      "reportedMediaCount": 50,
      "storiesExpanded": true,
      "storyCount": 3,
      "stories": [
        {
          "id": "highlight_story_1001",
          "mediaType": "image",
          "postedAt": "2025-06-10T09:00:00.000Z",
          "expiresAt": null,
          "mediaUrl": "https://example.com/highlight-story.jpg",
          "imageUrl": "https://example.com/highlight-story.jpg",
          "videoUrl": null,
          "width": 1080,
          "height": 1920,
          "durationSeconds": null,
          "hasAudio": null,
          "caption": null,
          "accessibilityCaption": null,
          "mentions": [],
          "hashtags": [],
          "links": [],
          "locations": [],
          "music": null,
          "stickers": []
        }
      ]
    }
  ],
  "requestedAt": "2026-08-13T10:05:00.000Z"
}
```

### Compact output

With `compactOutput: false`, stable empty arrays and count fields remain in every profile record. With `compactOutput: true`, a module that was not requested is omitted.

For example, a Stories-only result can omit `highlightCount` and `highlights`, while `status`, `isAccessible`, `reason`, and `errorMessage` always remain.

### 💰 Simple, predictable pricing

**Pricing starts as low as $4.00 per 1,000 successful operations on eligible paid Apify plans. Free-plan rates are $6.00–$7.00 per 1,000 successful operations.**

You pay for completed checks—not for every Story returned. A Highlight that returns 43 Story items still creates only one `highlight-content` charge.

| Operation | Free-plan price | Per 1,000 | When it applies |
|---|---:|---:|---|
| Current Stories for one profile (`stories-profile`) | `$0.007` | `$7.00` | One successful current Story check, including a valid empty result. |
| One Highlight list page (`highlights-profile`) | `$0.006` | `$6.00` | Each successfully retrieved Highlight list page. Profiles with more Highlights can require multiple pages. |
| Stories inside one Highlight (`highlight-content`) | `$0.006` | `$6.00` | One successfully opened Highlight, regardless of how many Story items it contains. |

Depending on the eligible paid Apify plan, each operation costs `$0.005`, `$0.0045`, or `$0.004`. Check the Actor's **Pricing** tab for the exact price available to your plan.

Pricing examples at the Free-plan rate:

- 100 profiles with current Stories only: approximately **$0.70**, plus the small Actor-start charge.
- One profile with current Stories and a one-page Highlight list: approximately **$0.013**.
- Opening 10 Highlights adds approximately **$0.06**.
- One Highlight returning 43 Stories costs **$0.006**, not `43 × $0.006`.

Additional billing rules:

- A successful check that confirms zero Stories or zero Highlights is charged because the retrieval completed.
- Failed retrieval operations are not charged.
- Duplicate versions of the same username are processed once per run and do not create duplicate operations.
- `maxHighlightsPerUser` limits Highlight expansion cost, not Highlight discovery.
- Each successfully retrieved Highlight list page is charged separately.
- A small automatic Actor-start charge may also apply.

You can set a maximum run cost in Apify when you need a hard spending limit.

### Common use cases

#### Story archival workflows

Feed authorized public 24-hour Story metadata and temporary media URLs into your own archival system before the Stories disappear. The Actor itself does not permanently store media.

#### Brand monitoring

Track what public brands publish in Stories, including mentions, promotional links, music, locations, and posting times.

#### Influencer monitoring

Analyze public creator activity, tagged accounts, music usage, campaign links, and saved Highlight collections across multiple profiles.

#### Highlight inventory workflows

Discover public Highlight collections, export their covers and metadata, and optionally pass their retrievable photos and videos into your own authorized storage workflow.

#### Content auditing

Review how a public profile organizes long-term Story content and compare the metadata count with the items currently retrievable from each Highlight.

#### Creator and competitive intelligence

Use structured Story metadata in research, dashboards, alerts, and analysis without reconnecting mixed Dataset records.

### How it works

1. The Actor normalizes usernames and profile URLs and removes duplicate profiles.
2. It retrieves current Stories when requested.
3. It discovers available Highlight collections and follows supported Highlight list pagination.
4. It opens the permitted number of Highlights only when expansion is enabled.
5. It normalizes useful media and metadata fields without exposing a large raw response.
6. It saves one hierarchical profile record to the Dataset for each unique input profile.

### API integration

The Actor's full name is:

```text
lance_api/instagram-stories-highlights-scraper-api
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lance_api/instagram-stories-highlights-scraper-api').call({
    usernames: ['example_creator'],
    includeStories: true,
    includeHighlights: true,
    expandHighlightItems: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].activeStories);
console.log(items[0].highlights);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("lance_api/instagram-stories-highlights-scraper-api").call(run_input={
    "usernames": ["example_creator"],
    "includeStories": True,
    "includeHighlights": True,
    "expandHighlightItems": False,
})

profiles = client.dataset(run["defaultDatasetId"]).list_items().items
print(profiles[0]["activeStories"])
print(profiles[0]["highlights"])
```

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/lance_api~instagram-stories-highlights-scraper-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "usernames": ["example_creator"],
    "includeStories": true,
    "includeHighlights": true,
    "expandHighlightItems": false
  }'
```

### 🤖 AI Agent integration

Use this Actor through the Apify MCP Server from MCP-compatible clients such as ChatGPT, Claude, Cursor, and Codex.

Example prompt:

> Use the Apify Actor `lance_api/instagram-stories-highlights-scraper-api` to retrieve current Instagram Stories and Highlights from these public profiles. Include direct media URLs, links, mentions, hashtags, music, locations, and timestamps. Keep the results grouped by profile and summarize each Highlight with its Story count.

Running the Actor through Apify MCP uses the same Actor pricing as a normal Actor run.

### FAQ

#### What does one Dataset item contain?

One item represents one unique Instagram profile. Current Stories are in `activeStories[]`; Highlight collections are in `highlights[]`; expanded Highlight Stories are in each Highlight's `stories[]`.

#### Does an account with no current Stories fail?

No. A successful check returns `status: "success"`, `activeStoryCount: 0`, and `activeStories: []`. The successful check is charged because it confirmed the result.

#### Which input formats are accepted?

Use plain usernames, `@usernames`, or public Instagram profile URLs. Post, Reel, and Story URLs are not profile inputs.

#### Can I process multiple Instagram profiles?

Yes. Add multiple values to `usernames`. Duplicate versions of the same username are normalized and processed once per run.

#### How am I charged if a profile returns many Stories?

A successful current-Story check creates one `stories-profile` charge whether it returns zero, one, or many active Stories. You are not charged once per returned Story.

#### How much does Highlight expansion cost?

On the Free plan, each successfully opened Highlight costs `$0.006`, regardless of how many Story items it returns. On eligible paid plans, it costs `$0.005`, `$0.0045`, or `$0.004`; check the Pricing tab for your plan-specific rate.

#### Does `maxHighlightsPerUser` limit the returned Highlight list?

No. It limits only how many discovered Highlights are opened to retrieve their `stories[]`. All discovered collections remain in `highlights[]`. Use `0` to expand all discovered Highlights.

#### Why can one profile create multiple Highlight-list charges?

Highlight collections can be paginated. Each successfully retrieved list page creates one `highlights-profile` charge and is merged into the profile's `highlights[]`.

#### Are media URLs permanent?

No. `imageUrl` and `videoUrl` are Instagram CDN URLs and may expire or stop working later.

#### Can it access private profiles?

No. The Actor is designed for publicly accessible profiles and does not attempt to obtain non-public information.

#### Does it download or permanently store media?

No. It returns temporary media URLs and structured metadata. Your authorized downstream workflow is responsible for any permitted download or storage.

#### Can AI agents use this Actor?

Yes. MCP-compatible AI clients can run it through the Apify MCP Server using the Actor's full name. MCP runs use the same pricing.

#### Does it return raw platform data?

No. The output keeps useful, documented fields and excludes large internal metadata, comments, licensing internals, and interaction controls.

### Limitations

- Only publicly accessible profile data is supported.
- Current Stories can disappear before a scheduled or delayed run retrieves them.
- CDN media URLs are temporary and may stop working later.
- Some metadata fields can be null or empty arrays when Instagram does not expose them for a particular Story or Highlight.
- `reportedMediaCount` is informational metadata, not a promise that the same number of Story items can be retrieved.
- Highlight expansion returns the available items supplied for that Highlight; it does not invent pagination when none is provided.
- The Actor does not download media, transcribe audio, run OCR, analyze sentiment, or collect Story comments.

### Public data and responsible use

Use this Actor only for lawful purposes. Respect Instagram's terms, privacy rights, intellectual property rights, and applicable data-protection rules. Only process data you are authorized to access and use.

Do not use the Actor for harassment, spam, unlawful profiling, attempts to obtain non-public information, or other activities that violate applicable laws or platform rules.

### Support

For help, open an issue on the Actor page or email **lanceapi2026@hotmail.com**.

Include the Apify Run ID, the affected public username, the relevant input settings, and a short description of the expected and actual result. Never send account passwords, cookies, API tokens, or other secrets.

# Actor input Schema

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

Enter usernames, @usernames, or public Instagram profile URLs. Duplicate profiles are processed once.

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

Get Stories currently available in each profile's 24-hour Story tray.

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

Get all discoverable Highlight collections. The Actor follows available Highlight list pages.

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

Open selected Highlights and return their photos and videos. Each opened Highlight creates an additional paid operation.

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

Limits only how many discovered Highlights are opened. Use 0 to open every discovered Highlight.

## `compactOutput` (type: `boolean`):

Omit Stories or Highlights sections that were not requested. Status and error fields are always included.

## Actor input object example

```json
{
  "usernames": [
    "nike"
  ],
  "includeStories": true,
  "includeHighlights": false,
  "expandHighlightItems": false,
  "maxHighlightsPerUser": 10,
  "compactOutput": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

One structured Dataset item for each unique Instagram profile input.

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

Run-level profile, result, pagination, and billing totals.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/instagram-stories-highlights-scraper-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("lance_api/instagram-stories-highlights-scraper-api").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 '{}' |
apify call lance_api/instagram-stories-highlights-scraper-api --silent --output-dataset

```

## MCP server setup

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

```

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/A06AjPITPu4cwy43R/builds/9iXMXmDFNYdAzohjx/openapi.json
