# Instagram Posts Reels Scraper (`monknwarriors/instagram-posts-reels-scraper`) Actor

Scrape every post or reel from any public Instagram profile — captions, hashtags, mentions, likes, comments, reel play counts, image and video URLs, collaborators and tagged users. No login required.

- **URL**: https://apify.com/monknwarriors/instagram-posts-reels-scraper.md
- **Developed by:** [Monk N Warriors](https://apify.com/monknwarriors) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 post or reel scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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 Posts & Reels Scraper

Scrape every post or reel from any public Instagram profile: captions,
hashtags, mentions, likes, comments, **reel play counts**, image and video
URLs, video length, collaborators, tagged accounts, location and audio.
Paste one username or a thousand.

You don't need an Instagram login, cookies or an account. Results come
back **newest-first, with pinned posts on top**, in the same order
Instagram shows them.

### How to use it

1. Add one or more profiles under **Instagram usernames or profile URLs**:
   `therock`, `@therock` or `https://www.instagram.com/therock/`. Use
   **Bulk edit** to paste a long list.
2. Choose **What to scrape**:
   - **Posts**: everything on the profile grid (photos, carousels and
     reels).
   - **Reels only**: the profile's Reels tab, including reels that aren't
     shown on the grid.
3. Optionally set **Max items per profile**, and/or **Only posts newer
   than** (a date like `2026-01-31`, or a period like `7 days` or
   `3 months`).
4. Run it.

### What you get

One row per post or reel:

| Field | Example |
|---|---|
| `url` / `shortCode` | `https://www.instagram.com/p/Dcw0BfjB_nX/` / `Dcw0BfjB_nX` |
| `type` | `Image`, `Video` or `Sidecar` (carousel) |
| `isReel` / `isPinned` | `true` / `false` |
| `caption` | `I’m inspired to build @projectrock to new levels. Embrace the hard things. …` |
| `hashtags` | `ProjectRock` |
| `mentions` | `projectrock` |
| `timestamp` | `2026-09-01T23:25:57Z` (ISO 8601, UTC) |
| `likesCount` / `commentsCount` | `107958` / `1778` |
| `videoPlayCount` | `3158146` (reels) |
| `videoDuration` | `169.625` (seconds) |
| `displayUrl` / `videoUrl` | highest-resolution image and video file |
| `carouselMediaCount` / `carouselMediaUrls` | `14` / every slide's URL, separated by `\|` (carousels only) |
| `ownerUsername` / `ownerFullName` / `ownerId` | `therock` / `Dwayne Johnson` / `232192182` |
| `coauthorUsernames` | `projectrock` (collab posts) |
| `taggedUsernames` | `projectrock` — accounts tagged in the photo or video, across every carousel slide |
| `locationName` / `locationId` | tagged location |
| `audioTitle` / `audioArtist` | `Original audio` / `therock` |
| `isPaidPartnership` | `false` |

Every row has exactly the same columns, and list values like hashtags and
tagged users are joined into a single cell. The CSV and Excel exports are
clean, with no empty or `undefined` columns.

**Who's in a post.** Each person is reported in the column matching how
they appear:

- a **collab co-author** goes in `coauthorUsernames`
- someone **tagged in the photo or video** goes in `taggedUsernames`
- someone **@mentioned in the caption** goes in `mentions`

One account can appear in all three.

#### Run report

The key-value store record **`RUN_REPORT`** lists, for each profile:

- how many items were scraped
- whether the item limit or date limit was reached
- the profile's full name, follower count and verified badge
- a clear reason for any profile that couldn't be scraped (doesn't exist,
  or is private)

### Good to know

- **Public profiles only.** A private account, or a handle that doesn't
  exist, is reported in `RUN_REPORT` and costs you nothing.
- **Collab posts** can list the partner account as `ownerUsername`, when
  the partner created the post and invited this profile. The
  `profileUsername` column always shows which profile you scraped.
- **Hidden reels.** A reel that the creator removed from their grid still
  shows on the Reels tab. Instagram gives little detail about those to
  logged-out visitors, so their caption, author and tag columns are empty,
  and `hasFullDetails` is `false`. Plays, likes, comments, image and posting
  date are still filled in.
- **Play counts, occasionally missing.** For a few profiles, Instagram's
  Reels tab errors on its side. Their posts and reels are still scraped in
  full, but `videoPlayCount` is empty, and `RUN_REPORT` shows the reason
  under `reelsTabError`.
- **Media URLs expire.** Instagram's image and video links stop working
  after a few days, so download files promptly if you need them.
- Counts are a snapshot taken at scrape time.
- **Use a residential proxy.** Instagram limits requests by IP address. The
  default residential proxy setting is strongly recommended for anything
  beyond a small test.
- Only posts and reels are included. A profile's **tagged** tab and
  **reposts** tab aren't available without logging in, so this Actor
  doesn't scrape them.

### Pricing

**Pay per result.** You pay for:

- each post or reel written to the dataset
- a small one-time fee for each profile that returns at least one result

A profile that is private, missing, or has nothing in your date range costs
nothing. See the Pricing tab for the current rates.

### Questions or issues?

Use the **Issues** tab on this Actor's page and share your run. That's the
fastest way to get a fix. This Actor is independently built and isn't
affiliated with Instagram or Meta. You're responsible for using the data in
line with the law where you are.

# Actor input Schema

## `usernames` (type: `array`):

One or more public Instagram profiles. Accepts a username (therock), @therock, or a profile link like https://www.instagram.com/therock/. Use Bulk edit to paste a long list.

## `resultsType` (type: `string`):

Posts: everything on the profile grid — photos, carousels and reels, newest first. Reels: only the profile's Reels tab, newest first, including reels that aren't shown on the grid.

## `resultsLimit` (type: `integer`):

Stop after this many posts (or reels) for each profile. Leave empty to scrape everything. Pinned posts come first, as on Instagram.

## `onlyPostsNewerThan` (type: `string`):

Skip anything posted before this date. Pick a date (e.g. 2026-01-31) or a relative period (e.g. 7 days, 3 months). Pinned posts older than this are skipped too. Leave empty for no date limit.

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

Instagram rate-limits datacenter and un-proxied IPs quickly. Residential proxy is strongly recommended and is the default.

## Actor input object example

```json
{
  "usernames": [
    "instagram"
  ],
  "resultsType": "posts",
  "resultsLimit": 12,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `posts` (type: `string`):

The default dataset — one row per post or reel: caption, hashtags, mentions, likes, comments, reel play count, image and video URLs, collaborators, tagged users and more.

## `postsCsv` (type: `string`):

The same data as a spreadsheet-friendly CSV file.

## `runReport` (type: `string`):

Per-profile outcome: items scraped, whether a limit was hit, follower count, and a clear reason for any profile that couldn't be scraped.

# 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 = {
    "usernames": [
        "instagram"
    ],
    "resultsLimit": 12
};

// Run the Actor and wait for it to finish
const run = await client.actor("monknwarriors/instagram-posts-reels-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 = {
    "usernames": ["instagram"],
    "resultsLimit": 12,
}

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

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

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

```

## CLI example

```bash
echo '{
  "usernames": [
    "instagram"
  ],
  "resultsLimit": 12
}' |
apify call monknwarriors/instagram-posts-reels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,monknwarriors/instagram-posts-reels-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tm1KpUV4cobUod114/builds/vqSFHOXxnRhUZaKPF/openapi.json
