Instagram Post Scraper - Captions, Likes, Media, No Login
Pricing
from $0.18 / 1,000 instagram post scrapeds
Instagram Post Scraper - Captions, Likes, Media, No Login
Scrape Instagram posts and reels from links. You get the caption, likes, comments and publish time. Also every carousel image and video URL. Plus the owner, hashtags, mentions and tagged users. It runs logged out, with no browser. $0.18 per 1,000 posts, flat on every plan.
Pricing
from $0.18 / 1,000 instagram post scrapeds
Rating
5.0
(1)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
37
Total users
18
Monthly active users
18 hours ago
Last modified
Categories
Share
Instagram Post Scraper: one row per post or reel, from links you already have
Paste Instagram post, reel or IGTV links and get one row each: the full caption, the like and comment counts, the exact publish time, every image and video URL including all the frames of a carousel, the owner, the hashtags, the mentions and the tagged users. Bare shortcodes work too, so a messy list is fine.
Two things are missing on purpose, and it is better to know now: there is no comment text, and
videoViewCount is usually null, because Instagram does not publish the play count to a
logged-out reader. Likes and comments are there on both posts and reels.
| Input | Post, reel or IGTV links, or bare shortcodes |
| Output | One row per post |
| Ceiling | 5,000 links per run |
| Account needed | None from you |
| Price | $0.18 per 1,000 posts, flat on every plan. Optional Facebook counts: $1.40 per 1,000 posts checked, from 12 October 2026 |
๐ What Instagram Post Scraper does
You give it links, it gives you rows. instagram.com/p/<code>/, /reel/<code>/, /tv/<code>/, a
link copied from a profile grid, or just DbtErSrlB2J on its own. Mix them freely in one run.
Carousels come back whole. images and videos hold every frame in carousel order, childPosts
holds one object per frame with its own shortcode and dimensions, and childPostsCount tells you
how many there were. A reel fills in videoUrl and videoDuration and carries type: "Video" with
productType: "clips".
Duplicate links are removed before anything is charged, including the same post supplied once as a URL and once as a bare code. A link that is dead, deleted or on a private account comes back as a free labelled row rather than a charge.
๐ฅ What you give it
{"postUrls": ["https://www.instagram.com/p/DbtErSrlB2J/","https://www.instagram.com/reel/DcCH2ZygIiP/","DbwWBxpDm_0"],"maxItems": 10}
| Field | Default | What it is |
|---|---|---|
postUrls | none | The links you want. Up to 5,000 per run, duplicates removed first. |
maxItems | none | Stop after this many posts, counting from the top of your list. Leave it empty to read every link. The input form starts you at 10. |
includeFacebookCounts | off | From 12 October 2026. Adds Facebook plays, likes and comments for posts that were also shared to Facebook, plus the Instagram-and-Facebook totals. $1.40 per 1,000 posts checked, on top of the post price, and it needs a paid Apify plan. Ticking it before then changes nothing and costs nothing. |
sessionCookies | none | Optional, and rarely needed. Your own Instagram cookie, used to read through your account's own rate limit. The value sits in the run input, so use an account you are happy to automate. |
proxyUrls | none | Leave it empty unless you have your own servers you want the traffic to leave through. |
Hand it no links at all and it writes one labelled sample row, free, so you can see the shape before spending anything.
๐ค What you get back
A real row from a real run. The caption is cut short in the middle, the media links are trimmed, and the eight carousel frames are shown as two:
{"ok": true,"charged": true,"recordType": "post","inputUrl": "https://www.instagram.com/p/DbtErSrlB2J/","id": "3957840214710558089","shortCode": "DbtErSrlB2J","url": "https://www.instagram.com/p/DbtErSrlB2J/","type": "Sidecar","productType": "carousel_container","isReel": false,"isSponsored": false,"caption": "Where in the (Martian) world is Curiosity?\n \nOur Curiosity Mars rover has started its climb up a Martian valley called Valle Grande. ...\n \n#NASA #Mars #CuriosityRover","hashtags": ["NASA", "Mars", "CuriosityRover"],"mentions": [],"likesCount": 284607,"commentsCount": 1759,"videoViewCount": null,"likesAndViewCountsDisabled": false,"isCommentsDisabled": false,"timestamp": "2026-08-06T15:49:01.000Z","displayUrl": "https://scontent-mia3-3.cdninstagram.com/v/t51.82787-15/766074877_...","videoUrl": null,"videoDuration": null,"images": ["https://scontent-mia3-3.cdninstagram.com/v/t51.82787-15/766074877_...","https://scontent-mia5-1.cdninstagram.com/v/t51.82787-15/766287913_..."],"videos": [],"childPosts": [{ "id": "3957839638910891589", "shortCode": "DbtEi6bPnZF", "type": "Image", "displayUrl": "https://scontent-mia3-3.cdninstagram.com/..." }],"childPostsCount": 8,"dimensionsWidth": 495,"dimensionsHeight": 292,"alt": null,"ownerId": "528817151","ownerUsername": "nasa","ownerFullName": "NASA","ownerIsVerified": true,"ownerIsPrivate": false,"ownerProfilePicUrl": "https://scontent-mia5-1.cdninstagram.com/v/t51.2885-19/...","ownerProfileUrl": "https://www.instagram.com/nasa/","coauthorProducers": [],"coauthorProfiles": [],"taggedUsers": [],"sponsorProfiles": [],"locationName": null,"locationId": null,"musicArtist": null,"musicTitle": null,"source": "graphql","scrapedAt": "2026-09-21T01:45:41.661Z"}
| Field | What it is |
|---|---|
type | Image, Video or Sidecar. Sidecar is Instagram's name for a carousel. |
productType | The finer kind: feed, clips for a reel, carousel_container, igtv. |
shortCode | Unique per post. The right key for joining runs together. |
timestamp | When it was published, in UTC. It never moves, so sort and filter on this one. |
likesCount, commentsCount | A snapshot at read time. Both come back null when the account has hidden its counts, and likesAndViewCountsDisabled says so. |
taggedUsers, coauthorProfiles, sponsorProfiles | Profile objects with id, username, full name, link and picture. Tagged users carry x and y coordinates when Instagram supplies them. |
locationName, musicTitle, alt | Filled in when the post carries them, null when it does not. Nothing is guessed. |
source | Which public route answered for this row. |
facebookCountsFound | Only with includeFacebookCounts on. true when Facebook numbers came back, false when Instagram showed the whole post and it carries none, null when this check could not tell. |
facebookPlayCount, facebookLikesCount, facebookCommentsCount | The Facebook side of a shared post. null when none came back. |
totalPlayCount, totalLikesCount, totalCommentsCount | Instagram and Facebook added together, the way Instagram's app shows a shared post. null unless Facebook numbers came back. |
instagramPlayCount | Instagram plays on their own, for reels, whenever the Facebook check answered. |
๐งพ Reading the output
Three kinds of row land in your dataset, and one flag separates them.
| Row | How to spot it | Billed |
|---|---|---|
| A real post | ok: true and charged: true | yes |
| The sample row | _sample: true, charged: false | no |
| A diagnostic | _diagnostic: true, charged: false, an errorCode | no |
Filter on charged == true and you have your posts. Read that flag as the marker that separates a
real row from a sample or a diagnostic, not as a receipt.
| Code | What it means |
|---|---|
NOT_FOUND | Deleted, or on a private account. Nothing public to read. |
BAD_INPUT | That entry is not an Instagram post link or a shortcode. |
RATE_LIMITED, BLOCKED | Instagram refused that link this time. Re-running usually clears it. |
SERVER_ERROR, NETWORK | Instagram was unreachable or answered badly. Re-run it. |
TIME_BUDGET | The run ran out of time before reaching that link. |
NO_RESULTS | Nothing in the list parsed at all, so the run stopped rather than working through dead links. |
FACEBOOK_COUNTS_OFF | You ticked Facebook counts but this run could not use them: before 12 October 2026, on a free Apify plan, or unavailable on this run. Nothing was looked up or charged for them. |
FACEBOOK_COUNTS_STOPPED | Facebook counts stopped part-way, at the maximum cost you set for the run. Later posts have the Facebook fields empty. |
A diagnostic row never fails the run and is never billed.
โถ๏ธ How to run it
- Open Instagram Post Scraper and click Try for free.
- Paste your links into Post or reel links, one per line.
- Set Maximum posts while you are testing, since you pay per post.
- Click Start.
- Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.
๐ฐ How much does it cost?
$0.18 per 1,000 posts. Flat on every Apify plan, no volume tiers.
You pay per post row delivered. Duplicate links are collapsed before the run starts, so the same post is never charged twice. The sample row, every diagnostic row, and links that were never valid Instagram links cost you nothing.
Facebook counts, if you tick them: $1.40 per 1,000 posts checked, from 12 October 2026, on top of the post price. Every post checked is charged, whether or not Facebook numbers come back for it, and the option needs a paid Apify plan.
๐ก What people use it for
- Turning a list of links from a brief into a table of captions, counts and media, in one run.
- Pulling every frame of a competitor's carousels for a creative review.
- Logging the like and comment counts of the same posts weekly to see how they age.
- Collecting reel video files and durations for a cut-down or a highlights reel.
๐ง What it does not do
- No comment text. The count is there, the comments are not. That is a separate actor, linked below.
- It will not walk a profile grid. Give it links. If you want everything an account has posted, use the profile-level actor below.
- Nothing private. A post on a private account comes back
NOT_FOUND, and no input reaches it. videoViewCountis usuallynull. Instagram does not publish the play count to a logged-out reader. Likes and comments are there.- A long list of dead links stops early. After 40 consecutive failures with nothing parsed, the
run writes a
NO_RESULTSrow and stops rather than burning the rest of your list. - If the run hits its deadline, the next 25 unread links get a
TIME_BUDGETrow each and the rest get no row at all. - Media links expire. They are signed, short-lived links, so download anything you want to keep.
- Facebook numbers are not on every shared post. They exist only for posts the account also shared
to Facebook, and Instagram does not show the Facebook side on every check. When it holds it back,
the row says
facebookCountsFound: nulland the check is still charged. - Counts are a snapshot at read time, not at publish time.
๐งญ Which Instagram scraper do you need?
| If you want | Use |
|---|---|
| One post or reel you already have the link for | This one |
| Everything on an account's grid | Instagram Scraper |
| One row per account, with contact details and engagement | Instagram Profile Scraper |
| Comments under a post or reel | Instagram Comments Scraper |
| Posts under a hashtag | Instagram Hashtag Scraper |
โ Questions people ask
Do I need an Instagram account? No. Public posts are read logged out, and that covers the vast majority of links.
Does a carousel cost more than a photo? No. One row, one charge, however many frames are in it.
What if I paste the same post twice? It is fetched and charged once. That includes the same shortcode supplied once as a URL and once on its own.
Can I get the comments? Not here. Use the comments actor linked above.
Is scraping Instagram legal? This reads public posts only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
Can I run it on a schedule? Yes. Re-running the same links is safe and gives you a fresh snapshot of the counts.
๐ If something breaks
Open the Issues tab on the actor page. Include one of the links that failed and the run ID, and the log is enough for us to see what happened.