Instagram Highlights Scraper — Extract Stories, Profiles
Pricing
$14.99/month + usage
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
Maintained by CommunityActor stats
0
Bookmarked
24
Total users
2
Monthly active users
4 days ago
Last modified
Categories
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_trayendpoint, 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_mediaendpoint (batched up to 20 highlight IDs per request) backfills any highlight missingmedia_count,created_at, or a full-resolution cover, and is also the source of each highlight's storyitemswhenincludeStoriesis on. - Highlight fields —
id,title,mediaCount,createdAt(ISO-8601),latestReelMediaAt(ISO-8601),highlightUrl(deep link),coverImageUrl,reelType,isPinned, plus owner fieldsownerId,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-runstories-<runId>dataset when the run ID resolves. - Pre-billing filters —
keywords,excludeKeywordsandminMediaCountrun before a highlight is written to the dataset, so a highlight your filters reject is never charged. - Media download —
downloadMediasaves each highlight cover image (and, when enabled, each story's media) into the run's key-value store and adds adownloadedMediaUrlfield to that row. - Automatic proxy escalation — starts on your
proxyConfigurationselection (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
| Feature | Instagram Highlights Scraper Plus | seemuapps/instagram-highlights-scraper | igview-owner/instagram-highlights-stories-viewer |
|---|---|---|---|
| Input method | Profile URL / username / @handle, unlimited count | Up to 20 usernames per run, as observed on the Apify Store on 2026-07-26 | Single 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 documented | Not applicable — no highlight discovery step |
| Owner/profile fields on each row | ✅ (ownerUsername, ownerFullName, ownerIsVerified, ownerProfilePicUrl, ownerIsPrivate) | Not documented beyond username | ✅ username only, as observed on the Apify Store on 2026-07-26 |
| Login required | No (logged-out by default) | No, as observed on the Apify Store on 2026-07-26 | No, as observed on the Apify Store on 2026-07-26 |
| Media download to key-value store | ✅ (downloadMedia) | Not documented | Not documented |
| Pricing model | Pay-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-26 | Pay-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:
| Parameter | Required | Type | Default / constraints | Description |
|---|---|---|---|---|
startUrls | Yes | array | editor: stringList | One 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. |
maxItems | No | integer | default 0; min 0 | Cap the number of highlights (parent rows) scraped per profile. Stories fetched inside a highlight do NOT count against this. 0 = unlimited. |
keywords | No | array | editor: stringList | Only keep highlights whose title contains at least one of these words (case-insensitive). Leave empty to keep all. |
excludeKeywords | No | array | editor: stringList | Drop highlights whose title contains any of these words (case-insensitive). |
minMediaCount | No | integer | default 0; min 0 | Only keep highlights that contain at least this many stories. 0 = no minimum. |
includeStories | No | boolean | default false | Fetch 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. |
maxStoriesPerHighlight | No | integer | default 0; min 0 | When includeStories is on, cap how many stories to fetch per highlight. 0 = all stories in the highlight. |
downloadMedia | No | boolean | default false | Download 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. |
proxyConfiguration | No | object | editor: 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
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time monitoring | New profile added to a watch list | On-demand single-profile run, includeStories off | Dataset → downstream system via apify_client |
| Scheduled monitoring | Tracking a profile's highlight curation over time | Apify Schedule, recurring | Dataset diffed run-over-run on id/title |
| Bulk dataset build | Content archiving or research dataset | One or more runs, many startUrls, includeStories on | Dataset export to CSV/DB |
🌴 Related Instagram Scrapers & Tools
| Scraper | What it extracts |
|---|---|
| Instagram Followers Scraper With Lead Enrichment | A profile's followers, enriched into contactable leads |
| Instagram Following Scraper With Lead Enrichment | The accounts a profile follows, enriched into leads |
| Instagram Hashtag Scraper | Hashtag posts, likes and comments |
| Instagram Related Person Scraper With Profile Enrichment | A profile's related/suggested accounts, with enrichment |
| TikTok Trending Scraper With Trend Insights | Trending short-video content on TikTok, for cross-platform content comparison |
| Website Contact & Email Extractor | Emails, 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 ApifyClientimport csvclient = 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.
Is it legal to scrape Instagram?
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.