# Instagram Posts & Reels Scraper — Views & Likes, No Login (`webdatalabs/instagram-posts-reels-scraper`) Actor

Scrape public Instagram posts and Reels without login or cookies: views, likes, comment counts, captions, image and video URLs, timestamps and owner. Paste post links or whole profiles; Reels from profiles include view counts. Optional date filter.

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

## Pricing

from $1.60 / 1,000 post or reels

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 & Reels Scraper — Views & Likes, No Login

Scrape public Instagram posts and Reels without logging in: view counts, likes, comment counts,
captions, image and video links, timestamps and the owner, from post links or whole profiles.

### What does this Instagram Posts & Reels Scraper do?

This Instagram posts and Reels scraper turns public Instagram content into one clean row per post.
Paste post links, Reel links or profiles (`https://www.instagram.com/nasa/`, `@nasa` or just `nasa`)
and get back the post type, caption, likes, comment count, publish time, owner, and links to every
image and video. Reels found through a profile also carry their **view count**, the number Instagram
does not show on the post page.

It needs no Instagram account, no login and no cookies, so there is no account of yours to get
restricted.

**What you get**

- **Views for Reels** found on a profile, so you can rank an account's Reels by reach.
- **Likes and comment counts**. When an owner hides likes, the field is empty and `likesHidden`
  says so; you never get a fake 0.
- **Caption, type and timestamp**: photo, video, carousel or Reel, with the exact publish time in UTC.
- **Owner details**: username, display name, account id and verified badge.
- **Every image and video**: full-size links for each slide of a carousel, plus the video file and
  cover of a Reel.
- **A date filter**: "Only posts newer than" stops a profile at the first older post, so you don't
  pay for posts outside your window.
- **A status for every input**: private, deleted, age-restricted or missing accounts and posts are
  reported in the run summary and never charged.

### What data can it extract?

| Field | What it is | Example |
|---|---|---|
| `url`, `shortcode` | Link and code of the post | `https://www.instagram.com/reel/Dd1gQBsCWE8/` |
| `type` | `photo`, `video`, `carousel` or `reel` | `reel` |
| `postedAt` | Publish time, ISO 8601 UTC | `2026-09-28T15:27:08.000Z` |
| `caption` | Caption text with hashtags and @mentions | `What happens when we detect an asteroid…` |
| `likes`, `commentsCount` | Like and comment counts | `99596`, `840` |
| `views` | Reel view count (Reels found on a profile) | `4931239` |
| `ownerUsername`, `ownerFullName`, `ownerIsVerified` | Who published it | `nasa`, `NASA`, `true` |
| `displayUrl`, `videoUrl`, `media` | Main image, video file, and every slide | see the example below |
| `input`, `foundVia` | Which of your input lines produced the row | `nasa`, `profile` |

The full field list, with types and descriptions, is in the **Output** tab of this page.

#### Which input gives which fields?

| You enter | You get | Reel views |
|---|---|---|
| A post or Reel link | That post, every field | No: Instagram does not publish view counts on the post page |
| A profile link or username | Its newest posts and Reels, up to "Max posts per profile" | Yes, for every Reel |

### Example output

One real record from a run on `nasa` (long signed links shortened with "…"):

```json
{
  "url": "https://www.instagram.com/reel/Dd1gQBsCWE8/",
  "shortcode": "Dd1gQBsCWE8",
  "id": "3996242083173720380",
  "type": "reel",
  "postedAt": "2026-09-28T15:27:08.000Z",
  "caption": "What happens when we detect an asteroid that could pose a threat to Earth?\n\nIn early 2025, NASA joined scientists around…",
  "likes": 99596,
  "commentsCount": 840,
  "views": 4931239,
  "likesHidden": false,
  "ownerUsername": "nasa",
  "ownerFullName": "NASA",
  "ownerId": "528817151",
  "ownerIsVerified": true,
  "displayUrl": "https://scontent-mia5-2.cdninstagram.com/v/t51.82787-15/825320801_18652458124049152_7299739194868789568_n.jpg?…",
  "videoUrl": "https://scontent-mia3-3.cdninstagram.com/o1/v/t2/f2/m86/AQOuHqPy8zAIe_zxT0betsc1P_MC0UbWr9RpQE1PXpLte2vJMirWZm53iFkG3HLLgYNA-UawzHs1ios2466gYPqEI3p8QO1APW0nZtQ.mp4?…",
  "durationSeconds": 38.61,
  "media": [
    {
      "type": "video",
      "url": "https://scontent-mia3-3.cdninstagram.com/o1/v/t2/f2/m86/AQOuHqPy8zAIe_zxT0betsc1P_MC0UbWr9RpQE1PXpLte2vJMirWZm53iFkG3HLLgYNA-UawzHs1ios2466gYPqEI3p8QO1APW0nZtQ.mp4?…",
      "thumbnailUrl": "https://scontent-mia5-2.cdninstagram.com/v/t51.82787-15/825320801_18652458124049152_7299739194868789568_n.jpg?…",
      "width": 608,
      "height": 1080
    }
  ],
  "input": "nasa",
  "foundVia": "profile",
  "scrapedAt": "2026-10-01T21:46:11.886Z"
}
```

