# Instagram Posts Scraper (Reels, Likes, Views, Captions) (`juliob.rangel/instagram-posts-scraper-fast`) Actor

Get the posts and reels of any public Instagram profile, with pagination and date filter: caption, hashtags, mentions, likes, comments, video views, date, type, images, video URL, location, tagged users and collabs. No login. Export to Excel, CSV or JSON.

- **URL**: https://apify.com/juliob.rangel/instagram-posts-scraper-fast.md
- **Developed by:** [Julio Barcellos Rangel](https://apify.com/juliob.rangel) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 post scrapeds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Posts Scraper (Reels, Likes, Views, Captions)

Instagram Posts Scraper collects the posts and reels of any public Instagram profile, page after page, with an optional date filter: caption, hashtags, mentions, likes, comments, video views, date, type, image and video links, location, tagged users and collab authors. It is a fast Instagram post scraper for marketers, agencies and researchers who track brands, creators and competitors. Use it to export Instagram posts to Excel, CSV or JSON, or as an Instagram reels scraper for view counts, with no login.

### What does Instagram Posts Scraper do?

You give it a list of Instagram profiles. For each one, the scraper reads the profile's public feed, newest first, 12 posts per page, and keeps going until it reaches your limit, your start date, or the end of the feed. Each post or reel becomes one row.

It accepts these forms, mixed in the same list:

| Input form | Example |
|---|---|
| Username | `nike` |
| Username with @ | `@natgeo` |
| Profile URL | `https://www.instagram.com/nasa/` |

Every line is turned into a lowercase username and duplicates are removed, so `NASA`, `@nasa` and `https://www.instagram.com/nasa/` count as one profile.

Each row holds the post's text (caption, plus the hashtags and @mentions found in it), its numbers (likes, comments, video views, video length, number of carousel slides), its media (cover image and video file links), when it was posted, where (location), who is in it (tagged users and collab authors), and flags for pinned posts and paid partnerships. You do not need an Instagram account, cookies or an API key.

### What data can you extract?

| Field | What it means | Example |
|---|---|---|
| `input` | The profile you asked for, as a username | `nike` |
| `postId` | Instagram's numeric post ID | `4003644396204241217` |
| `shortcode` | Short code used in the post link | `DePzV26vLFB` |
| `url` | Link to the post or reel | `https://www.instagram.com/reel/DePzV26vLFB/` |
| `type` | `image`, `video`, `reel` or `carousel` | `reel` |
| `caption` | Full caption text | `Five MVPs.\nAt some point, it stops being a debate…` |
| `hashtags` | Hashtags found in the caption, without `#` | `["NASA", "Space", "Stars"]` |
| `mentions` | Accounts @mentioned in the caption, without `@` | `["aja22wilson"]` |
| `takenAt` | When the post was published (ISO 8601) | `2026-10-08T20:34:27.000Z` |
| `likes` | Number of likes, or `null` when the owner hid them | `72787` |
| `comments` | Number of comments | `1647` |
| `views` | Video play count (videos and reels only) | `1806288` |
| `likesHidden` | The owner hid the like and view counts | `false` |
| `videoDurationSeconds` | Video length in seconds (videos and reels only) | `30` |
| `imageUrl` | Image link: the photo, the video cover or the first carousel slide | `https://scontent-ord5-1.cdninstagram.com/v/…` |
| `videoUrl` | Video file link (MP4), for videos and reels | `https://scontent-ord5-2.cdninstagram.com/o1/v/…mp4?…` |
| `carouselCount` | Number of slides in a carousel | `6` |
| `location` | Name of the tagged location | `New York` |
| `locationId` | Instagram ID of that location | `317742662473550` |
| `taggedUsers` | Usernames tagged in the media | `["aja22wilson", "nikebasketball"]` |
| `coauthors` | Usernames of collab (co-author) accounts | `["nikebasketball"]` |
| `isPinned` | The post is pinned to the top of the profile | `false` |
| `isPaidPartnership` | Marked as a paid partnership | `false` |
| `ownerUsername` | Username of the account that owns the post | `nike` |
| `ownerFullName` | Display name of the owner | `Nike` |
| `ownerVerified` | The owner has the verified badge | `true` |
| `scrapedAt` | When the row was collected | `2026-10-11T20:16:06.841Z` |
| `error` | Only on error rows: why no posts were returned | `Profile not found, private or without posts` |

Counts are real numbers, so you can sort and compute engagement in Excel or Google Sheets right away. Empty values come as `null`, and empty lists as `[]`.

### How to use Instagram Posts Scraper

1. Open Instagram Posts Scraper in Apify Console (sign in or create a free Apify account).
2. In **Profiles**, paste usernames or profile URLs, one per line.
3. Set **Max posts per profile** (default 24, up to 5,000).
4. Optional: pick a date in **Only posts newer than** to get recent posts only.
5. Click **Start**. The log shows how many posts each profile returned.
6. Open the **Output** tab to see the table, then click **Export** to download the data as JSON, CSV, Excel or HTML.
7. Optional: save the input as a task and add a schedule (for example daily) to collect new posts from the same profiles.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `profiles` | array of strings (required) | `["nike"]` | Instagram usernames or profile URLs, for example `nike`, `@natgeo`, `https://www.instagram.com/nasa/`. |
| `maxPostsPerProfile` | integer, 1 to 5,000 | `24` | Max posts per profile. Newest first; pinned posts come first, as on Instagram. |
| `onlyPostsNewerThan` | date (YYYY-MM-DD) | none | Optional. Keeps only posts published on or after this date and stops when older posts are reached. |
| `proxy` | object | `{"useApifyProxy": true}` | Apify Proxy settings. |

A plain username can be up to 30 characters of letters, numbers, underscores and dots. Links to single posts, reels, stories or the Explore page are not profiles, so those lines are skipped.

Example input that gets up to 100 posts from each of three profiles, published since 1 September 2026:

```json
{
  "profiles": [
    "nike",
    "@natgeo",
    "https://www.instagram.com/nasa/"
  ],
  "maxPostsPerProfile": 100,
  "onlyPostsNewerThan": "2026-09-01",
  "proxy": {
    "useApifyProxy": true
  }
}
```

### Output example

A real row from the latest run (the image and video links are shortened):

```json
{
  "input": "nike",
  "postId": "4003644396204241217",
  "shortcode": "DePzV26vLFB",
  "url": "https://www.instagram.com/reel/DePzV26vLFB/",
  "type": "reel",
  "caption": "Five MVPs.\nAt some point, it stops being a debate and starts being a pattern.\nCongrats, @aja22wilson",
  "hashtags": [],
  "mentions": ["aja22wilson"],
  "takenAt": "2026-10-08T20:34:27.000Z",
  "likes": 72787,
  "comments": 1647,
  "views": 1806288,
  "likesHidden": false,
  "videoDurationSeconds": 30,
  "imageUrl": "https://scontent-ord5-1.cdninstagram.com/v/t51.82787-15/840881769_18671823154020081_1639312122082324346_n.jpg?…",
  "videoUrl": "https://scontent-ord5-2.cdninstagram.com/o1/v/t2/f2/m86/AQMjjjt42-K3klG6NsCE7zIcCeYryx1Y2ShJf….mp4?…",
  "carouselCount": null,
  "location": null,
  "locationId": null,
  "taggedUsers": ["aja22wilson", "nikebasketball"],
  "coauthors": ["nikebasketball"],
  "isPinned": false,
  "isPaidPartnership": false,
  "ownerUsername": "nike",
  "ownerFullName": "Nike",
  "ownerVerified": true,
  "scrapedAt": "2026-10-11T20:16:06.841Z"
}
```

An error row looks like this and is not charged:

```json
{
  "input": "this.profile.does.not.exist",
  "error": "Profile not found, private or without posts"
}
```

### How much does it cost?

Instagram Posts Scraper uses pay per event pricing. You pay **$1.00 per 1,000 posts** returned ($0.001 per post or reel) on the Free plan. Platform usage (compute and proxy) is included in that price.

| Apify plan | Price per 1,000 posts |
|---|---|
| Free | $1.00 |
| Bronze (10% off) | $0.90 |
| Silver (20% off) | $0.80 |
| Gold and higher (30% off) | $0.70 |

Worked examples on the Free plan:

- 1 profile with the default 24 posts = **$0.024**
- 100 profiles × 50 posts = 5,000 posts = **$5.00**
- 20 competitors × 30 new posts a month, for 12 months = 7,200 posts = **$7.20** ($5.04 on Gold)

What you are **not** charged for:

- Error rows ("Profile not found, private or without posts" and "Instagram did not respond, try again later").
- Posts older than your `onlyPostsNewerThan` date, which are dropped before saving.
- Retries, duplicate profiles and skipped lines.

### Use cases

- **Competitor monitoring.** Follow what competing brands post, how often, and which formats (reel, carousel, image) get the most likes and comments.
- **Influencer vetting.** Check a creator's recent posts, real engagement per post, paid partnership flags and the brands they tag or collab with.
- **Campaign reporting.** Collect every post since the campaign start date with `onlyPostsNewerThan`, then sum likes, comments and views.
- **Reels analytics.** Compare reel view counts and video length to see what length works for an account.
- **Hashtag and mention research.** Use the `hashtags` and `mentions` lists to see which tags and partners an account uses most.
- **Content archives.** Save captions, dates and media links of a brand's feed for audits and content libraries.
- **Location insights.** Find which posts are tagged with a place and group them by `location`.

### Tips and limits

- **Public profiles only.** Private profiles, missing profiles and profiles with no posts return one error row: "Profile not found, private or without posts".
- **Date filter details.** Posts come newest first. With `onlyPostsNewerThan`, the scraper stops at the first older post that is not pinned. Pinned posts are kept even when they are older than the date, because Instagram shows them first. If no post passes the date filter, you get the same error row as above.
- **Pinned posts count toward the limit.** They come first, as on Instagram. Check `isPinned` if you want to leave them out of your analysis.
- **Collab posts.** Posts made in collaboration can show up on a profile while another account owns them. `input` is always the profile you asked for, and `ownerUsername` is the real owner.
- **Hidden likes.** When the owner hid like counts, `likes` is `null` and `likesHidden` is `true`.
- **Views only for videos.** `views` and `videoDurationSeconds` are `null` for images and carousels. For carousels, `imageUrl` is the first slide and `videoUrl` is `null`.
- **No comment texts.** You get the number of comments, not the comments themselves.
- **Media links expire.** `imageUrl` and `videoUrl` are temporary Instagram CDN links. Download the files soon if you need to keep them.
- **Retries.** Each page gets up to 8 tries with a 30-second timeout. If Instagram does not answer at all for a profile, you get the error row "Instagram did not respond, try again later". If it stops answering after some pages, you keep the posts already collected.
- **Skipped lines.** Lines that are not a username or profile URL produce no row, so compare the row count with your list if something seems missing.

### Use it from the API, Python or JavaScript

JavaScript (Node.js) with the official `apify-client` package:

```javascript
const { ApifyClient } = require('apify-client');

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const input = { profiles: ['nike', 'https://www.instagram.com/nasa/'], maxPostsPerProfile: 50 };

(async () => {
    const run = await client.actor('juliob.rangel/instagram-posts-scraper-fast').call(input);
    const { items } = await client.dataset(run.defaultDatasetId).listItems();
    console.log(items);
})();
```

Python with the official `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')
run_input = {'profiles': ['nike'], 'maxPostsPerProfile': 200, 'onlyPostsNewerThan': '2026-09-01'}

run = client.actor('juliob.rangel/instagram-posts-scraper-fast').call(run_input=run_input)
items = client.dataset(run['defaultDatasetId']).list_items().items
for item in items:
    print(item.get('type'), item.get('likes'), item.get('views'), item.get('url'))
```

The scraper also works with Make, Zapier and n8n, can export results to Google Sheets, can call your webhook when a run finishes, and can be used by AI agents through the Apify MCP server.

### FAQ

#### Do I need an Instagram login, cookies or an API key?

No. The scraper reads public profile feeds without logging in. You only need an Apify account to run it.

#### Can I export Instagram posts to Excel or CSV?

Yes. After the run, open the Output tab and export the dataset as Excel, CSV, JSON or HTML, or read it through the API.

#### How many posts can I get per profile?

Up to 5,000 per profile with `maxPostsPerProfile`, as long as the profile has that many posts and Instagram keeps answering.

#### Does it scrape reels?

Yes. Reels come with `type` set to `reel`, their play count in `views`, their length in `videoDurationSeconds` and the video file in `videoUrl`.

#### Is it legal to scrape Instagram?

The scraper only collects publicly available data. You are responsible for complying with Instagram's terms and with privacy laws such as GDPR and LGPD. Posts can contain personal data (names, faces, tagged users), so you need a legitimate reason to collect and use it.

#### Why did I get a row with an `error` field?

The profile does not exist, is private, has no posts (or none newer than your date), or Instagram did not answer after 8 tries. Error rows are not charged. Check the username and run it again later.

#### Can I scrape a single post or a hashtag?

No. The input is a list of profiles. Single post links, reel links and hashtag pages are not supported.

### Related scrapers

- [Instagram Profile Stats Scraper (Followers, Bio, Posts)](https://apify.com/juliob.rangel/instagram-profile-stats)
- [TikTok Video Scraper (Views, Likes, Comments, Shares)](https://apify.com/juliob.rangel/tiktok-video-scraper-fast)
- [Threads Scraper (Profiles, Posts, Search)](https://apify.com/juliob.rangel/threads-scraper-fast)
- [YouTube Shorts Scraper (Channels & Hashtags)](https://apify.com/juliob.rangel/youtube-shorts-scraper)
- [YouTube Channel Videos Scraper (Fast & Cheap)](https://apify.com/juliob.rangel/youtube-channel-videos)
- [Pinterest Search Scraper (Pins, Images, Links, Boards)](https://apify.com/juliob.rangel/pinterest-search-scraper-fast)

***

## Extrator de Posts do Instagram (PT-BR)

Colete posts e reels de qualquer perfil público do Instagram, com paginação e filtro de data, sem login: legenda, hashtags, curtidas, comentários, visualizações de vídeos, data, tipo, imagens e links. Você paga só por post retornado.

# Actor input Schema

## `profiles` (type: `array`):

Instagram usernames or profile URLs, e.g. nike, @natgeo, https://www.instagram.com/nasa/

## `maxPostsPerProfile` (type: `integer`):

Newest first (pinned posts come first, as on Instagram).

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

Optional date (YYYY-MM-DD). Stops when older posts are reached.

## `proxy` (type: `object`):

Apify Proxy settings.

## Actor input object example

```json
{
  "profiles": [
    "nike"
  ],
  "maxPostsPerProfile": 24,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "profiles": [
        "nike"
    ],
    "maxPostsPerProfile": 24
};

// Run the Actor and wait for it to finish
const run = await client.actor("juliob.rangel/instagram-posts-scraper-fast").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 = {
    "profiles": ["nike"],
    "maxPostsPerProfile": 24,
}

# Run the Actor and wait for it to finish
run = client.actor("juliob.rangel/instagram-posts-scraper-fast").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 '{
  "profiles": [
    "nike"
  ],
  "maxPostsPerProfile": 24
}' |
apify call juliob.rangel/instagram-posts-scraper-fast --silent --output-dataset

```

## MCP server setup

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

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/w3pCZ39fZ8Hl5gLGR/builds/UKtrRSs2ruSzLygfP/openapi.json
