# Instagram Scraper (`hpix/instagram-scraper`) Actor

Scrape Instagram profiles, posts, and Reels at scale.

- **URL**: https://apify.com/hpix/instagram-scraper.md
- **Developed by:** [Hpix](https://apify.com/hpix) (community)
- **Categories:** Social media, Lead generation
- **Features:** Limited permissions
- **Stats:** 641 total users, 89 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.65 / 1,000 profile posts

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 Scraper

**The Ultimate All-in-One Instagram Scraper**

Extract high-quality data from Instagram profiles, posts, and Reels in seconds. Designed for marketers, researchers, and creators who need reliable data without the technical headache.

### 🚀 Why choose this Scraper?

- **Reliability by Default:** No more worrying about getting blocked. This Actor uses premium residential proxies and anti-detection mechanisms to ensure your tasks finish successfully.
- **Reels, Posts & Profiles:** Whether you need engagement stats on a viral Reel or the follower count of a specific influencer, we've got you covered.
- **Clear, Predictable Costs:** Stop guessing how much memory or CPU you need. You only pay for the data you actually receive.
- **Beautiful Data Views:** Don't get lost in code. Use the built-in output tabs to see your results in a clean, organized table with images.

### **✨ What can you do with it?**

- **Analyze Engagement:** Get play counts, likes, and comment totals for Reels and Posts.
- **Monitor Influencers:** Track bio changes, follower growth, and verified status.
- **Content Research:** Use the **Date Filter** to only see content from the last week or month.
- **Bulk Exports:** Download your results instantly as **Excel, CSV, or JSON**.

### **🛠️ Getting Started is Easy**

1. **Enter URLs or Usernames:** Paste the Instagram profiles or specific post links you want to scrape.
2. **Pick Your Content:** Toggle profile data, posts, and reels independently — or scrape them all at once.
3. **Set Your Limits:** Use the "Posts per account" or "Date Range" filters to get exactly what you need.
4. **Run & Relax:** Click **Start** and watch your data populate in the "Output" tab.

### **📊 Sample Output**

#### Profile Data

| Username | Full name       | Profile picture          | Followers  | Following | Data            |
| -------- | --------------- | ------------------------ | ---------- | --------- | --------------- |
| zuck     | Mark Zuckerberg | \<Zuck's profile picture> | 16,879,414 | 623       | <post metadata> |

#### Post Data

| Thumbnail        | Caption                               | Code        | Type | Like count | Comment count | Data            |
| ---------------- | ------------------------------------- | ----------- | ---- | ---------- | ------------- | --------------- |
| <Post thumbnail> | Two decades, many awesome projects... | DTTbdGlkaWl | post | 158,039    | 5,228         | <post medatada> |

#### Reel Data

| Thumbnail        | Caption                               | Play count | Comment count | Like count | Data            |
| ---------------- | ------------------------------------- | ---------- | ------------- | ---------- | --------------- |
| <Reel thumbnail> | When @merab.dvalishvili is in town... | 27,979,151 | 4,670         | 394,756    | <reel metadata> |

### **💡 Pro Tips**

- **Massive Lists:** This Actor is optimized for bulk. You can input hundreds of profiles at once; it will handle the queue automatically.
- **Date Filtering:** To save time and budget, use the beginDate parameter to only grab content created recently (e.g., "7 days ago").
- **Custom Logic:** Advanced users can use the "Custom functions" field to automatically skip posts that don't meet specific criteria (like posts without music).
- **Cleaner Output:** Disable the "Include raw data" option to strip the raw Instagram API response from the output and reduce dataset size.
- **Pin Skipping:** "Skip pinned posts" and "Skip pinned reels" let you skip content pinned to specific tabs independently — useful for accounts that pin promotional content to the top of their feed.

### 🔧 Advanced Usage

#### Custom functions

This is an advanced parameter that you can use to modify the crawler's behavior.
With custom functions, you can skip a post or profile based on its data or stop crawling a profile's posts when a certain condition is met.

Two hooks are available:

- **`shouldSkip(item)`** — Return `true` to skip the current item (post, reel, or profile). Processing continues with the next item.
- **`shouldContinue(item)`** — Return `false` to stop crawling after the current item. Useful for stopping at a specific post.

For example, skip posts that don't have music metadata:

```javascript
{
  shouldSkip: (item) => item.kind == "post" && !item.data.music_metadata;
}
```

Or stop crawling when it reaches a specific post code:

```javascript
{
  shouldContinue: (item) => item.data.code != "codeToStopCrawling";
}
```

You can see the item schema by selecting "All fields" on the output tab, and viewing as JSON.

#### Restricted Posts

Some Instagram posts are age-restricted or otherwise limited and can't be accessed through the standard API. Enable the **"Scrape restricted posts"** toggle to attempt fetching these individual posts. This is a paid feature — each restricted post scraped incurs an additional charge on top of the standard per-post fee.

Please refer to the Actor pricing for details.

### 📃 Changelog

Do you have a feature suggestion?
Create an [issue](https://console.apify.com/actors/JER1eC8E7teQWMN3p/issues) and let me know!

#### v1.1.0

- ✨ Added restricted posts scraping
- ✨ Added skip_pinned_timeline and skip_pinned_reels options (deprecated skip_pinned)
- 🔧 Improved output schema and dataset views
- 🔧 Fixed date range filtering for pinned posts
- Initial release

### ❓ FAQ

#### Can I export the scraped data to Excel?

Sure! Apify allows you to download the results as an Excel spreadsheet.
You can also download in CSV, JSON, XML, HTML, JSONL, and RSS.

#### What other data is available apart from the examples shown?

Each post, reel, and profile contains a
`data` field with extensive metadata beyond what's shown in the table view. To explore all available fields, select "All fields" in the output tab and view the results as JSON.

Here are some notable fields available in the output:

| Field            | Type     | Description                                                         |
| ---------------- | -------- | ------------------------------------------------------------------- |
| `is_pinned`      | boolean  | Whether the post/reel is pinned by the profile                      |
| `pinned_tabs`    | string\[] | Tabs where the item is pinned: `["timeline"]`, `["reels"]`, or both |
| `music_info`     | object   | Music metadata for reels (artist, song title, album art)            |
| `video_versions` | array    | All available video resolution URLs for reels                       |
| `hashtags`       | string\[] | Hashtags extracted from the caption                                 |
| `video_duration` | number   | Video duration in seconds (for video posts and reels)               |
| `view_count`     | number   | View count for individual reels (when scraping by post URL)         |
| `bio_links`      | string   | External URL from the profile's bio                                 |

#### I just found a bug! Can you fix it?

Oh, what a shame! Please create an [Issue](https://console.apify.com/actors/JER1eC8E7teQWMN3p/issues), so I can evaluate
what happened.

#### Can you implement X feature?

Of course! You can use the **[Issues](https://console.apify.com/actors/JER1eC8E7teQWMN3p/issues)** tab to suggest new
features.

### ⚠️ Disclaimer

This Actor scrapes public data from Instagram pages. Features are susceptible to changes made by Meta.

### ⛓️‍💥 Known issues

- Private or age-restricted accounts cannot be scraped as they are not publicly accessible.
- View counts for Reels are only available when scraping individual post URLs, not when scraping entire profiles. Play counts, however, are available in both scenarios.
- Instagram does not provide view counts for some posts, as these metrics are not publicly visible for those specific posts.

### 👀 See also

- [Instagram Profile Monitor](https://apify.com/hpix/instagram-profile-monitor): Track Instagram profiles over time and
  monitor growth trends with historical data analysis and beautiful visualizations. Perfect for tracking competitors, influencers, or your own profile's performance.

# Actor input Schema

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

Instagram usernames or URLs

## `scrape_posts` (type: `boolean`):

Scrape all posts (images and reels) from profiles.

## `scrape_reels` (type: `boolean`):

Scrape reels from profiles. To scrape metadata like play count and music info, disable the "Scrape posts" option above.

## `scrape_profile_data` (type: `boolean`):

Scrape profile information

## `posts_per_account` (type: `integer`):

Number of posts/reels to fetch per user

## `extra_options` (type: `object`):

Additional scraping options

## `posts` (type: `array`):

Scrape posts using their URL or code

## `scrape_restricted_posts` (type: `boolean`):

Scrape age-restricted or otherwise limited Instagram posts that are not publicly available by default. This is a paid feature — please refer to the Actor pricing.

## `scrape_detailed_data` (type: `boolean`):

Scrape detailed data for each post, including music information and play counts. This is a paid feature — each post scraped will be charged at the same rate as "Restricted post". Please refer to the Actor pricing for details.

## `fromDate` (type: `string`):

Start scraping from this date (oldest posts to include)

## `toDate` (type: `string`):

Stop scraping at this date (newest posts to include)

## `custom_functions` (type: `string`):

Functions to customize the crawler's behaviour. Accepts an object with two functions, `shouldSkip` and `shouldContinue`, each taking a data argument which contains the data for the current scraped item.

## `include_raw_data` (type: `boolean`):

Include the `data` field in the output. Disabling this decreases the size of the output dataset.

## Actor input object example

```json
{
  "profiles": [
    "zuck"
  ],
  "scrape_posts": true,
  "scrape_reels": true,
  "scrape_profile_data": true,
  "posts_per_account": 12,
  "scrape_restricted_posts": false,
  "scrape_detailed_data": false,
  "custom_functions": "{ shouldSkip: (item) => item.kind == 'post' && !item.data.music_metadata, shouldContinue: (item) => item.data.code != 'codeToStopCrawling' }",
  "include_raw_data": 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": [
        "zuck"
    ],
    "custom_functions": "{ shouldSkip: (item) => false, shouldContinue: (item) => true }"
};

// Run the Actor and wait for it to finish
const run = await client.actor("hpix/instagram-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 = {
    "profiles": ["zuck"],
    "custom_functions": "{ shouldSkip: (item) => false, shouldContinue: (item) => true }",
}

# Run the Actor and wait for it to finish
run = client.actor("hpix/instagram-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 '{
  "profiles": [
    "zuck"
  ],
  "custom_functions": "{ shouldSkip: (item) => false, shouldContinue: (item) => true }"
}' |
apify call hpix/instagram-scraper --silent --output-dataset

```

## MCP server setup

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