# Instagram Highlights Scraper — Albums & Media Links (`lergassy/instagram-highlights-scraper`) Actor

Scrape Instagram highlight albums: album title, cover and media count, then every photo and video inside with its file link, posted date, caption and the link, mention and hashtag stickers. Handles or profile links in, one row per media out. No login, no cookies.

- **URL**: https://apify.com/lergassy/instagram-highlights-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 10 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 account checkeds

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 Stories Scraper** turns a list of public Instagram handles into a table of **active stories** and **highlight albums**. One row per media: the file link, when it was posted, when it expires, and the stickers on it — links, mentions, hashtags, locations, polls and questions. No login, no cookies, no Instagram account of yours at risk.

### What you get

| Mode | What comes back | One row is |
|---|---|---|
| 📸 **Active stories** | Everything the account posted in the last 24 hours | One story |
| ⭐ **Highlight albums** | The permanent albums under the bio, opened media by media | One media inside an album |
| 📸+⭐ **Both** | Both of the above in one run | Either |

Every row carries the account, the media file link in its largest size, photo-or-video, the posted and expiry time, the caption, and every sticker Instagram attached — including the **link sticker**, which is the one marketers actually want.

### Why this needs us at all

Instagram does not show stories or highlights to a logged-out visitor from any address: the profile page answers with a redirect to the login screen, and its internal API answers `401 require_login`. Checked on 28 October 2026. This Actor reads them through a paid data source that holds the sessions, so you never hand over your own cookies and never get an account banned.

### What it costs

Two charges, and both are stated before you press Start:

| What is charged | When |
|---|---|
| **One account checked** | Once per handle in your list — whether or not it has active stories right now |
| **One media** | For every story or highlight media actually delivered, with its file link |

There is also a **run fee**, and it is the smallest in this niche — below what every competitor charges to start a run.

#### On the Apify Free plan

A run collects the **first account in your list in full** — every story and every highlight media it has — and **nothing is charged at all**. The remaining accounts come back as a free note saying they were left alone. So you see the real shape and volume of the data before paying anything. Every account costs us a request to a paid data source, and the free plan does not cover it.

Why the account is charged even when it is empty: looking up an account costs us the same whether it has twenty stories or none. Measured on 25 real accounts on 28 October 2026, nine of them had no active stories at that moment — stories live 24 hours, so an empty answer is a normal answer, not a failure. Charging only for delivered media would mean the accounts that do post subsidise the ones that do not.

### Input

| Field | What it does |
|---|---|
| `usernames` | Handles, `@handles` or profile links, one per line |
| `mode` | `stories`, `highlights` or `both`; leave empty for this Actor's own default (Stories Scraper: both, Highlights Scraper: highlights) |
| `includeHighlightItems` | Off = one row per album (title, cover, media count), cheaper. On = one row per media inside it |
| `maxHighlightsPerUser` | Newest albums first |
| `maxItemsPerUser` | `0` = no limit |

### Output

```json
{
  "type": "story",
  "username": "natgeo",
  "mediaType": "photo",
  "takenAt": "2026-10-27T14:07:48.000Z",
  "expiringAt": "2026-10-28T14:07:48.000Z",
  "imageUrl": "https://…",
  "videoUrl": null,
  "caption": null,
  "links": [], "mentions": ["natgeotravel"], "hashtags": [], "polls": []
}
```

Highlight rows add `highlightId` and `highlightTitle`, so you can group an album back together in a spreadsheet.

### What it does not do

- Private accounts. No media is returned; the account check itself is charged, like any other lookup.
- Who viewed a story. Only the account owner can see that, and we are not the account owner.
- Posting or replying. This Actor only reads.

### For AI agents

- **Minimal input:** `{"usernames": ["natgeo"]}` — handles, `@handles` or profile links; `mode` is `stories`, `highlights` or `both`.
- **Returns:** one row per story or highlight media (or one row per highlight album when `includeHighlightItems` is off). An account with nothing to give — no active stories, no albums, wrong handle — gets one free `type: "notice"` row with the reason; filter it out with `type != "notice"`.
- **Time:** about 25 seconds for one account with stories and 10 highlight albums. A few accounts — call synchronously (`run-sync-get-dataset-items`); long lists — start the run and poll it.

### Errors and empty runs

An empty run always says why in its own words — no active stories, no albums, wrong handle — in a free `notice` row. Filter it out with `type != "notice"`. If our data source stops answering, the run says exactly what it answered, word for word, instead of guessing.

### Your feedback

Found a bug or a missing field? Open an issue on the Actor page. Problems reported by buyers are fixed the same day.

# Changelog

This Actor's version history is a separate document: https://apify.com/lergassy/instagram-highlights-scraper/changelog.md

# Actor input Schema

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

One per line: nasa, @nasa or https://www.instagram.com/nasa/. Public accounts only — private ones return no rows and cost nothing. <b>Billing: each handle here is charged once as an account check</b>, even if it has no active stories right now; delivered media is charged on top.

## `mode` (type: `string`):

Leave empty and the Actor does what its name says: Instagram Stories Scraper collects stories and highlights, Instagram Highlights Scraper collects highlights only. Stories live 24 hours; highlights are the permanent albums under the bio.

## `includeHighlightItems` (type: `boolean`):

On: one row per media inside each album, with its file link. Off: one row per album (title, cover, media count) — cheaper and faster.

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

Newest albums first.

## `maxItemsPerUser` (type: `integer`):

0 = no limit.

## Actor input object example

```json
{
  "usernames": [
    "natgeo"
  ],
  "includeHighlightItems": true,
  "maxHighlightsPerUser": 10,
  "maxItemsPerUser": 0
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Instagram story or per media inside a highlight album: account, photo or video, media file link, posted and expiry time, caption, link, mention, hashtag, location and poll stickers.

## `summary` (type: `string`):

How many rows were delivered, what was charged, and how many requests the data source has left.

# 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": [
        "natgeo"
    ]
};

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

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = { "usernames": ["natgeo"] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/instagram-highlights-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": [
    "natgeo"
  ]
}' |
apify call lergassy/instagram-highlights-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/instagram-highlights-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/6eJ2NValfiXm06vDK/builds/NpIj33giQv4LqboFS/openapi.json
