Instagram Posts Scraper Pro avatar

Instagram Posts Scraper Pro

Pricing

Pay per usage

Go to Apify Store
Instagram Posts Scraper Pro

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

Netdesignr

Maintained by Community

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, or full extraction 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, and no_posts_found instead of a silent empty dataset.

What makes this actor stronger

  • Clearer pricing: one post event 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, and dataDetailLevel for easier switching from other Instagram post actors.
  • Better observability: every run persists both RUN_META and SUMMARY.json so 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

FieldDescription
idStable Instagram media or post identifier
shortCodePost or reel shortcode
postUrlCanonical Instagram post URL
typeimage, video, reel, or carousel
captionCaption text when available
hashtagsHashtags parsed from the caption
mentionsMentions parsed from the caption
coauthorsCoauthor usernames when exposed
isPinnedWhether the post appears pinned
isSponsoredBest-effort sponsored indicator
commentsDisabledWhether comments are disabled
publishedAtISO publish timestamp when parseable
likesCountLike count when visible
commentsCountComment count when visible
videoViewCountView count for reels and videos when visible
videoDurationSecondsVideo duration when visible
mediaNormalized media array with image or video variants
ownerUsernamePost owner username
ownerFullNamePost owner full name when available
ownerIsVerifiedBest-effort verification flag
profileOptional profile snapshot object
recentCommentsOptional preview comments when exposed
accessStatusSuccess or explicit diagnostic status
warningsHonest extraction warnings instead of invented values
extractionMethodhttp_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

ParameterTypeDefaultDescription
startUrlsarray[]Usernames, profile URLs, post URLs, or reel URLs
maxPostsPerProfileinteger24Max posts emitted for each profile target
skipPinnedPostsbooleanfalseRemove pinned posts before date filtering
onlyPostsNewerThanstringnoneISO date or relative value like 2 weeks
extractionModestringbalancedfast, balanced, or full
includeRecentCommentsbooleantrueInclude comment preview when Instagram exposes it
recentCommentsLimitinteger3Max preview comments per post
includeProfileDetailsbooleanfalseAttach a profile snapshot to each post
sessionCookieHeaderstringnoneOptional raw Cookie header from a logged-in session
proxyConfigurationobjectnoneOptional proxy configuration
emptyRunPolicystringretry_then_warnHow to exit when reachable targets emit zero posts
debugModebooleanfalseInclude extra diagnostics
usernamearray or stringnoneLegacy compatibility alias for profile targets
resultsLimitintegernoneLegacy compatibility alias for maxPostsPerProfile
dataDetailLevelstringnoneLegacy 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_META with input count, items emitted, retry usage, residential fallback usage, exit code, and success flags
  • SUMMARY.json with per-target accessStatus, items emitted, extraction method, and warnings

Possible accessStatus values:

  • success
  • login_wall
  • private_or_unavailable
  • rate_limited
  • not_found
  • no_posts_found
  • unknown_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 ApifyClient
client = 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().items
print(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.

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.

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.