Instagram Post Scraper by URL: Reels, Carousel, Likes, Plays
Pricing
from $0.95 / 1,000 post returneds
Instagram Post Scraper by URL: Reels, Carousel, Likes, Plays
This Instagram post scraper takes post and reel URLs and returns one row per post: likes, comments, caption, carousel images, video URL and length, audio, tagged users, location and recent reel plays. No login, no cookies, no start fee. You pay only for posts returned.
Pricing
from $0.95 / 1,000 post returneds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Security
Limited permissionsShare
This Instagram post scraper takes post and reel URLs and returns one row per post: likes, comments, caption, hashtags, carousel images, video URL and length, audio, tagged users, location with coordinates, and plays for recent reels. No login, no cookies, no start fee. You pay $1.65 per 1,000 posts on the Free plan, down to $0.95 on Gold and above, and only for posts actually returned.
What can I do with this Instagram post scraper?
- Track campaigns and creators. Keep a list of post and reel URLs and refresh likes and comments whenever you want, plus plays while a reel is still recent.
- Check influencer deliverables. Confirm that a sponsored post is live, who is tagged, who co-authored it and how it is performing.
- Build a content dataset. Get captions, hashtags, mentions, image URLs and video URLs ready for analysis or for AI tools.
- Save the slides of a carousel. Each carousel row lists its images and videos, not only the cover.
- Find out where a post was made. Location name, ID and coordinates are included when the post has them.
What data do you get?
| Group | Fields |
|---|---|
| Post | shortCode, id, url, inputUrl, type (Image, Video, Sidecar), productType, timestamp, caption, captionIsEdited, hashtags, mentions, alt |
| Engagement | likesCount, likesHidden, commentsCount, isCommentsDisabled, videoPlayCount, viewCountStatus |
| Media | displayUrl, dimensionsWidth, dimensionsHeight, images, childPosts, videoUrl, videoDuration, hasAudio, musicInfo |
| Author | ownerUsername, ownerFullName, ownerId, ownerIsVerified, ownerProfilePicUrl, coauthorProducers, taggedUsers |
| Place | locationName, locationId, latitude, longitude |
| Run | status, note, source, scrapedAt. The last row can also hold notCheckedUrls (URLs to put in a new run) |
Familiar field names such as shortCode, likesCount, commentsCount, caption, displayUrl, childPosts and ownerUsername make it easy to switch an existing workflow.
How to scrape Instagram posts by URL
- Paste your post and reel URLs into
urls. Links with tracking parameters,/reels/links, links with the username in the path and bare shortcodes all work.directUrlsis accepted as another name forurls. - Set
maxPoststo the most posts you want from this run. - Leave
includeViewCountson if you want plays for recent reels, or turn it off for a faster run. - Press Start, then download the rows as JSON, CSV or Excel, or read them through the API.
Input
| Field | What it does | Default |
|---|---|---|
urls | Instagram post and reel URLs, one per line. Up to 1,000 are read per run. | One free sample post when no URLs are given |
maxPosts | The most posts to return and charge for in this run (1 to 1,000). | 100 |
includeViewCounts | Also look up videoPlayCount for reels. Free of charge. | true |
{"urls": ["https://www.instagram.com/p/DeuOR-CjKE9/","https://www.instagram.com/reel/DeTUk4sDSp-/","https://www.instagram.com/p/DfGx7fskZhY/"],"maxPosts": 100,"includeViewCounts": true}
Output example
{"status": "ok","inputUrl": "https://www.instagram.com/reel/DeTUk4sDSp-/","id": "4004634989362489982","type": "Video","productType": "clips","shortCode": "DeTUk4sDSp-","url": "https://www.instagram.com/reel/DeTUk4sDSp-/","hashtags": [],"mentions": [],"likesCount": 100000,"likesHidden": false,"commentsCount": 1000,"timestamp": "2026-10-10T15:15:02.000Z","ownerUsername": "nasa","ownerIsVerified": true,"videoDuration": 43.767,"hasAudio": true,"videoPlayCount": 11094767,"viewCountStatus": "ok","musicInfo": { "artist_name": "nasa", "song_name": "Original audio" }}
Counts in this example are rounded, and some fields are left out to keep it short.
How much does it cost?
$1.65 per 1,000 posts on the Free plan, with lower prices on paid Apify plans:
| Apify plan | Price per 1,000 posts |
|---|---|
| Free | $1.65 |
| Bronze | $1.45 |
| Silver | $1.24 |
| Gold and above | $0.95 |
There is no start fee and no extra charge for carousels, video details, audio or plays. You are charged only for rows with status: "ok". Every other row is free, and the full list is below.
FAQ
How do I get likes and comment counts from an Instagram post by URL?
Paste the URL into urls and run the Actor. Each row has likesCount and commentsCount. When Instagram marks the likes as hidden, likesCount is empty and likesHidden is true.
How do I download all images from an Instagram carousel?
Carousel rows have type: "Sidecar". The images field lists the URL of every slide, and childPosts gives each slide's type, size and video URL.
Can I scrape Instagram reels without logging in? Yes. You don't need an Instagram account, a cookie or an API key.
Can I run this from an API or an AI agent? Yes. Call the Actor through the Apify API, or from an AI agent through the Apify MCP server, with a list of URLs. The rows come back as JSON.
How do I scrape many Instagram posts at once?
Paste a list of URLs (the limit is 1,000 per run). Each URL the run reaches gets a row, in the order you gave them. URLs it did not reach are listed together in one last row. Instagram limits how many posts can be opened without logging in, so long lists may not be read in full. If Instagram refuses most of the recent posts, the run stops early instead of going on. URLs that were not reached are in notCheckedUrls in the last row, ready for a new run a few hours later.
What happens if a run reaches its timeout?
The run stops about 30 seconds before its timeout and writes a last not-checked row. Rows already returned stay in the dataset. URLs it did not finish are not charged and are listed in notCheckedUrls. To read them, start a new run with those URLs, or set a longer timeout.
Why is isCommentsDisabled empty?
It is filled in only when Instagram states it on the post's page. Instagram usually leaves it out for visitors who are not logged in.
Rows you are not charged for
A URL that was read but did not return a post gets its own row, so you can see what happened to it. URLs the run did not check (past maxPosts, past the 1,000 URL limit, past the maximum total charge, stopped because Instagram refused most posts, or stopped before the run timeout) are counted in one last row, and notCheckedUrls lists them for a new run.
status | What it means |
|---|---|
sample | No URLs were given, so one sample post was read to show the output. Add your own URLs to urls. |
no-public-post | Instagram shows no public post at this address. It may be deleted, private or mistyped. |
blocked | Instagram did not let this run open the post. Run the URL again later; you were not charged. |
unreadable | The post could not be read in this run. |
invalid-input | The entry is not an Instagram post or reel URL, such as a profile link. For a /share/ link, open the link and paste the URL of the post. |
duplicate | The same post was already in this run's list. |
not-checked | One row at the end: how many entries were not read and why (past maxPosts, past the 1,000 URL limit, Instagram refused most posts, or the run was about to reach its timeout). The URLs are in notCheckedUrls. |
budget-reached | The run reached the maximum total charge you set. Entries it did not reach are counted in one row at the end, with their URLs in notCheckedUrls. |
viewCountStatus explains the videoPlayCount of each post, and it never changes the price:
viewCountStatus | What it means |
|---|---|
ok | videoPlayCount is filled in. |
not-in-recent-reels | The reel is not among the account's most recent reels, where plays are shown. |
plays-unavailable | The plays could not be read in this run. Try the URL again later; the post itself is still returned. |
not-requested | includeViewCounts is off. |
Limitations
- Instagram limits how many posts can be opened without logging in, so long lists may stop early. The rest are not charged and are listed in
notCheckedUrls. - Only public posts can be read. Private accounts and deleted posts return a free
no-public-postrow. videoPlayCountis available for an account's most recent reels, about the latest 12. Older reels return the row withviewCountStatus: "not-in-recent-reels".- Instagram does not show share, save or repost counts without a login, so they are not in the output.
- Comment text is not collected.
commentsCountis what Instagram shows to logged-out visitors. A0may not mean nobody commented, because comments can be turned off or hidden. musicInfoholds the song title and artist, or the creator's original audio.uses_original_audiosays which one it is. It is empty when Instagram gives no audio details for that reel.- Image and video URLs come from Instagram's CDN and expire after a while, so download the files soon after the run.
- Email addresses and phone numbers in captions, names, alt text and audio titles are masked in the output on a best-effort basis. Not every way of writing them can be caught, so some may remain. Masking can also go too far: a long number such as a reference code may be masked as well.
- Use the data in line with the rules that apply to you, including privacy law for any personal data in posts.
Need help or a missing field?
Open the Issues tab and tell us what you need. If a row looks wrong, include the run ID.
Thanks for using this Actor
We build these tools for people who run them every day, and we improve them from what users tell us.
- Missing a field, or need another filter? Tell us in the Issues tab. If the data is there, we add it.
- Found a bug or a wrong value? Post the run ID in the Issues tab. Wrong data is the thing we fix first.
If this Actor saved you time, a short review helps other people find it.