Instagram Reels Scrapy 2.0
Pricing
from $0.30 / 1,000 results
Instagram Reels Scrapy 2.0
Quickly extract essential metadata from Instagram Reels (thumbnail, author, caption, duration, views, likes). Flexible input; comments and media downloads are optional. Lightweight, fast, and cost-effective — ideal for dashboards, clipping, and automations.
Pricing
from $0.30 / 1,000 results
Rating
0.0
(0)
Developer
Esdrasdw
Maintained by CommunityActor stats
1
Bookmarked
14
Total users
0
Monthly active users
3 hours ago
Last modified
Categories
Share
$0.05 per 1,000 results. Around 50x cheaper than the usual Instagram scraper.
Extract public Reels and posts from Instagram profiles — with view, like and comment counts — and get clean, structured rows you can drop straight into a spreadsheet, a dashboard or your own database.
Give it a list of profiles, say how many items you want from each, and run it. No login, no cookies, no browser automation on your side.
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.
What you get
For every item, the standard output includes the thumbnail, the caption's first line, the profile handle, the post URL, the publish date, view count, like count, comment count and duration. 32 more fields are available on demand — hashtags, mentions, tagged users, co-authors, carousel items, tagged location, sponsors, full caption, every video and thumbnail rendition, audio track details and more. 41 fields in total.
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 use it
- Put one or more profiles in Instagram profiles — a handle (
nasa) or a profile URL (https://www.instagram.com/nasa/). - 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.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
directUrls | array | ["https://www.instagram.com/nasa/"] | Profiles to scrape — 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 |
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 | standard 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
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 the 13 standard fields, from displayUrl to
id below (the form pre-selects the first nine). When you pick fields, you get
exactly those. Everything after id is opt-in: add it to selectedFields and
it shows up as an extra column.
| 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 (Reels mode only) |
likesCount | integer | Likes. -1 when the author hides them |
commentsCount | integer | Comments |
videoDuration | number | Length in seconds (Reels mode only) |
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 (Reels mode) |
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) | omitted | omitted |
photos | photos and carousels, no Reels | n/a (photos have none) | n/a |
For view counts, request reels.
You can download the dataset in JSON, CSV, Excel, HTML, XML or RSS.
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 unavailable | The handle does not exist, was renamed, or is not available to the public | Check the handle |
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.
What people use this for
- 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.
Frequently asked questions
Which content type should I pick?
reels if you want view counts and duration — it is the only mode Instagram
reports those for. posts for the whole timeline. photos for photos and
carousels with the Reels filtered out.
Why is videoPlayCount empty on posts and photos?
Those modes do not report play counts. Request reels when views matter.
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.
How much does it cost? $0.05 per 1,000 items, charged per item delivered. A run that returns nothing costs nothing.
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.