### How to scrape Instagram posts and Reels (quick start)

1. Paste your links or usernames into **Instagram posts, Reels or profiles**, one per line.
2. For profiles, set **Max posts per profile** (Instagram serves posts 12 at a time).
3. Optionally set **Only posts newer than** to a date (`2026-09-01`) or a period (`30 days`).
4. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the API.

The last 30 days of a profile, including Reel views:

```json
{
  "startUrls": ["https://www.instagram.com/nasa/"],
  "maxPostsPerProfile": 100,
  "postedAfter": "30 days"
}
```

Specific posts and Reels by link:

```json
{
  "startUrls": [
    "https://www.instagram.com/p/DdwalmrkTSK/",
    "https://www.instagram.com/reel/Dd1gQBsCWE8/"
  ]
}
```

A list of creators, newest 12 posts each:

```json
{
  "startUrls": ["@nasa", "natgeo", "https://www.instagram.com/instagram/"],
  "maxPostsPerProfile": 12
}
```

Every run also writes a summary record, `OUTPUT`, in its key-value store. It lists the status of
each input line (delivered, private, not found, blocked) and a ready-to-paste `rerunInput` for
anything a stopped run did not finish.

### How much does it cost to scrape Instagram posts?

You pay per result: one charge for each post or Reel delivered to your dataset. The current price
is shown on this page. Private accounts, deleted posts, accounts that do not exist, and posts
outside your date filter are never charged. Set a maximum cost per run in the run options and the
scraper stops cleanly when it reaches it.

There is no separate proxy fee: the scraper chooses its own route to Instagram, and you do not need
a proxy setting.

### Use cases

- **Influencer vetting.** Scrape a creator's last 50 posts and sort the Reels by `views`.
  Compare `likes / views` across candidates before you book a campaign.
- **Campaign reporting.** Run the brand and creator profiles weekly with `postedAfter: "7 days"`.
  Each run returns that week's posts with likes, comments and views.
- **Competitor content analysis.** Chart a competitor's posting cadence from `postedAt` and its
  format mix from `type` (Reels against carousels against photos).
- **AI and content teams.** Collect captions plus `media` links from accounts in a niche to build
  training or inspiration datasets. Filter with `type = "reel"` and a minimum of `views`.
- **Social analytics dashboards.** Send each run's dataset to Google Sheets, Make, Zapier or n8n
  through Apify's integrations, keyed on `shortcode`.

### FAQ

#### Do I need an Instagram account, login or cookies?

No. The scraper reads what Instagram shows to logged-out visitors, so you never provide credentials
and no account of yours is involved.

#### Why are views empty for posts I gave as links?

Instagram publishes a Reel's view count only in the profile's Reels feed, not on the post page.
Enter the profile instead (with "Only posts newer than" to keep it short) and each Reel arrives with
its `views`. Photos and carousels have no view count.

#### Why are some likes empty?

The owner hid the like count on that post. Instagram then sends no real number, so `likes` (and
`views`) are empty and `likesHidden` is `true`, rather than showing a misleading 0.

#### Can it scrape hashtags, keyword search, comments or followers?

No. Instagram shows hashtag pages, keyword search and stories only to logged-in users, so they are
out of scope for a no-login scraper. This scraper also returns comment counts, not comment texts,
and no follower lists.

#### How many posts can it get from one profile?

Up to 1,000 of the newest posts and Reels per profile in one run, set with **Max posts per profile**.
Pinned posts at the top of a profile are included, but they never cut a date filter short.

