Instagram Posts Scraper Pro
Pricing
Pay per usage
Instagram Posts Scraper Pro
Scrape public Instagram posts, reels, and carousel posts from usernames, profile URLs, and post URLs with optional cookies, explicit diagnostics, and simple per-post pricing. Unofficial actor, not affiliated with Instagram or Meta.
Pricing
Pay per usage
Rating
5.0
(1)
Developer
Netdesignr
Actor stats
1
Bookmarked
3
Total users
2
Monthly active users
a day ago
Last modified
Categories
Share
Scrape Instagram posts, reels, and carousel posts from public profiles and direct post URLs with optional session cookies, explicit diagnostics, and simple per-post pricing.
$0.90 / 1,000 posts | Optional cookies | HTTP-first speed | Clear login-wall diagnostics
Why use this Instagram scraper
- Scrape public Instagram usernames, profile URLs, post URLs, and reel URLs in one actor.
- Capture posts, reels, and carousels with normalized media, captions, hashtags, mentions, coauthors, and engagement metrics.
- Skip pinned posts correctly before date filtering so "recent posts only" runs behave the way users expect.
- Use
fast,balanced, orfullextraction modes depending on how much fallback and resilience you want. - Attach optional profile snapshots and recent comment previews without introducing a second billing event.
- Get explicit run diagnostics such as
login_wall,private_or_unavailable,rate_limited, andno_posts_foundinstead of a silent empty dataset.
What makes this actor stronger
- Clearer pricing: one
postevent instead of separate billing for lightweight results versus detailed results. - Better reliability strategy: HTTP-first for lower cost, then browser fallback only when Instagram degrades or HTML parsing is required.
- Better migration path: accepts
username,resultsLimit, anddataDetailLevelfor easier switching from other Instagram post actors. - Better observability: every run persists both
RUN_METAandSUMMARY.jsonso empty runs can be audited quickly. - Better operator controls: optional raw session cookie header support when public Instagram surfaces become login-walled.
What data you can extract
| Field | Description |
|---|---|
id | Stable Instagram media or post identifier |
shortCode | Post or reel shortcode |
postUrl | Canonical Instagram post URL |
type | image, video, reel, or carousel |
caption | Caption text when available |
hashtags | Hashtags parsed from the caption |
mentions | Mentions parsed from the caption |
coauthors | Coauthor usernames when exposed |
isPinned | Whether the post appears pinned |
isSponsored | Best-effort sponsored indicator |
commentsDisabled | Whether comments are disabled |
publishedAt | ISO publish timestamp when parseable |
likesCount | Like count when visible |
commentsCount | Comment count when visible |
videoViewCount | View count for reels and videos when visible |
videoDurationSeconds | Video duration when visible |
media | Normalized media array with image or video variants |
ownerUsername | Post owner username |
ownerFullName | Post owner full name when available |
ownerIsVerified | Best-effort verification flag |
profile | Optional profile snapshot object |
recentComments | Optional preview comments when exposed |
accessStatus | Success or explicit diagnostic status |
warnings | Honest extraction warnings instead of invented values |
extractionMethod | http_api, http_html, or browser_html |
Supported inputs
- Instagram usernames such as
natgeo - Instagram profile URLs such as
https://www.instagram.com/nasa/ - Instagram post URLs such as
https://www.instagram.com/p/SHORTCODE/ - Instagram reel URLs such as
https://www.instagram.com/reel/SHORTCODE/
Out of scope in v1:
- Stories
- Hashtag feeds
- Location feeds
- Topic discovery feeds
- Full comment crawling
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
startUrls | array | [] | Usernames, profile URLs, post URLs, or reel URLs |
maxPostsPerProfile | integer | 24 | Max posts emitted for each profile target |
skipPinnedPosts | boolean | false | Remove pinned posts before date filtering |
onlyPostsNewerThan | string | none | ISO date or relative value like 2 weeks |
extractionMode | string | balanced | fast, balanced, or full |
includeRecentComments | boolean | true | Include comment preview when Instagram exposes it |
recentCommentsLimit | integer | 3 | Max preview comments per post |
includeProfileDetails | boolean | false | Attach a profile snapshot to each post |
sessionCookieHeader | string | none | Optional raw Cookie header from a logged-in session |
proxyConfiguration | object | none | Optional proxy configuration |
emptyRunPolicy | string | retry_then_warn | How to exit when reachable targets emit zero posts |
debugMode | boolean | false | Include extra diagnostics |
username | array or string | none | Legacy compatibility alias for profile targets |
resultsLimit | integer | none | Legacy compatibility alias for maxPostsPerProfile |
dataDetailLevel | string | none | Legacy compatibility alias for extractionMode |
Example input
{"startUrls": ["natgeo","https://www.instagram.com/nasa/","https://www.instagram.com/reel/DHB0Example/"],"maxPostsPerProfile": 20,"skipPinnedPosts": true,"onlyPostsNewerThan": "30 days","extractionMode": "balanced","includeRecentComments": true,"recentCommentsLimit": 3,"includeProfileDetails": true,"emptyRunPolicy": "retry_then_warn"}
Migration-friendly input example
{"username": ["natgeo", "nasa"],"resultsLimit": 12,"skipPinnedPosts": true,"dataDetailLevel": "detailedData"}
If both legacy and canonical fields are provided, the canonical fields win.
Output example
{"id": "3612345678901234567","shortCode": "DHB0Example","postUrl": "https://www.instagram.com/reel/DHB0Example/","type": "reel","caption": "A behind-the-scenes launch day update from @nasa #space","hashtags": ["space"],"mentions": ["nasa"],"coauthors": [],"isPinned": false,"isSponsored": false,"isPaidPartnership": false,"commentsDisabled": false,"publishedAt": "2026-03-21T14:13:00.000Z","likesCount": 18452,"commentsCount": 213,"videoViewCount": 220194,"videoDurationSeconds": 28.4,"media": [{"type": "video","url": "https://instagram.fxyz1-1.fna.fbcdn.net/v/t50.2886-16/example.mp4","thumbnailUrl": "https://instagram.fxyz1-1.fna.fbcdn.net/v/t51.2885-15/example.jpg","altText": "Astronauts preparing for launch","width": 720,"height": 1280,"durationSeconds": 28.4,"variants": []}],"ownerUsername": "nasa","ownerFullName": "NASA","ownerId": "528817151","ownerIsVerified": true,"profile": {"username": "nasa","fullName": "NASA","followersCount": 98123456,"followingCount": 81,"postsCount": 4321},"recentComments": [{"id": "17890000123456789","text": "This is incredible.","ownerUsername": "spacefan","likesCount": 12}],"inputUrl": "https://www.instagram.com/nasa/","accessStatus": "success","warnings": [],"extractionMethod": "http_api","scrapedAt": "2026-03-25T22:15:00.000Z"}
Diagnostics and run artifacts
Every run stores:
RUN_METAwith input count, items emitted, retry usage, residential fallback usage, exit code, and success flagsSUMMARY.jsonwith per-targetaccessStatus, items emitted, extraction method, and warnings
Possible accessStatus values:
successlogin_wallprivate_or_unavailablerate_limitednot_foundno_posts_foundunknown_error
API examples
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('netdesignr/instagram-posts-scraper-pro').call({startUrls: ['natgeo'],maxPostsPerProfile: 12,skipPinnedPosts: true,extractionMode: 'balanced',includeProfileDetails: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("netdesignr/instagram-posts-scraper-pro").call(run_input={"startUrls": ["https://www.instagram.com/nasa/"],"maxPostsPerProfile": 12,"skipPinnedPosts": True,"extractionMode": "balanced"})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
cURL
curl -X POST "https://api.apify.com/v2/acts/netdesignr~instagram-posts-scraper-pro/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls": ["natgeo"],"maxPostsPerProfile": 12,"skipPinnedPosts": true,"extractionMode": "balanced"}'
Pricing
This actor is designed for a simpler one-event pricing model.
- Free: $0.90 / 1,000 posts
- Starter: $0.80 / 1,000 posts
- Scale: $0.70 / 1,000 posts
- Business: $0.50 / 1,000 posts
The actor charges only after dataset items are successfully written. Retries do not add a second detail charge because there is no separate detail event.
FAQ
Does this scrape Instagram posts without logging in?
Yes, for public surfaces Instagram still exposes to logged-out browsers. When Instagram degrades the public response, the actor can retry, use a proxy, or use an optional logged-in cookie header.
Why is session cookie support useful?
It helps when Instagram serves a login wall, partial HTML, or a reduced public response. It is optional and meant for users who already have a compliant internal workflow for handling their own account session data.
How does pinned post filtering work?
When skipPinnedPosts is enabled, pinned posts are removed before the onlyPostsNewerThan filter is applied. This avoids the common case where an old pinned post slips into a recent-only result set.
Does it support reels and carousels?
Yes. Reels are normalized as type: "reel" and multi-item posts are normalized as type: "carousel" with a media[] array.
Can I scrape full comments?
No. v1 focuses on post extraction and only keeps small recent comment previews when Instagram exposes them in the source payload.
What happens on empty runs?
The actor retries once with a fresh session. If needed and no proxy was supplied, it can attempt a residential proxy fallback. The final run status is written to RUN_META and SUMMARY.json.
Legal and responsible use
Use this actor only for data you have the right to collect and process. Respect Instagram's terms, applicable law, privacy obligations, and downstream compliance requirements such as GDPR or CCPA. Review your own legal basis before using scraped social media data in production.