Instagram Highlights Scraper — Extract Stories, Profiles avatar

Instagram Highlights Scraper — Extract Stories, Profiles

Pricing

$14.99/month + usage

Go to Apify Store
Instagram Highlights Scraper — Extract Stories, Profiles

Instagram Highlights Scraper — Extract Stories, Profiles

Scrapes Instagram Story Highlights from any public profile, capturing highlight titles, cover images, story media, timestamps, and URLs. Ideal for content research, brand analysis, influencer insights, and automated extraction of long-term Instagram story archives

Pricing

$14.99/month + usage

Rating

0.0

(0)

Developer

Scrapio

Scrapio

Maintained by Community

Actor stats

0

Bookmarked

24

Total users

2

Monthly active users

4 days ago

Last modified

Share

Instagram Highlights Scraper — Extract Highlights, Stories, Profiles

Instagram Highlights Scraper Plus turns any public Instagram profile's story highlights into structured, typed JSON. Give it a profile URL, username, or @handle and it returns every highlight's title, ID, media count, creation and last-updated dates, deep link and cover image, plus each highlight's owner metadata (username, full name, verified status, profile picture). Turn on story fetching and it also returns the individual stories inside each highlight — image/video URLs, timestamps, duration and dimensions — as linked child rows. Unlike scraping frameworks that return raw HTML, it returns typed JSON ready for your database, dashboard, or LLM pipeline without any parsing. This guide covers every input and output field, exactly how the pay-per-event billing works, and how teams deploy it for content monitoring, competitor research, and dataset building.

🧭 What Does Instagram Highlights Scraper Plus Do?

Instagram Highlights Scraper Plus resolves one or more Instagram profiles and fetches all of their public story highlights — the pinned reels that live permanently on a profile, distinct from 24-hour stories. No Instagram account or login is required for the default flow: the Actor loads each profile page logged out, resolves the numeric user ID from the page HTML, and fetches highlights through Instagram's private and GraphQL endpoints without ever presenting a session cookie. Capabilities:

  • Resolves any number of target profiles in a single run (startUrls), each accepted as a full URL, bare username, or @handle
  • Fetches every highlight per profile with title, media count, creation/last-updated timestamps, deep link and cover image
  • Optionally fetches the individual stories inside each highlight — media type, direct image/video URL, taken-at timestamp, duration, dimensions and accessibility caption (includeStories)
  • Filters highlights by title keyword (include/exclude) and by minimum story count before they're written or billed
  • Caps highlights per profile and stories per highlight independently (maxItems, maxStoriesPerHighlight)
  • Optionally downloads cover images and story media into the run's key-value store (downloadMedia)
  • Escalates proxies automatically — your selection, then datacenter, then residential — on an Instagram block, without failing the run

⚡ Features & Capabilities

The Actor is built around three layers: highlight discovery, optional per-story enrichment, and pre-billing filters.

