# Instagram Profile Content Scraper — Posts, Reels & Story Status (`thenetaji/instagram-profile-content-scraper`) Actor

Scrape posts, reels, or check story/live status for one or more public Instagram accounts, with optional full media detail enrichment.

- **URL**: https://apify.com/thenetaji/instagram-profile-content-scraper.md
- **Developed by:** [The Netaji](https://apify.com/thenetaji) (community)
- **Categories:** Social media, For creators, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 results

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 Profile Content Scraper — Posts, Reels & Story Status

The Actor collects the public content published by one or more Instagram accounts. One field selects what to collect — posts, reels, or highlights and story status — and pagination is handled internally.

### Selecting content

`scraperType` is required and determines what a run returns.

| Value | Label | Returns |
|---|---|---|
| `userPosts` | Posts | Feed posts, paginated |
| `userReels` | Reels | Reels, paginated |
| `userHighlights` | Highlights/Story Status | Highlight reels, plus whether a public story is live now |

### Accepted input

| Field | Type | Default | Description |
|---|---|---|---|
| `username` | array of strings | — | Required. Usernames, profile URLs, or numeric user IDs. |
| `scraperType` | enum | `userPosts` | Required. `userPosts`, `userReels`, `userHighlights`. |
| `maxItem` | integer | `100` | Maximum items saved per account. `0` removes the limit. |
| `enrichMedia` | boolean | `false` | Fetches the full media object for every item. |

```json
{
  "username": ["nasa"],
  "scraperType": "userPosts",
  "maxItem": 100,
  "enrichMedia": false
}
```

A value made entirely of digits is treated as a numeric user ID rather than a username; anything else is treated as a username or profile URL. This matters for accounts whose username is all digits — pass the profile URL in that case so it is not misread as an ID.

`maxItem` applies to each account independently rather than as a shared total.

### Response fields

One record per item.

| Field | Contents |
|---|---|
| `pk` | Instagram media ID |
| `code` | Shortcode, the identifier in a post URL |
| `like_count` | Likes |
| `comment_count` | Comments |
| `taken_at` | Publication timestamp |
| `media_type` | Image, video, or carousel |
| `caption` | Caption text |
| `has_public_story` | Whether a public story is live, in Highlights mode |
| `is_live` | Whether the account is broadcasting live, in Highlights mode |
| `enriched` | Whether the full media object was fetched |
| `source_username` | The account this item came from |

```json
{
  "pk": "3412987456123456789",
  "code": "C9xY2zAqBcD",
  "like_count": 184220,
  "comment_count": 1204,
  "taken_at": 1785312000,
  "media_type": 1,
  "source_username": "nasa",
  "enriched": false
}
```

`code` is the useful identifier to carry forward — it is what appears in a post URL and what [Instagram Post Scraper](https://apify.com/thenetaji/instagram-post-scraper) accepts.

### Behaviour on partial results

Content is collected through a cursor and ends when Instagram reports no further pages, returns an empty page, or `maxItem` is reached.

Enrichment is applied per item and issues one additional request each. Items that fail to enrich are skipped rather than aborting the run.

### Frequently asked questions

**Are stories themselves returned?**
No. Highlights mode returns highlight reels — the collections an account has pinned to its profile — along with `has_public_story` and `is_live`, which report whether a story or broadcast is live at the moment of the run. The story content itself is not collected. Those two fields are point-in-time observations: a run an hour later can legitimately report differently.

**Why do reels also appear among posts?**
Instagram surfaces reels in the main feed as well as the reels tab, so the two modes overlap for accounts that post both. `userReels` is the reliable way to isolate them; filtering `userPosts` on `media_type` is an approximation.

**Why did an account return fewer items than it has posted?**
Either `maxItem` capped the run, or Instagram stopped serving pages. The feed paginates through a bounded window rather than a complete archive, so very old content on a long-running account can be unreachable. The run log distinguishes the two.

**What does `enrichMedia` add, and what does it cost?**
The complete media object — full caption, all carousel children, tagged users, and location where present. Each item costs one additional request and one additional billed event, so a 500-item run performs 500 extra requests. Collecting first and enriching a subset afterwards is usually cheaper.

**Can a numeric user ID be used instead of a username?**
Yes. A value made only of digits is sent as a user ID. Because that rule is purely syntactic, an account whose username happens to be all digits would be misread — pass the profile URL for those.

**How is a private account handled?**
It returns nothing. Only public content is readable, and no logged-in session is used.

### Related Actors

| Actor | Purpose |
|---|---|
| [Instagram Post Scraper](https://apify.com/thenetaji/instagram-post-scraper) | Full detail or comments for individual posts |
| [Instagram User Info Scraper](https://apify.com/thenetaji/instagram-user-info-scraper) | Profile details for the accounts themselves |
| [Instagram Popular Search Scraper](https://apify.com/thenetaji/instagram-popular-search-scraper) | Content by hashtag or keyword rather than by account |
| [Instagram Followers & Followings Scraper](https://apify.com/thenetaji/instagram-followers-followings-scraper) | Follower and following lists |

# Actor input Schema

## `username` (type: `array`):

Instagram usernames to scrape

## `scraperType` (type: `string`):

Which kind of content to collect for each account.

## `maxItem` (type: `integer`):

Maximum number of items to scrape (0 = unlimited)

## `enrichMedia` (type: `boolean`):

Replace each thin hit with its complete media record (caption, counters, all image/video variants). Costs an extra event per swapped item.

## Actor input object example

```json
{
  "username": [
    "natgeo"
  ],
  "scraperType": "userPosts",
  "maxItem": 100,
  "enrichMedia": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

All records scraped by this run

# 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 = {
    "username": [
        "natgeo"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/instagram-profile-content-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 = { "username": ["natgeo"] }

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/instagram-profile-content-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 '{
  "username": [
    "natgeo"
  ]
}' |
apify call thenetaji/instagram-profile-content-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thenetaji/instagram-profile-content-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/193rW0z09SE6leYhm/builds/Y2TXwMa0IqXakOJbF/openapi.json
