$0.05/1K - Instagram Reels Scrapy
Pricing
$0.10 / 1,000 results
$0.05/1K - Instagram Reels Scrapy
$0.05 per 1,000 results. Extract Reels and posts from public Instagram profiles with views, likes and comments. Export to JSON, CSV or Excel.
Pricing
$0.10 / 1,000 results
Rating
5.0
(2)
Developer
Esdrasdw
Maintained by CommunityActor stats
4
Bookmarked
89
Total users
4
Monthly active users
17 hours ago
Last modified
Categories
Share
What is Instagram Scraper?
High-quality Instagram data, delivered fast. Reels, posts and carousels from public profiles, with precise view, like and comment counts, in clean structured rows ready for a spreadsheet, a dashboard or a database.
⚡ Fast. Speed, agility and ease for your automations.
🥇 From $0.10 per 1,000 results on any paid Apify plan ($0.10 on the free plan).
What can this Instagram scraper do?
- 🥇 High-quality data. Numbers with full precision: views, likes, comments, video duration and publish date. Every item comes with the same clean, structured fields, with no gaps to patch later.
- ⚡ Speed. Several profiles at once, with no login and nothing to configure.
- 📅 Filter by date. Ask only for what was published since a date (the last 7 days, since January, since a campaign started) and the run stops as soon as it reaches older posts.
- 🧰 Versatile. Reels, the full timeline or photos only, up to 10,000 items per profile, and only the columns you choose.
- 🛡️ You only pay for what you get. Charged per item delivered. A run that returns nothing costs nothing.
What data can you extract from Instagram?
Every item includes all 41 fields by default: thumbnail, caption, profile
handle, post URL, publish date, view, like and comment counts, duration,
hashtags, mentions, tagged users, co-authors, carousel items, tagged location,
sponsors, every video and thumbnail rendition, audio track details and more.
Use selectedFields to keep only the columns you need.
You choose the columns. Ask for nine fields and you get nine clean columns instead of a wall of JSON you have to clean up later.
How to scrape Instagram profiles
- Put one or more profiles in Instagram profiles — a handle (
neymarjr),@neymarjror a profile URL (https://www.instagram.com/neymarjr/). - Pick the Content to scrape — Reels, the full timeline, or photos only.
- Set Results limit per profile.
- Optionally, narrow it down under Filters: a date range, or no pinned posts.
- Run it, then download the dataset as JSON, CSV, Excel or HTML.
How much does it cost to scrape Instagram?
| Free plan | Any paid Apify plan | |
|---|---|---|
| Results | $0.10 per 1,000 | $0.10 per 1,000 |
Charged per item delivered. A run that returns nothing costs nothing.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
directUrls | array | — | Profiles to scrape — handle, @handle or URL |
resultsType | string | reels | reels, posts (full timeline) or photos |
resultsLimit | integer | 100 | Maximum items per profile |
resultsLimitPerProfile | object | — | A different limit for specific profiles (API and saved tasks only) |
onlyPostsNewerThan | string | — | Only items published on or after this date |
skipPinnedPosts | boolean | false | Leave out posts pinned to the top of the profile |
selectedFields | array | all fields | Which columns to return |
Field names match the ones used by the standard Instagram scraper, so an input
written for that Actor also works here. resultsLimitPerProfile is the
addition. Handles are not case-sensitive, and
profile URLs may carry extra parts such as ?igsh=... or /reels/.
Example input
{"directUrls": ["nasa", "natgeo"],"resultsType": "reels","resultsLimit": 50,"selectedFields": ["url", "title", "videoPlayCount", "likesCount", "commentsCount"]}
A different limit for each profile
Not shown in the form: send it in the JSON input, over the API or in a saved
task. No need for one run per profile just to vary the limit. List the
exceptions in resultsLimitPerProfile; every other profile uses
resultsLimit:
{"directUrls": ["nasa", "natgeo", "instagram"],"resultsLimit": 100,"resultsLimitPerProfile": { "nasa": 2000, "instagram": 20 }}
That returns 2,000 items from nasa, 100 from natgeo and 20 from instagram, in a
single run. Keys accept a handle, @handle or profile URL, and a profile that
appears only in resultsLimitPerProfile is scraped too. Each limit goes from 1
to 10,000.
Filter by date
onlyPostsNewerThan takes:
- a date:
2024-01-31 - an ISO timestamp:
2024-01-31T18:00:00Z(no time zone means UTC) - a relative period:
3 days,2 weeks,6 months,1 year(alsominutesandhours)
All times are UTC, and the date itself is included:
{"directUrls": ["natgeo"],"resultsType": "posts","resultsLimit": 1000,"onlyPostsNewerThan": "2026-01-01"}
That returns everything natgeo published since January 1st, newest first, and stops as soon as it reaches older posts, in every content type.
resultsLimit counts only items that pass the filters. Items skipped on the
way are never delivered and never charged.
Pinned posts sit at the top of a profile regardless of their date. With a date
filter, a pinned post is returned only if its own date is inside the window. To
leave pinned posts out entirely, turn on skipPinnedPosts.
Output
{"displayUrl": "https://scontent.cdninstagram.com/v/t51.../image.jpg","title": "Coming out of my shell","ownerUsername": "nasa","url": "https://www.instagram.com/reel/DcEMvAdOryS/","timestamp": "2026-08-10T20:06:13","videoPlayCount": 1512492,"likesCount": 34514,"commentsCount": 291,"videoDuration": 79.5}
Photos and carousels have no view count, so videoPlayCount is omitted for
those items.
Every field you can request
With selectedFields empty you get every field below. When you pick fields,
you get exactly those.
| Field | Type | What it is |
|---|---|---|
displayUrl | string | Thumbnail image URL |
title | string | First line of the caption, trimmed |
ownerUsername | string | Profile handle, without @ |
url | string | Public post URL |
timestamp | string | Publish date, ISO 8601 |
videoPlayCount | integer | Plays (videos and Reels) |
likesCount | integer | Likes. -1 when the author hides them |
commentsCount | integer | Comments |
videoDuration | number | Length in seconds (videos and Reels) |
aspectRatio | string | For example 9:16 |
videoUrl | string | Highest quality video URL |
shortCode | string | Instagram short code |
id | string | Media ID, as <pk>_<ownerId> |
pk | string | Media PK on its own |
caption | string | Full caption text |
alt | string | Instagram's accessibility description, when it exists |
hashtags | array | Hashtags found in the caption |
mentions | array | Handles mentioned in the caption |
taggedUsers | array | Users tagged in the media |
coauthorProducers | array | Collab co-authors |
childPosts | array | Carousel items, one entry each |
locationName | string | Tagged place, when the post has one |
locationId | string | Tagged place ID, when the post has one |
ownerId | string | Owner numeric ID |
ownerFullName | string | Owner display name |
isPinned | boolean | Pinned to the top of the profile |
paidPartnership | boolean | Declared paid partnership |
sponsors | array | Handles tagged as sponsor |
affiliate | boolean | Affiliate content |
isCommentsDisabled | boolean | Comments turned off |
hasAudio | boolean | Carries an audio track |
musicInfo | object | Audio track details |
productType | string | clips, feed, carousel_container |
type | integer | Instagram media type |
originalWidth / originalHeight | integer | Source dimensions |
images | array | Every thumbnail size |
videoVersions | array | Every video rendition |
dashManifest | string | DASH manifest |
spritesheet | object | Scrubbing sprite sheet |
igPlayCount | integer | Instagram play counter (videos and Reels) |
Fields Instagram does not return are left out of the item instead of being sent
as 0 or "", so an empty column means "not reported", never "zero".
Content types, and which counts come with each
resultsType | What you get | videoPlayCount | videoDuration |
|---|---|---|---|
reels | Reels only | yes | yes |
posts | the full timeline (Reels, photos, carousels) | yes, for videos | yes, for videos |
photos | photos and carousels, no Reels | n/a (photos have none) | n/a |
You can download the dataset in JSON, CSV, Excel, HTML, XML or RSS.
How to use the API
Every run is available over the Apify API. Replace <TOKEN> with your API
token from Settings → Integrations.
Run and wait for the results
Returns the dataset items directly, in one call:
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"directUrls": ["nasa"],"resultsType": "reels","resultsLimit": 50}'
Best for small and medium jobs. The connection stays open until the run ends, so keep a generous client timeout.
Start a run and collect later
For large jobs, start the run and poll for it:
# 1. startcurl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/runs?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"directUrls": ["nasa"], "resultsLimit": 5000}'# 2. check status — look for "status": "SUCCEEDED"curl "https://api.apify.com/v2/actor-runs/<RUN_ID>?token=<TOKEN>"# 3. fetch the itemscurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&format=csv"
Python
from apify_client import ApifyClientclient = ApifyClient("<TOKEN>")run = client.actor("<ACTOR_ID>").call(run_input={"directUrls": ["nasa"],"resultsType": "posts","resultsLimit": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["url"], item.get("likesCount"))
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<TOKEN>' });const run = await client.actor('<ACTOR_ID>').call({directUrls: ['nasa'],resultsType: 'reels',resultsLimit: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.length);
Run summary
Besides the dataset, each run writes an OUTPUT record to the key-value store
with a per-profile summary:
{"ok": true,"total_items": 150,"users": [{ "user": "nasa", "count": 100 },{ "user": "natgeo", "count": 50 }]}
When a profile cannot be completed, its entry carries an error field and the
items already collected stay in the dataset. The error is one of:
error | What it means | What to do |
|---|---|---|
profile not found, or restricted to logged-in users (for example, age-restricted) | The handle does not exist, was renamed, or is visible only to logged-in users (age-restricted accounts) | Check the handle; restricted profiles cannot be collected without login |
profile is private | The profile is private | Nothing — only public profiles can be read |
no public items found (the profile may be private or have none) | Nothing public came back for this content type | Check the profile or the content type |
could not be collected right now, please try again later | A temporary problem on Instagram's side | Run that profile again later |
collection stopped early, please try again later for the rest | Some items were collected, then a temporary problem stopped it | Run again later for the rest |
collection stopped before the end of this profile; items collected so far are in the dataset | The run reached its page limit for this profile, for example a very old date filter on a large profile | Narrow the date range, or split it into several runs |
not a valid Instagram profile | The entry is not a handle or profile URL (for example a post link) | Fix the entry |
the run time limit was reached before this profile finished; items collected so far are in the dataset | The run's timeout arrived mid-profile | Give the run a longer timeout |
not started: run time limit reached | The timeout arrived before this profile's turn | Give the run a longer timeout |
Sizing the timeout. Reels mode collects roughly 150 reels per minute per profile. A run asking for 2,000 reels needs about 15 minutes, so a 10-minute timeout will stop it early. When the timeout is close, the run stops on its own, writes this summary and finishes as Succeeded, keeping everything collected so far.
When a profile has a problem, the run's status line says so.
Legacy input names
Inputs with the previous names (usernames, content_type,
quantity_per_user, selected_fields) still run. The log shows the current
names.
Use cases
- Influencer vetting: reach versus engagement over the last Reels.
- Content research: which formats, hashtags and sounds perform.
- Period reports for a month, quarter or campaign.
- Daily monitoring with
onlyPostsNewerThan: "1 day". - Sponsored content:
paidPartnership,sponsorsandtaggedUsers.
Other Actors
| Actor | What it does |
|---|---|
| TikTok Scraper | Videos from public TikTok profiles, with views, likes, comments, shares and saves, plus comment text and replies |
Frequently asked questions
Which content type should I pick?
reels for Reels only. posts for the whole timeline, with views and
duration on every video. photos for photos and carousels with the Reels
filtered out.
Why is videoPlayCount empty on some items?
Photos and carousels have no view count. On a video it is empty only when
Instagram does not report it for that item.
Why is likesCount sometimes -1?
The author hid the like count on that post.
Can I scrape private profiles?
No. Only public profiles return data. A private profile is skipped and marked
in OUTPUT (as profile is private, or as having no public items), and the
rest of the run continues.
What happens if one profile fails?
The other profiles keep going. Items already collected stay in the dataset, and
the OUTPUT record marks that profile with an error field.
Can I ask for more items than the profile has? Yes. You get everything available and the run ends normally.
Do I need a proxy or a login? No. There is nothing to configure — no cookies, no session, no browser.
How do I get only recent posts?
Set onlyPostsNewerThan, for example to 7 days.
Why is the result smaller than my resultsLimit?
With a date filter, you get everything since that date up to the limit. If
the profile published fewer items in that period, that is all there is.
How many items can one run get from a very large profile?
In Posts mode, typically 1,500 to 2,000 items per run. OUTPUT says when a
profile stops early.
How do I exclude pinned posts?
Turn on skipPinnedPosts. Posts pinned to the Reels tab count as pinned too.
Can I get comment text?
No. This Actor returns media and its metrics, including commentsCount, but
not the comments themselves.
Is this affiliated with Instagram? No. See the disclaimer at the bottom.
Notes and limits
- Only public profiles are supported. Private accounts return no items.
- A profile that is unavailable is skipped with a warning; the other profiles in the same run continue normally.
- Requesting more items than a profile has simply returns everything available.
Support
Found a bug or need a field that is not on the list? Open an issue on the Actor's Issues tab with the input you used and the run ID.
Disclaimer
This is an unofficial tool and is not affiliated with, endorsed by, or sponsored by Instagram or Meta Platforms, Inc. It collects only publicly available content. You are responsible for how you use the data, including compliance with applicable laws and the target site's terms.