# Instagram Reel Scraper (`fetch_cat/instagram-reel-scraper`) Actor

Extract public Instagram Reel rows from direct Reel URLs, including visible metadata and warning fields when Instagram hides logged-out data.

- **URL**: https://apify.com/fetch\_cat/instagram-reel-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 item processeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Instagram Reel Scraper

Extract structured rows from public Instagram Reel URLs. This Actor is built for social listening, creator research, UGC campaign checks, and workflow automation where you need a repeatable dataset with one row per Reel.

### At a glance

- **Primary job**: Turn public Instagram Reel links into CSV, JSON, Excel, or API-ready dataset rows.
- **Input**: Direct public Reel URLs such as `https://www.instagram.com/reel/Da-2R72yymt/`.
- **Output**: Reel shortcode, canonical URL, caption/hashtags/mentions when visible, public metrics when visible, media URLs when visible, warnings, and per-input errors.
- **Best for**: Brand monitoring, creator/content research, short-video trend tracking, UGC QA, and enrichment pipelines.

### Input recipes

- **Single Reel smoke test**: Paste one public Reel URL and set `maxItems` to `1`.
- **Batch Reel export**: Paste multiple public Reel URLs and keep `maxItems` equal to the number of URLs you want processed.
- **Diagnostic monitoring**: Keep the `warnings`, `error`, and `errorDescription` columns in exports so hidden or unavailable Reels are easy to review.

### What data can you extract?

| Field | Description |
| --- | --- |
| `inputUrl` | Original URL from your input. |
| `id`, `shortCode` | Stable Reel shortcode used for deduplication. |
| `url` | Canonical Instagram Reel URL. |
| `caption` | Caption text when visible in the public payload. |
| `hashtags`, `mentions` | Tags and mentions parsed from visible public text. |
| `ownerUsername`, `ownerId` | Owner metadata when visible. |
| `timestamp` | Published timestamp when visible. |
| `likesCount`, `commentsCount`, `shareCount` | Public engagement metrics when visible. |
| `videoPlayCount` | Public play count when Instagram labels a value as plays. |
| `viewCount` | Compatibility field populated only when Instagram exposes a distinct view count; it is never copied from `videoPlayCount`. |
| `thumbnailUrl`, `videoUrl` | Public media URLs when exposed by Instagram. |
| `warnings` | Missing optional fields or degraded public payload notes. |
| `error`, `errorDescription` | Per-input error details for invalid, blocked, or unavailable URLs. |
| `fetchedAt` | ISO timestamp for the scrape. |

### Input configuration

| Setting | JSON key | Use it for | Example |
| --- | --- | --- | --- |
| Instagram Reel URLs | `startUrls` | Direct public Reel URLs to process. | `https://www.instagram.com/reel/Da-2R72yymt/` |
| Maximum reels | `maxItems` | Cap the number of unique Reel URLs processed. | `3` |
| Maximum runtime | `maxRuntimeSecs` | Stop early, save a checkpoint, and leave cleanup time before the platform timeout. | `270` |
| Proxy configuration | `proxyConfiguration` | Optionally use Apify Proxy when direct public access is limited. | Apify Proxy |

### Example input

```json
{
  "startUrls": [
    { "url": "https://www.instagram.com/reel/Da-2R72yymt/" }
  ],
  "maxItems": 1
}
```

### Example output

```json
{
  "inputUrl": "https://www.instagram.com/reel/Da-2R72yymt/",
  "id": "Da-2R72yymt",
  "shortCode": "Da-2R72yymt",
  "type": "reel",
  "url": "https://www.instagram.com/reel/Da-2R72yymt/",
  "caption": null,
  "hashtags": [],
  "mentions": [],
  "ownerUsername": null,
  "likesCount": null,
  "commentsCount": null,
  "videoPlayCount": null,
  "viewCount": null,
  "thumbnailUrl": null,
  "warnings": [
    "Caption was not visible in the public response.",
    "Direct-URL availability does not prove that this Reel is visible in the owner profile grid."
  ],
  "error": null,
  "errorDescription": null,
  "fetchedAt": "2026-07-14T10:22:26.244Z"
}
```

### Pricing

| Event | Free | Bronze | Silver | Gold | Platinum | Diamond | Charged when |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| Run start | `$0.005` | `$0.005` | `$0.005` | `$0.005` | `$0.005` | `$0.005` | Once when the Actor starts. |
| Item processed | `$0.00115` | `$0.00100` | `$0.00078` | `$0.00060` | `$0.00040` | `$0.00028` | Each successful Reel row saved to the dataset. |

Status rows for blocked, unavailable, or failed URLs are diagnostic output and do not trigger the item charge. The run-start event is charged only after input validation succeeds.

### Who is this for?

- **Social media teams** checking public Reel links from campaigns or creators.
- **Creator researchers** building a repeatable list of Reels for review.
- **Automation builders** who need one structured dataset row per Reel URL.
- **Analysts** who prefer explicit warnings over silent skips when public fields are hidden.

### Tips for best results