Core features

  • Dual-path highlight fetch — the primary path calls Instagram's private highlights_tray endpoint, which needs no relay tokens and returns every highlight in one response with rich fields (media_count, created_at, full-resolution cover candidates). If that path is unavailable, the Actor falls back to a paginated GraphQL relay query (up to 15 pages) using guest tokens read live from the profile page HTML, only dropping to hardcoded fallback tokens if the page exposes none.
  • Reels-media enrichment — a second call to Instagram's reels_media endpoint (batched up to 20 highlight IDs per request) backfills any highlight missing media_count, created_at, or a full-resolution cover, and is also the source of each highlight's story items when includeStories is on.
  • Highlight fieldsid, title, mediaCount, createdAt (ISO-8601), latestReelMediaAt (ISO-8601), highlightUrl (deep link), coverImageUrl, reelType, isPinned, plus owner fields ownerId, ownerUsername, ownerFullName, ownerIsVerified, ownerIsPrivate, ownerProfilePicUrl.
  • Story item fields (optional)mediaType (image/video), mediaUrl, videoUrl, imageUrl, imageVariants, takenAt, expiringAt, videoDuration, width, height, accessibilityCaption. Emitted as child rows (type: "story", isChild: true, parentId: <highlight id>) and also mirrored to a per-run stories-<runId> dataset when the run ID resolves.
  • Pre-billing filterskeywords, excludeKeywords and minMediaCount run before a highlight is written to the dataset, so a highlight your filters reject is never charged.
  • Media downloaddownloadMedia saves each highlight cover image (and, when enabled, each story's media) into the run's key-value store and adds a downloadedMediaUrl field to that row.
  • Automatic proxy escalation — starts on your proxyConfiguration selection (or no proxy), escalates to datacenter, then to residential proxies on an Instagram block (HTTP 429/403); residential proxies retry up to 3 times with a fresh IP each attempt, and once residential is used it stays sticky for the rest of the run.

How Instagram Highlights Scraper Plus compares to other Instagram scrapers

FeatureInstagram Highlights Scraper Plusseemuapps/instagram-highlights-scraperigview-owner/instagram-highlights-stories-viewer
Input methodProfile URL / username / @handle, unlimited countUp to 20 usernames per run, as observed on the Apify Store on 2026-07-26Single 17-digit Highlight ID per run — you must already know it, as observed on the Apify Store on 2026-07-26
Optional story items✅ (includeStories, with per-highlight cap)✅ (always fetched with highlights)✅ (this is the Actor's only mode)
Highlight-level filtering✅ (keywords, excludeKeywords, minMediaCount)Not documentedNot applicable — no highlight discovery step
Owner/profile fields on each row✅ (ownerUsername, ownerFullName, ownerIsVerified, ownerProfilePicUrl, ownerIsPrivate)Not documented beyond usernameusername only, as observed on the Apify Store on 2026-07-26
Login requiredNo (logged-out by default)No, as observed on the Apify Store on 2026-07-26No, as observed on the Apify Store on 2026-07-26
Media download to key-value store✅ (downloadMedia)Not documentedNot documented
Pricing modelPay-per-event (row_result)Pay-per-event, plus a documented 20-highlights-per-run free-tier cap, as observed on the Apify Store on 2026-07-26Pay-per-event, as observed on the Apify Store on 2026-07-26

If your use case is feeding structured data to an LLM, all three return typed JSON, so the output-format row alone isn't the decision-maker — discovery flexibility is. This Actor and seemuapps' both discover highlights from a profile; igview-owner's requires you to already have a Highlight ID (extracted, for example, from this Actor's highlightUrl field) and only fetches that one highlight's stories.

When another tool might suit you better

If you already have a specific Highlight ID and only need that single reel's stories — not profile-wide discovery — igview-owner/instagram-highlights-stories-viewer is a narrower tool built exactly for that lookup. If you need to bulk-download a large number of profiles' highlights on Instagram's built-in free-tier cap and don't need title/media-count filtering or owner metadata, seemuapps/instagram-highlights-scraper covers that with a simpler two-field input.

Instagram Highlights Scraper Plus within the Scrapio data stack

Instagram Highlights Scraper Plus covers a profile's story highlights and their stories. For a profile's followers, use the Instagram Followers Scraper With Lead Enrichment. For who a profile follows, use the Instagram Following Scraper With Lead Enrichment. For hashtag-level posts, likes and comments, use the Instagram Hashtag Scraper. For a profile's related/similar accounts, use the Instagram Related Person Scraper With Profile Enrichment.

Why do developers and data teams scrape Instagram highlights?

🏢 Marketing and content teams

Feed a competitor's or partner's profile into startUrls and get back every pinned highlight's title, mediaCount and coverImageUrl in one structured pass — no manual scrolling through a profile's highlight tray. Turn on includeStories to pull the actual media behind each highlight for creative research, or set keywords to ["launch", "sale"] to isolate only highlights tagged for a specific campaign type.

📊 AI training data and RAG indexing

title, accessibilityCaption (on story items) and ownerFullName/ownerUsername are the highest-information text fields for RAG enrichment of a brand or creator knowledge base. For training data, mediaType, reelType and isPinned are the fields with the most consistent structure across records, since they're small enumerations rather than free text. Every field returns as a typed primitive — string, integer, boolean or null — so no HTML parsing sits between the dataset and your context window.

📱 Competitive and market intelligence

Run the same startUrls against a competitor's profile on a schedule and track mediaCount, latestReelMediaAt and title across their highlight set over time — a direct read on whether they're actively curating pinned content or letting a highlight tray go stale.

🔬 Research and academic use

title, mediaCount, createdAt and isPinned across a set of public profiles support content-strategy and social-media research. The Actor only reaches highlights Instagram serves to a logged-out viewer of a public profile — no private-account data is accessible.

🎥 Product and SaaS development

The per-highlight coverImageUrl, title and owner fields are the building block for a brand-monitoring dashboard, a content-archiving tool, or a highlight-backup product layered on top of this Actor's dataset output.

🍚 Input Parameters

All 9 parameters, read directly from .actor/actor.json, in schema order:

ParameterRequiredTypeDefault / constraintsDescription
startUrlsYesarrayeditor: stringListOne target per line: a full profile URL (https://www.instagram.com/nasa), a username (nasa), or an @handle (@nasa). Each is resolved to the profile and all its public story highlights are scraped.
maxItemsNointegerdefault 0; min 0Cap the number of highlights (parent rows) scraped per profile. Stories fetched inside a highlight do NOT count against this. 0 = unlimited.
keywordsNoarrayeditor: stringListOnly keep highlights whose title contains at least one of these words (case-insensitive). Leave empty to keep all.
excludeKeywordsNoarrayeditor: stringListDrop highlights whose title contains any of these words (case-insensitive).
minMediaCountNointegerdefault 0; min 0Only keep highlights that contain at least this many stories. 0 = no minimum.
includeStoriesNobooleandefault falseFetch the actual stories inside each highlight: media type, image/video URL, taken-at timestamp, duration, dimensions and accessibility caption. Each story is emitted as a child row (type: "story", isChild: true, parentId: <highlight id>) and also mirrored to a per-run stories-<runId> dataset.
maxStoriesPerHighlightNointegerdefault 0; min 0When includeStories is on, cap how many stories to fetch per highlight. 0 = all stories in the highlight.
downloadMediaNobooleandefault falseDownload each highlight cover image (and, when story items are enabled, each story's media) into the run's key-value store and add a downloadedMediaUrl field.
proxyConfigurationNoobjecteditor: proxy; prefill {"useApifyProxy": true}Choose which proxies to use. On an Instagram block the Actor fails fast and escalates: datacenter, then residential (up to 3 retries with a fresh IP each time; once residential is used it stays sticky for the rest of the run).

⚠️ The Actor also reads an undocumented sessionId string from the raw input — it is not a declared property in .actor/actor.json and has no field in the Apify Console UI, but if you pass one via the API it is sent as an Instagram sessionid cookie on every request. It is never required: the default flow works fully logged out.

{
"startUrls": ["https://www.instagram.com/nasa/"],
"maxItems": 5,
"keywords": ["mission"],
"excludeKeywords": ["ad"],
"minMediaCount": 3,
"includeStories": true,
"maxStoriesPerHighlight": 10,
"downloadMedia": false,
"proxyConfiguration": { "useApifyProxy": true }
}

Supported URL types and input formats

startUrls accepts, per entry: a full profile URL (https://www.instagram.com/nasa), a bare username (nasa), or an @handle (@nasa). URLs must be on the instagram.com domain; a first path segment of stories, p, reel, reels, explore or tv is rejected as "not a profile URL" rather than silently mis-resolved. A bare username may only contain letters, digits, underscores and periods.

Examples:

  • ["https://www.instagram.com/nasa/"] — single profile by full URL
  • ["nasa", "nike"] — multiple profiles by bare username, one run
  • ["@nasa"] — single profile by @handle

📦 Output Format

Each dataset row is one highlight or, when includeStories is on, one story linked to its parent highlight. Every highlight row and every story row that passes the filters bills exactly one row_result charged event each — a run with includeStories on and 10 stories inside one kept highlight bills 11 row_result events for that highlight, not 1. Diagnostic rows — a bad startUrls entry, or a profile with no accessible highlights — are still written to the dataset (success: false, an error string) but are pushed without a charged_event_name, so they cost nothing; filter on success == true to see only billed rows. The default dataset view shown in the Apify Console surfaces 29 columns; the Actor pushes a superset of that — highlight rows carry 6 owner fields (ownerId, ownerUsername, ownerIsPrivate, in addition to the 3 owner fields in the view) that aren't in the default view, and story rows carry videoUrl, imageUrl, imageVariants and expiringAt in addition to the fields shown by default. Every row also carries input_url, success, error and scrapedAt.

Output for a highlight

{
"input_url": "https://www.instagram.com/nasa/",
"username": "nasa",
"userId": "528817151",
"type": "highlight",
"isChild": false,
"parentId": null,
"id": "17895695668004550",
"highlightUrl": "https://www.instagram.com/stories/highlights/17895695668004550/",
"title": "Artemis",
"mediaCount": 24,
"createdAt": "2021-08-19T18:03:11Z",
"latestReelMediaAt": "2024-05-01T12:00:00Z",
"coverImageUrl": "https://scontent.cdninstagram.com/v/t51.../cover.jpg",
"reelType": "highlight_reel",
"isPinned": true,
"ownerId": "528817151",
"ownerUsername": "nasa",
"ownerFullName": "NASA",
"ownerIsVerified": true,
"ownerIsPrivate": false,
"ownerProfilePicUrl": "https://scontent.cdninstagram.com/v/t51.../profile.jpg",
"storiesCount": 10,
"success": true,
"error": null,
"scrapedAt": "2026-07-26T10:00:00Z"
}

Output for a story item

{
"input_url": "https://www.instagram.com/nasa/",
"username": "nasa",
"userId": "528817151",
"type": "story",
"isChild": true,
"parentId": "17895695668004550",
"id": "3863446781711360305",
"mediaType": "video",
"mediaUrl": "https://instagram.fasr1-1.fna.fbcdn.net/v/t50.../story.mp4",
"videoUrl": "https://instagram.fasr1-1.fna.fbcdn.net/v/t50.../story.mp4",
"imageUrl": "https://instagram.fasr1-1.fna.fbcdn.net/v/t51.../thumb.jpg",
"imageVariants": [
{ "url": "https://scontent.cdninstagram.com/.../480x852.jpg", "width": 480, "height": 852 },
{ "url": "https://scontent.cdninstagram.com/.../1080x1920.jpg", "width": 1080, "height": 1920 }
],
"takenAt": "2021-08-19T17:55:03Z",
"expiringAt": null,
"videoDuration": 14.7,
"width": 1080,
"height": 1920,
"accessibilityCaption": "Photo by NASA on August 19, 2021.",
"success": true,
"error": null,
"scrapedAt": "2026-07-26T10:00:00Z"
}

An error row (a bad startUrls entry, or a profile with no accessible highlights) omits the owner and story-specific fields and instead carries success: false and a populated error string, e.g. "No highlights found for this profile."

Schema stability and export options

Field names stay fixed across runs regardless of whether includeStories or downloadMedia is enabled — unavailable fields are emitted as null rather than omitted, except downloadedMediaUrl, which is present only when downloadMedia is on. Results are stored in the Actor's default dataset and can be exported from the Apify Console or API as JSON, CSV, Excel, XML, HTML or RSS — the standard Apify dataset export formats — and are also readable programmatically via apify_client while, or after, the run is in progress. When includeStories is on, story rows are additionally mirrored to a separate stories-<runId> dataset for the duration of that run.

💡 Instagram Highlights Scraper Plus Strategy Guide

🎯 Strategy 1: Real-time content-monitoring pipeline

Trigger a run whenever a competitor or partner profile is added to your watch list. Set startUrls to that profile, leave includeStories off for a fast metadata-only pass, and read title, mediaCount, coverImageUrl and latestReelMediaAt back through apify_client into your content-tracking system as soon as the run finishes.

🎯 Strategy 2: Scheduled monitoring and alerting

Use an Apify Schedule to re-run the same startUrls against a profile weekly. Diff the new dataset's id/title set against the previous run's id/title set to isolate newly added or renamed highlights, then alert on any highlight whose latestReelMediaAt moved forward — a direct signal the profile is actively curating that reel.

🎯 Strategy 3: Bulk highlight-and-story dataset build

List every target profile in a single startUrls array, turn on includeStories to capture per-story media, and export the resulting dataset directly to CSV or a database via apify_client. No concurrency limit is documented for the number of profiles in one run; profiles are processed one at a time within a run, so parallelism across a very large profile list comes from running multiple Actor runs rather than one wide run.

Strategy comparison at a glance

StrategyBest forRun patternOutput format
Real-time monitoringNew profile added to a watch listOn-demand single-profile run, includeStories offDataset → downstream system via apify_client
Scheduled monitoringTracking a profile's highlight curation over timeApify Schedule, recurringDataset diffed run-over-run on id/title
Bulk dataset buildContent archiving or research datasetOne or more runs, many startUrls, includeStories onDataset export to CSV/DB
ScraperWhat it extracts
Instagram Followers Scraper With Lead EnrichmentA profile's followers, enriched into contactable leads
Instagram Following Scraper With Lead EnrichmentThe accounts a profile follows, enriched into leads
Instagram Hashtag ScraperHashtag posts, likes and comments
Instagram Related Person Scraper With Profile EnrichmentA profile's related/suggested accounts, with enrichment
TikTok Trending Scraper With Trend InsightsTrending short-video content on TikTok, for cross-platform content comparison
Website Contact & Email ExtractorEmails, phones and social links crawled from a company website

How to integrate Instagram Highlights Scraper Plus with your stack

Instagram Highlights Scraper Plus works with any language or tool that can make an HTTP request, through the Apify API and the official apify-client SDKs.

Python

from apify_client import ApifyClient
import csv
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
"startUrls": ["https://www.instagram.com/nasa/", "nike"],
"maxItems": 10,
"includeStories": True,
"maxStoriesPerHighlight": 5,
}
run = client.actor("instagram-highlights-scraper-plus").call(run_input=run_input)
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
with open("highlights.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["type", "username", "id", "title",
"mediaCount", "coverImageUrl", "highlightUrl"])
writer.writeheader()
for row in rows:
writer.writerow({k: row.get(k) for k in writer.fieldnames})
print(f"Exported {len(rows)} rows to highlights.csv")

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('instagram-highlights-scraper-plus').call({
startUrls: ['https://www.instagram.com/nasa/', 'nike'],
maxItems: 10,
includeStories: true,
});
const { items: rows } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Fetched ${rows.length} rows`);

Async and scheduled pipelines

For large exports, start the run with client.actor(...).start() instead of .call() and poll client.run(runId).get() for status, or configure an Apify Schedule in the Console to run automatically on a cadence. Results are pulled from the dataset once the run status is SUCCEEDED — the Actor itself does not push a webhook payload, but Apify's platform-level webhooks can be attached to any run to notify an external endpoint on completion.

🎯 Who Needs Instagram Highlights Scraper Plus? (Use Cases & Industries)

🏢 Marketing and content teams

Track a competitor's or partner's highlight tray by title and mediaCount, exporting coverImageUrl and highlightUrl straight into a content-research board.

📊 Brand and audience analysts

Profile which topics a creator or brand pins as highlights over time using title and latestReelMediaAt, to benchmark content-curation cadence against competitors.

📱 Influencer and partnership managers

Pull a creator's full highlight set with includeStories on to review the actual media behind each pinned reel before a partnership pitch, using ownerFullName and ownerIsVerified to confirm the account.

🔬 Researchers

Build public-data datasets on content-curation patterns — highlight counts, titles, and pin timing — across a set of public profiles, using only fields the Actor pulls from a logged-out view of public profile data.

🎥 Product and SaaS builders

Layer a content-archiving tool, a brand-monitoring dashboard, or a highlight-backup product on top of this Actor's coverImageUrl, mediaUrl and downloadedMediaUrl output.

Scraping publicly accessible data is generally lawful in the United States: in hiQ Labs, Inc. v. LinkedIn Corp., 938 F.3d 985 (9th Cir. 2019), the Ninth Circuit held that scraping data a website makes publicly available does not violate the Computer Fraud and Abuse Act. That precedent concerns public-data access, not any specific platform's terms. Separately, running a scraper against Instagram may conflict with Instagram's own Terms of Service — a civil contract matter between the account holder and Meta, not a criminal one, and a real risk to weigh independently. Because highlight rows include personal data of the profile owner — username, full name, verification status and profile picture — data protection law applies: GDPR in the EU/UK and CCPA/CPRA in California both govern the collection, storage and use of personal data, public or not. Instagram Highlights Scraper Plus returns only publicly accessible data. What you do with that data is your responsibility — consult legal counsel for commercial applications involving personal data.

❓ Frequently asked questions

Does Instagram Highlights Scraper Plus work without an Instagram account?

Yes, by default. The Actor loads each profile page logged out and resolves highlights through Instagram's private and GraphQL endpoints without a session cookie. An undocumented sessionId input exists for advanced use but is never required.

How does Instagram Highlights Scraper Plus handle Instagram's anti-scraping measures?

It escalates proxies on a block: your proxyConfiguration selection first, then a datacenter fallback, then residential proxies with up to 3 retries on a fresh IP each time — after which residential stays sticky for the rest of the run. Individual requests also back off exponentially with jitter on transient failures before that escalation kicks in.

Can I run Instagram Highlights Scraper Plus at scale without getting blocked?

maxItems and maxStoriesPerHighlight bound the volume per profile, and any number of profiles can be listed in startUrls. No uptime or block-rate guarantee is published. Profiles within a single run are processed one at a time, not in parallel, so very large batches are better split across multiple runs than pushed through one oversized startUrls list.

How fresh is the data Instagram Highlights Scraper Plus returns?

Every run fetches highlights and, when enabled, stories live from Instagram at run time — there is no caching layer in the Actor. Data reflects each profile's highlight tray at the moment of the run.

Which fields work best for AI training and RAG indexing?

For RAG, title and, on story items, accessibilityCaption are the highest-information free-text fields. For training data, mediaType, reelType and isPinned are the most consistently structured fields across records, since they're small enumerations rather than free text. All fields return as typed primitives (string, integer, boolean, or null) — no HTML parsing or normalization is required before use.

What personal data does Instagram Highlights Scraper Plus collect, and who is responsible for its use?

Each highlight row includes the owner's ownerUsername, ownerFullName, ownerIsVerified, ownerIsPrivate and ownerProfilePicUrl — public profile fields that can constitute personal data under GDPR/CCPA. The Actor never fabricates a value it cannot find; a missing field returns null. Lawful basis for storing and using that data rests with you as the operator.

Does Instagram Highlights Scraper Plus work with Claude, ChatGPT, and other AI agent tools?

Yes, as an HTTP endpoint. No MCP server is documented for this Actor, but any agent framework that can call the Apify API — directly, or via the apify-client package — can start a run and read back the dataset. Every response is typed JSON, so no parsing step sits between the Actor and an LLM's context window.

What happens if a profile has no accessible highlights?

The Actor emits one row with type: "highlight", success: false and error: "No highlights found for this profile." — and does not charge a row_result event for it, since the charge only fires on success: true rows.

How does Instagram Highlights Scraper Plus compare to other Instagram highlight scrapers?

igview-owner/instagram-highlights-stories-viewer is a better fit if you already have a specific 17-digit Highlight ID and just need that one reel's stories, as observed on the Apify Store on 2026-07-26 — it has no profile-wide discovery step. seemuapps/instagram-highlights-scraper is a simpler two-field tool (usernames plus a highlights-per-user cap) with a documented 20-highlights-per-run free tier, as observed on the Apify Store on 2026-07-26. Instagram Highlights Scraper Plus's advantage is discovery-plus-filtering in one run: title/media-count filters, owner metadata, and optional media download, on top of the same profile-to-highlights discovery those competitors also perform.

ℹ️ Disclaimer

Instagram Highlights Scraper Plus extracts only publicly available data from Instagram. This tool is intended for lawful use cases only. Users are responsible for complying with Instagram's terms of service and applicable data protection laws in their jurisdiction.