Instagram Reels Engagement Scraper
Pricing
Pay per usage
Instagram Reels Engagement Scraper
Collects engagement metrics (views, likes, shares, saves, and publisher username) for Instagram Reels.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Dwi Wahyu
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
An Apify Actor built in TypeScript with the Apify SDK and Crawlee that collects engagement metrics for Instagram Reels.
Features & Scope
Accepts one or more Instagram Reel URLs (https://www.instagram.com/reel/<id>/ or /reels/<id>/) and returns strictly the following engagement metrics per Reel:
publisherUsername— Account username of the Reel creatorviews— Video view / play countlikes— Like countshares— Share / reshare count (nullwhen not publicly available)saves— Save / bookmark count (nullwhen not publicly available)
Strict Scope Guarantees
- No extraneous data: Does not scrape or store captions, comments, audio tracks, hashtags, or media files.
- No fabricated numbers: Any metric that is not publicly available or is hidden by the creator is returned as
null— values are never estimated or guessed. - URL normalization & deduplication: Strips query parameters, hash fragments, and trailing slashes (
https://www.instagram.com/reel/<id>), deduplicating repeated Reel URLs in a single run. - Every input accounted for: Invalid URLs (non-Instagram domains, profile links, regular
/p/posts, stories) or deleted/private Reels do not crash the run — they produce a structured dataset item with a descriptiveerrorfield andnullmetrics.
Input
The Actor input is defined in ./.actor/input_schema.json (and ./INPUT_SCHEMA.json):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
reelUrls | string[] | Yes | — | One or more Instagram Reel URLs (https://www.instagram.com/reel/<id>/ or /reels/<id>/). |
proxyConfiguration | object | No | { "useApifyProxy": true } | Apify Proxy configuration. Use Residential proxies if plain requests are blocked or rate-limited. |
maxConcurrency | integer | No | 4 | Number of Reel URLs processed in parallel (1–10). |
sessionCookie | string (secret) | No | — | Optional Instagram sessionid cookie value if login is required for restricted targets. Encrypted and never logged or stored. |
Example Input
{"reelUrls": ["https://www.instagram.com/reel/DQWxAjPjI32/","https://www.instagram.com/reel/C5QuBSkux6R/","https://www.instagram.com/reel/DTq4oW2kfPx/"],"proxyConfiguration": {"useApifyProxy": true},"maxConcurrency": 4}
Output
The Actor stores one item per deduplicated Reel URL in the default Apify Dataset, rendered as a table in the Apify Console via ./.actor/dataset_schema.json.
Output Schema
{"reelUrl": "string","publisherUsername": "string | null","views": "number | null","likes": "number | null","shares": "number | null","saves": "number | null","scrapedAt": "ISO 8601 string","error": "string | null"}
Example Output
[{"reelUrl": "https://www.instagram.com/reel/DQWxAjPjI32","publisherUsername": "iammattjupp","views": 2595,"likes": 99,"shares": null,"saves": null,"scrapedAt": "2026-10-18T14:55:00.000Z","error": null},{"reelUrl": "https://www.instagram.com/reel/C5QuBSkux6R","publisherUsername": "shinewithnatasha","views": 1536,"likes": 150,"shares": null,"saves": null,"scrapedAt": "2026-10-18T14:55:01.000Z","error": null},{"reelUrl": "https://www.instagram.com/reel/DTq4oW2kfPx","publisherUsername": "itszachford","views": 179,"likes": 6,"shares": null,"saves": null,"scrapedAt": "2026-10-18T14:55:02.000Z","error": null},{"reelUrl": "https://www.instagram.com/p/INVALID_POST_URL/","publisherUsername": null,"views": null,"likes": null,"shares": null,"saves": null,"scrapedAt": "2026-10-18T14:55:00.000Z","error": "Invalid Instagram Reel URL: path must match /reel/<id>/ or /reels/<id>/."}]
How It Works
- Input Normalization & Deduplication: Validates each URL against Instagram Reel path patterns (
/reel/<id>and/reels/<id>), strips query strings and trailing slashes, and deduplicates URLs. - Embedded JSON & GraphQL Extraction (Primary):
- Fetches Instagram's embed endpoint (
/p/<id>/embed/captioned/) and extracts the embeddedcontextJSON(gql_data.shortcode_media) and DOM metadata. - Queries the main Reel page (
/reel/<id>/) and Instagram's GraphQL endpoint (/graphql/query) when additional fields are needed or when an optionalsessionCookieis provided.
- Fetches Instagram's embed endpoint (
- Browser Fallback (Secondary):
- Falls back to headless Puppeteer only if plain HTTP requests are blocked or fail to return embedded data.
- Retries with Exponential Backoff:
- Processes URLs in parallel (default concurrency
4) and retries failed requests up to3times with exponential backoff.
- Processes URLs in parallel (default concurrency
Local Development & Testing
# Install dependenciesnpm install# Run unit testsnpm test# Build TypeScriptnpm run build# Run Actor locally using Apify CLIapify run
Deployment to Apify Platform
# 1. Authenticate with your Apify accountapify login# 2. Deploy the Actor to the Apify platformapify push
Summary of Metric Availability
| Metric | Public Availability | Notes |
|---|---|---|
publisherUsername | Obtainable | Extracted from shortcode_media.owner.username, Embed DOM, or OpenGraph/Twitter meta tags. |
views | Obtainable | Extracted as exact integer from shortcode_media.video_view_count / video_play_count (null if hidden by creator). |
likes | Obtainable | Extracted as exact integer from shortcode_media.edge_liked_by.count / like_count (null if hidden by creator). |
shares | Returns null publicly | Instagram does not expose reshare_count publicly without creator/authenticated API access; returns null when unavailable. |
saves | Returns null publicly | Instagram does not expose save_count publicly outside Instagram Insights; returns null when unavailable. |