Instagram Highlights Scraper API – Stories & Media
Pricing
from $3.00 / 1,000 profiles
Instagram Highlights Scraper API – Stories & Media
Scrape Instagram Highlights and the Stories saved inside them. Get Highlight titles, covers, photos, videos, direct media URLs, timestamps, mentions, hashtags, links, locations, music, stickers, and more. Process up to 50 profiles per run with structured, API-ready results.
Pricing
from $3.00 / 1,000 profiles
Rating
0.0
(0)
Developer
LanceAPI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Scrape Instagram Highlights, then go deeper into the Stories, photos, videos, links, mentions, music, and metadata saved inside them.
Enter an Instagram username, @username, or profile URL to discover the Highlight collections saved on a public profile. Start with lightweight Highlight summaries, or open the returned Highlights to retrieve their available photos, videos, direct media URLs, and Story-level details—including mentions, hashtags, links, locations, music, and supported stickers.
Every result is already organized as Profile → Highlights → Stories, so you can send it directly to a database, dashboard, AI workflow, monitoring system, or archive without rebuilding the relationships yourself. Process one profile on the Free plan or up to 50 profiles per paid run, and control cost by choosing how many Highlights to return and whether to retrieve their content.
- Summaries or full Story content — Discover Highlight collections first, then open them only when you need the content inside.
- Photos, videos, and direct media URLs — Move available creative assets into authorized research, archiving, and automation workflows.
- Rich Story-level metadata — Retrieve captions, timestamps, mentions, hashtags, links, locations, music, and supported stickers.
- Pay only for the depth you request — Each opened Highlight is charged once, whether it contains 5 Stories or 50; Story items are never billed individually.
Key features
- Instagram Highlight discovery — Go beyond the first few visible collections and return up to your selected limit, with IDs, titles, covers, counts, and useful dates.
- Optional Highlight expansion — Keep research quick and economical with summaries, or open each returned Highlight when photos, videos, and Story details matter.
- Photos, videos, and direct media URLs — Move available media references directly into an authorized archive, review process, or downstream application.
- Rich Story-level metadata — Understand more than the creative asset with captions, timestamps, dimensions, mentions, hashtags, links, locations, music, and supported stickers.
- Clean nested results — Receive one organized record per profile, with every Highlight and Story already connected in a predictable structure.
- Batch processing with cost control — Paid users can process up to 50 profiles per run, while
maxHighlightsPerProfileandincludeHighlightContentcontrol result volume and depth.
Why Instagram Highlights matter
Active Stories disappear quickly, while Highlights are content a profile has chosen to keep visible and organize over time. That makes them especially useful for researching brand positioning, products and services, campaigns, FAQs, creator partnerships, destinations, portfolios, and evergreen content. Not every profile uses Highlights in the same way, but they can provide a more durable view of what a brand or creator considers important.
Quick start
- Enter a username,
@username, or Instagram profile URL in Input. - Keep Get Highlight content off for a quick, lower-cost first run.
- Click Start and open the Dataset when the run finishes.
- If you need the photos, videos, and Story metadata inside the returned Highlights, enable Get Highlight content and run again.
Minimal input
{"usernames": ["lenasu2567"],"includeHighlightContent": false,"maxHighlightsPerProfile": 10}
Start with Highlight summaries, then enable Highlight content only when you need Story-level details. The default returns up to 10 summaries; increase the limit when your workflow needs a broader view of the profile.
Example result
This shortened result shows the summary structure returned by the input above. The highlights array is abbreviated to one item for readability.
{"username": "lenasu2567","profileUrl": "https://www.instagram.com/lenasu2567/","status": "success","highlightCount": 10,"highlights": [{"id": "18333455860266830","title": "Here🩵🤍","coverImageUrl": "[temporary Instagram CDN URL]","storiesExpanded": false,"storyCount": null}]}
Use cases
- Brand and competitor monitoring — Track the product collections, campaigns, FAQs, events, links, and creative themes that brands keep visible on their profiles.
- Creator and influencer research — Study how creators organize long-term content and identify the media, mentions, destinations, music, and links used inside their Highlights.
- Highlight archiving — Preserve structured records and media references for public content you are authorized to retain before collections change.
- Content audits — Review Highlight structure, collection size, update activity, and Story-level metadata across one or many profiles.
- Social media intelligence — Add Instagram Highlight data to broader creator, campaign, category, or competitive-research datasets.
- AI analysis workflows — Use returned captions, metadata, mentions, hashtags, and links for downstream classification, summarization, or topic analysis.
- API and automation workflows — Send clean nested results to databases, dashboards, scheduled monitoring jobs, and other business systems.
How it works
- Add one or more Instagram usernames or profile URLs.
- The Actor normalizes the inputs and removes duplicate profiles.
- It discovers each profile's available Highlight collections.
- It returns up to your selected Highlight limit and, if requested, opens each returned Highlight to retrieve all available Story items.
- It saves one structured Dataset record per unique profile.
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
usernames | string[] | Yes | ["lenasu2567"] | Instagram usernames, @usernames, or profile URLs. Duplicate representations of the same profile are processed once. |
includeHighlightContent | boolean | No | false | Open every returned Highlight and retrieve all available Stories inside it. Each opened Highlight is charged once; Story items are not charged individually. Enable this only when you need Story-level details because it increases run time and cost. |
maxHighlightsPerProfile | integer | No | 10 | Maximum Highlight collections returned per profile, from 1 to 50. Additional pages are retrieved when needed. |
Clearly invalid input, non-Instagram URLs, and Instagram Post, Reel, Story, Explore, or account-management URLs are rejected before profile processing.
Input examples
Return up to 20 Highlights and open their Stories
{"usernames": ["lenasu2567"],"includeHighlightContent": true,"maxHighlightsPerProfile": 20}
Use the default: 10 Highlight summaries without Stories
{"usernames": ["@lenasu2567"],"includeHighlightContent": false}
Return and open the first five Highlights
{"usernames": ["lenasu2567","https://www.instagram.com/instagram/"],"includeHighlightContent": true,"maxHighlightsPerProfile": 5}
Output
Each normalized unique profile creates one Dataset record. Highlights are returned in highlights[], and opened Highlight content is returned in each Highlight's nested stories[].
Profile└── highlights[]└── stories[]
Successful profiles with no Highlights return highlightCount: 0 and highlights: []. Invalid, private, unavailable, and failed profiles also receive a clear result row instead of being silently omitted.
Complete output example
This shortened example uses the real public profile lenasu2567 and its real Here🩵🤍 Highlight. Temporary CDN URLs are represented by descriptive placeholders because signed URLs expire. The run requested one Highlight with content; the nested Story array is shortened for readability.
{"schemaVersion": "1.0","input": "lenasu2567","username": "lenasu2567","userId": "9143732116","fullName": "Lena Xuan Su💛","isVerified": true,"profileUrl": "https://www.instagram.com/lenasu2567/","status": "success","reason": null,"errorMessage": null,"isPrivate": false,"isAccessible": true,"highlightCount": 1,"expandedHighlightCount": 1,"highlightStoryCount": 15,"highlights": [{"id": "18333455860266830","title": "Here🩵🤍","coverImageUrl": "[temporary Instagram CDN URL]","reportedMediaCount": 15,"createdAt": "2026-06-22T00:25:32.000Z","updatedAt": "2026-09-07T02:28:47.000Z","latestStoryAt": "2026-09-07T02:26:53.000Z","storiesExpanded": true,"storyCount": 15,"stories": [{"id": "3924760181110502078","mediaType": "image","postedAt": "2026-06-22T00:24:53.000Z","expiresAt": null,"mediaUrl": "[temporary Instagram CDN image URL]","imageUrl": "[temporary Instagram CDN image URL]","videoUrl": null,"width": 1080,"height": 1920,"durationSeconds": null,"hasAudio": null,"caption": null,"accessibilityCaption": null,"mentions": [],"hashtags": [],"links": [],"locations": [],"music": null,"stickers": []}]}],"requestedAt": "2026-09-09T02:57:25.387Z"}
The top-level counts are calculated from the complete returned result. The example above includes its one returned Highlight but shows only one of the 15 nested Story items.
Field reference
Profile fields
| Field | Type | Meaning |
|---|---|---|
schemaVersion | string | Output contract version. |
input | string | Original supplied value. |
username | string | null | Normalized Instagram username. |
userId | string | null | Instagram profile ID when available. |
fullName | string | null | Public profile display name when available from Highlight data. |
profilePicUrl | string | null | Temporary public profile image URL when available. |
isVerified | boolean | null | Public verification state when available. |
profileUrl | string | null | Canonical Instagram profile URL. |
status | string | success, partial, private, not_found, or failed. |
reason | string | null | Stable reason code when the result is not fully successful. |
errorMessage | string | null | Human-readable result explanation. |
isPrivate | boolean | null | Confirmed privacy state when available. |
isAccessible | boolean | Whether public Highlight data was accessible. |
highlightCount | integer | Unique Highlight collections returned. |
expandedHighlightCount | integer | Highlights successfully opened for content. |
highlightStoryCount | integer | Total Story items returned across opened Highlights. |
highlights | object[] | Discovered Highlight collections with optional nested Stories. |
requestedAt | string | ISO 8601 processing timestamp. |
Highlight fields
| Field | Type | Meaning |
|---|---|---|
id | string | null | Normalized Highlight ID without the highlight: prefix. |
title | string | null | Highlight title. |
coverImageUrl | string | null | Best available temporary cover image URL. |
reportedMediaCount | number | null | Informational count reported by Highlight metadata. |
createdAt | string | null | Highlight creation time in ISO 8601 UTC when available. |
updatedAt | string | null | Highlight metadata update time in ISO 8601 UTC when available. |
latestStoryAt | string | null | Latest reported Highlight Story time in ISO 8601 UTC when available. |
storiesExpanded | boolean | Whether this Highlight was successfully opened during the run. |
storyCount | integer | null | Actual Story items returned; null when the Highlight was not opened. |
stories | object[] | Available photos, videos, and metadata returned from the Highlight. |
Story fields
| Field | Type | Meaning |
|---|---|---|
id | string | null | Story media identifier. |
mediaType | string | image, video, or unknown. |
postedAt | string | null | Original publication time in ISO 8601 UTC. |
expiresAt | null | Always null because saved Highlight content is not treated as an active 24-hour Story. |
mediaUrl | string | null | Primary direct image or video URL. |
imageUrl | string | null | Image or video-cover URL. |
videoUrl | string | null | Direct video URL for video items. |
width, height | number | null | Selected media dimensions in pixels. |
durationSeconds | number | null | Video duration. |
hasAudio | boolean | null | Reported audio availability for videos. |
caption | string | null | Story caption when available. |
accessibilityCaption | string | null | Accessibility description when available. |
mentions | object[] | Mentioned accounts. |
hashtags | string[] | Hashtags without #. |
links | object[] | Supported link stickers. |
locations | object[] | Available location metadata. |
music | object | null | Available music title, artist, and audio ID. |
stickers | object[] | Supported poll, question, quiz, countdown, and slider metadata. |
Status and errors
Status and reason reference
| Status | Meaning |
|---|---|
success | Highlight discovery and every requested content expansion completed successfully. Empty Highlights or empty content can still be successful. |
partial | Some useful Highlight data was returned, but pagination, requested expansion, or the spending limit prevented full completion. |
private | The profile was identified as private or unavailable for public Highlight access. |
not_found | The Instagram profile could not be found. |
failed | No usable Highlight result was produced. |
Possible reason values are:
invalid_input, profile_not_found, private_account, highlight_fetch_failed, highlight_pagination_failed, highlight_content_partial, highlight_content_failed, rate_limited, budget_limit_reached, and processing_error.
Failure result example
{"schemaVersion": "1.0","input": "https://www.instagram.com/reel/ABC123/","username": null,"userId": null,"fullName": null,"profilePicUrl": null,"isVerified": null,"profileUrl": null,"status": "failed","reason": "invalid_input","errorMessage": "The supplied value is not an Instagram username or profile URL.","isPrivate": null,"isAccessible": false,"highlightCount": 0,"expandedHighlightCount": 0,"highlightStoryCount": 0,"highlights": [],"requestedAt": "2026-09-09T00:00:00.000Z"}
Invalid input is rejected before Profile, Highlight, or Highlight Content processing.
Pricing
Pay only for the depth your workflow needs. Start with summaries when Highlight-level data is enough. Enable Highlight Content only when you need the Stories, photos, videos, direct media URLs, and metadata saved inside each collection.
- Start:
$0.002per run. - Profile processing:
$3.00per 1,000 successfully processed profiles. - Highlights: as low as
$2.30per 1,000 returned Highlight collections. - Highlight Content: as low as
$5.00per 1,000 successfully opened Highlights.
One charge opens the whole Highlight. Story items are not billed individually: a Highlight with 5 Stories and a Highlight with 50 Stories each incur only one Highlight Content charge. That gives you predictable costs even when a collection contains many photos or videos.
The charging rules are simple:
- A successfully processed public profile with no Highlights is charged for the Start and Profile only.
- Summary-only runs do not create Highlight Content charges.
- Private, not-found, failed, and clearly invalid profiles do not create a Profile charge. The Start fee still applies to the run.
- Failed Highlight discovery or content expansion does not create the corresponding Highlight or Highlight Content charge. Partial results are charged only for completed work.
See the Pricing tab for the current prices available with your Apify plan.
Free vs. paid
- Free users: up to 1 unique valid profile per run.
- Paid users: up to 50 unique valid profiles per run.
Limits are applied after username normalization and duplicate removal. Requests above the applicable limit fail before profile processing and are never silently truncated.
API examples
Actor name:
lance_api/instagram-highlights-scraper-api
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('lance_api/instagram-highlights-scraper-api').call({usernames: ['lenasu2567'],includeHighlightContent: true,maxHighlightsPerProfile: 5,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0].highlights);
Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("lance_api/instagram-highlights-scraper-api").call(run_input={"usernames": ["lenasu2567"],"includeHighlightContent": True,"maxHighlightsPerProfile": 5,})profiles = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(profiles[0]["highlights"])
cURL
curl -X POST \"https://api.apify.com/v2/acts/lance_api~instagram-highlights-scraper-api/run-sync-get-dataset-items" \-H "Authorization: Bearer $APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"usernames": ["lenasu2567"],"includeHighlightContent": true,"maxHighlightsPerProfile": 5}'
FAQ
Can I scrape Instagram Highlights from a username or profile URL?
Yes. Enter a username, @username, or public Instagram profile URL. The Actor normalizes these formats and returns the profile's available Highlight collections.
Can I scrape Instagram Highlight Stories, photos, and videos?
Yes. When includeHighlightContent is enabled, the Actor opens the returned Highlights and retrieves available Story items, including images, videos, direct media URLs, and supported Story metadata. You can process or save media you are authorized to retain; the Actor itself does not download files.
Do I have to retrieve Highlight content?
No. The default returns Highlight summaries only. This is useful when you need collection IDs, titles, covers, counts, and dates without the added time and cost of opening every Highlight.
How many Instagram profiles can I process in one run?
Free users can process 1 unique profile per run. Paid users can process up to 50. Duplicate versions of the same username are processed once.
How is pricing calculated?
Pricing follows the work you request: a small Start fee, each successfully processed Profile, each returned Highlight, and each Highlight opened for content. Use maxHighlightsPerProfile and includeHighlightContent to control result volume and cost.
Am I charged for every Story inside a Highlight?
No. Story items are not billed individually. Opening one Highlight creates one Highlight Content charge whether it returns a few Stories or many.
Why can reportedMediaCount differ from storyCount?
reportedMediaCount comes from the Highlight's reported collection metadata, while storyCount counts the Story items actually available when the Highlight is opened. These values can differ. For example, a Highlight may report 80 items while 28 are currently returned; that difference does not by itself indicate a failed or incomplete run.
Are the image and video URLs permanent?
No. Instagram CDN URLs can expire. Process or save media you are authorized to retain while the links are still active.
Can I scrape private Instagram Highlights?
No. The Actor works with publicly accessible profiles and Highlight data only.
How is this different from an Instagram Stories scraper?
An Instagram Stories scraper retrieves a profile's currently active Stories. This Instagram Highlights scraper focuses on the saved Highlight collections displayed on a profile and can optionally retrieve the Story content available inside them.
Limitations
- Works with publicly accessible Instagram profiles and currently available Highlight data; private content is outside its scope.
- Focuses on Highlights, not active Stories outside Highlights, posts, Reels, comments, followers, following lists, or search results.
- Availability can be affected by Instagram access challenges, rate limits, or temporary restrictions.
- Some optional metadata can be null or empty when it is not publicly available.
- Direct media URLs can expire, and the Actor does not download media, create transcripts, run OCR, translate content, or perform sentiment analysis.
Responsible use
Use public data responsibly and in line with Instagram's terms, privacy and intellectual-property rights, and applicable law. The Actor requires only public profile identifiers—never provide passwords, cookies, sessions, or access tokens.
Support
For support, open an issue on the Actor page or email lanceapi2026@hotmail.com. Include the Apify Run ID, public username, input settings, and expected versus actual result. Never send passwords, cookies, or API tokens.