- **Use direct public Reel URLs**: Canonical `/reel/SHORTCODE/` and profile-prefixed `/USERNAME/reel/SHORTCODE/` links are accepted. Profile listing, hashtag, audio, location, and private routes are outside V1 scope.
- **Start small**: Test 1-3 URLs before larger batches.
- **Expect nullable fields**: Instagram frequently hides captions, metrics, owner details, or media URLs from logged-out public payloads.
- **Use warnings**: The `warnings` array explains degraded payloads without dropping the row.
- **Resume safely**: If the Actor reaches its runtime cutoff, resurrect the same run with the same input and storage. `RUN_CHECKPOINT` prevents already completed shortcodes from being processed twice.

### API usage

**Node.js**

```js
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("fetch_cat/instagram-reel-scraper").call({
  startUrls: [{ url: "https://www.instagram.com/reel/Da-2R72yymt/" }],
  maxItems: 1
});
console.log(run.defaultDatasetId);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("fetch_cat/instagram-reel-scraper").call(run_input={
    "startUrls": [{"url": "https://www.instagram.com/reel/Da-2R72yymt/"}],
    "maxItems": 1,
})
print(run["defaultDatasetId"])
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/fetch_cat~instagram-reel-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://www.instagram.com/reel/Da-2R72yymt/"}],"maxItems":1}'
```

### MCP and AI agents

Use this Actor from MCP-compatible tools through the official Apify MCP Server.

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=fetch_cat/instagram-reel-scraper"
```

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/instagram-reel-scraper"
    }
  }
}
```

Example prompt: "Run Instagram Reel Scraper on this Reel URL and summarize warnings and visible metrics."

### Limits and caveats

- **Public data only**: No login cookies, private accounts, private APIs, DMs, or paid source credentials are used.
- **Instagram can hide fields**: Missing optional fields are returned as `null` with warnings instead of guessed values.
- **Plays and views differ**: `videoPlayCount` and `viewCount` preserve Instagram's visible labels. The Actor does not alias plays into views.
- **Direct and profile visibility differ**: A Reel can be available by direct URL without appearing in the owner's profile grid.
- **Bounded retries**: Transient blocks and server failures are retried up to three times within the shared run deadline. Per-URL failures are isolated so other Reel URLs can still complete.
- **No video downloads in V1**: The Actor returns URLs when visible, not binary media files.

Every run writes `RUN_SUMMARY` to the default key-value store. A deadline-limited run also retains `RUN_CHECKPOINT`; resurrecting that run with the same storage resumes pending URLs. An unexpected all-error workload fails the run after saving uncharged diagnostic rows.

### FAQ

**Does this Actor log in to Instagram?**\
No. It only processes public Reel URLs and returns warning fields when Instagram hides optional data.

**Why are some fields null?**\
Instagram can hide captions, metrics, media URLs, or owner details from public logged-out pages. The Actor keeps the row and explains the missing data in `warnings`.

**Can I scrape profile reels?**\
Not in V1. Use direct public Reel URLs for the most predictable output.

### Related Actors

- [Instagram Profile Posts Scraper](https://apify.com/fetch_cat/instagram-profile-posts-scraper) — collect public profile post rows when profile pages are the source.
- [Instagram Stories Highlights Scraper](https://apify.com/fetch_cat/instagram-stories-highlights-scraper) — extract public story highlight rows.
- [TikTok Video Scraper](https://apify.com/fetch_cat/tiktok-video-scraper) — short-form video data from TikTok URLs.

### Legality and responsible use

Process only data you are allowed to access. Follow Instagram's terms, Apify's terms, and applicable laws.

### Support

Open an issue from the Actor page if a run fails or output looks wrong. Include the run ID or URL, input JSON, expected output, actual output, and a reproducible public URL such as `https://www.instagram.com/reel/Da-2R72yymt/`.

# Actor input Schema

## `startUrls` (type: `array`):

Direct public Instagram Reel URLs to scrape, including canonical /reel/ links and profile-prefixed /USERNAME/reel/ links. Private, deleted, or login-only Reels return error rows.

## `maxItems` (type: `integer`):

Maximum number of unique Reel URLs to process in this run.

## `maxRuntimeSecs` (type: `integer`):

Stop new requests early enough to save a checkpoint and run summary before the platform timeout. Resume with the same input to continue pending URLs.

## `proxyConfiguration` (type: `object`):

Optional proxy configuration. Leave empty for a direct request, or configure Apify Proxy when Instagram limits access from your runtime location.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.instagram.com/reel/Da-2R72yymt/"
    }
  ],
  "maxItems": 3,
  "maxRuntimeSecs": 270
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `checkpoint` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.instagram.com/reel/Da-2R72yymt/"
        }
    ],
    "maxItems": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/instagram-reel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.instagram.com/reel/Da-2R72yymt/" }],
    "maxItems": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/instagram-reel-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.instagram.com/reel/Da-2R72yymt/"
    }
  ],
  "maxItems": 3
}' |
apify call fetch_cat/instagram-reel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fetch_cat/instagram-reel-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/wK9jTbtvraYMMkrGE/builds/NmnJgnTkjmJsAVCsI/openapi.json