#### What happens if a run times out or I stop it?

Every post delivered before the stop stays in your dataset and is charged once. The `OUTPUT`
summary marks the run as stopped and includes a `rerunInput` with the inputs that did not finish.
A profile that was cut off part-way is read again from its newest post, so for very large profiles
give the run a longer timeout instead of relying on a rerun. As a guide, a test run read 1,000 posts
from one profile in about 30 minutes.

#### What happens with private, deleted or age-restricted content?

The scraper reports it instead of failing. In the `OUTPUT` summary each input line has a status:
`PRIVATE`, `NOT_FOUND` (no such account), `NOT_AVAILABLE` (deleted, or hidden from logged-out
visitors, as alcohol brands are) or `BLOCKED`. None of these is charged.

#### Why does a post show a different owner than the profile I entered?

Collaboration posts appear on every co-author's profile. `ownerUsername` is the account that
published the post; `input` shows the profile you entered, so you can always group rows by your own
list.

#### How long do the image and video links work?

They are signed Instagram CDN links that expire after a few days. Download the files you need soon
after the run, or re-run to get fresh links.

#### Is it legal to scrape Instagram?

This scraper only collects publicly visible data, without logging in. In *Meta Platforms v. Bright
Data* (N.D. Cal., 2024), the court found that Meta's terms did not bar logged-off scraping of public
data. Posts can still contain personal data, so the GDPR and similar laws apply to how you use them:
collect only what you need and make sure you have a legitimate purpose. This is not legal advice;
ask your lawyer about your specific use.

### Related actors

- [Meta Ad Library Scraper](https://apify.com/webdatalabs/meta-ad-library-scraper): the ads a brand runs on Instagram and Facebook.
- [Instagram Reels Transcript](https://apify.com/webdatalabs/instagram-reels-transcript): spoken transcripts and hooks of public Instagram Reels.
- [Meta Threads Scraper](https://apify.com/webdatalabs/meta-threads-scraper): public Threads posts, replies and profiles.
- [Facebook Posts Scraper](https://apify.com/webdatalabs/facebook-posts-scraper): posts from public Facebook Pages and Groups.
- [YouTube Shorts Scraper](https://apify.com/webdatalabs/youtube-shorts-scraper): YouTube Shorts with views and engagement.
- [TikTok Shop Scraper](https://apify.com/webdatalabs/tiktok-shop-scraper): TikTok Shop products and sales data.

### Support

Found a problem or need a field that is missing? Open an issue in the **Issues** tab; we read every one.

# Actor input Schema

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

One per line: a post or Reel link (https://www.instagram.com/p/DdwalmrkTSK/), a profile link (https://www.instagram.com/nasa/), @nasa or just nasa. A profile returns its newest posts and Reels. Hashtag and keyword search need a logged-in account and are not supported.

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

How many of the newest posts and Reels to take from each profile. Instagram serves them 12 at a time. Does not limit post or Reel links.

## `postedAfter` (type: `string`):

Optional. Skips posts published before this date (2026-09-01) or period (30 days, 2 weeks). A profile stops at the first older post, so you are never charged for posts outside the window. Pinned posts at the top of a profile are skipped, not treated as the end.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.instagram.com/nasa/",
    "https://www.instagram.com/reel/Dd1gQBsCWE8/",
    "@natgeo"
  ],
  "maxPostsPerProfile": 12
}
```

# Actor output Schema

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

No description

## `full` (type: `string`):

No description

## `runSummary` (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": [
        "https://www.instagram.com/nasa/",
        "https://www.instagram.com/p/DdwalmrkTSK/"
    ],
    "maxPostsPerProfile": 12
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdatalabs/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 = {
    "startUrls": [
        "https://www.instagram.com/nasa/",
        "https://www.instagram.com/p/DdwalmrkTSK/",
    ],
    "maxPostsPerProfile": 12,
}

# Run the Actor and wait for it to finish
run = client.actor("webdatalabs/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 '{
  "startUrls": [
    "https://www.instagram.com/nasa/",
    "https://www.instagram.com/p/DdwalmrkTSK/"
  ],
  "maxPostsPerProfile": 12
}' |
apify call webdatalabs/instagram-posts-reels-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,webdatalabs/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/35vhHO7R4Zvu6DHEn/builds/JkqMmTacbgYwZxY9g/openapi.json
