# Instagram Scraper - Posts, Reels, Hashtags & Profiles (`topapi/instagram-scraper`) Actor

Scrape Instagram posts, reels and carousels by profile, hashtag or post URL: caption, likes, comments, plays, engagement rate, date, image/video URLs, music, tagged users, co-authors, location, pinned and paid-partnership flags. Date, type and keyword filters, monitor mode. No login.

- **URL**: https://apify.com/topapi/instagram-scraper.md
- **Developed by:** [Top Api](https://apify.com/topapi) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 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.

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

### What does Instagram Scraper do?

**Instagram Scraper** extracts Instagram posts from instagram.com and turns profile names, hashtags or post URLs into structured rows: one row per post, reel or carousel with caption, likes, comments, plays, publish date, media URLs, music, tagged users and the owner. Built for marketing teams, influencer and brand researchers, and data pipelines that need Instagram posts data without a login, cookies or an API key.

Instagram Posts Scraper - Instagram Reels Scraper - Instagram Hashtag Scraper - Instagram Profile Posts API

<a href="https://console.apify.com/actors/5UGcwS9WCCJbVqzDY"><img src="https://api.apify.com/v2/key-value-stores/qNQ9zP0xaj2yxGeMY/records/instagram-scraper-source.png" alt="Instagram posts grid of a public profile that Instagram Scraper turns into rows" style="width:70%"></a>

- **Posts, reels and carousels from any public profile:** newest first, pinned posts flagged, 10 posts per page, as deep as you set the cap.
- **Hashtags and keywords:** the reels Instagram shows on its public keyword page for a term, with play counts, 12 per page.
- **Single posts and reels by URL:** paste any `/p/` or `/reel/` link or a bare shortcode and get the full record in one request.
- **One better than the rest:** `engagementRate` (likes + comments over the owner's followers), `captionCreatedAt`, `likeAndViewCountsDisabled`, `musicInfo.audioType` and `isTrendingInClips`, every image rendition in `images`, carousel items with their own tagged users, and reel play counts even for posts in a profile timeline.
- **No login, cookies or Instagram API key:** the actor reads only what Instagram shows a signed-out visitor.
- **Filters:** date window, post type, minimum likes, keyword, tagged place and pinned posts; pay-per-result with no start fee.
- **Export anywhere:** JSON, CSV, Excel, XML, RSS; schedules, webhooks, Make, Zapier, n8n, Google Sheets, Slack.
- **Works with AI agents:** call it through the Apify API or the MCP server; `compact` trims rows for LLM context windows.

### What data can you get from Instagram?

<table>
<tr>
<td>🔗 Post URL and shortcode (`url`, `shortCode`)</td>
<td>📝 Caption, hashtags, mentions</td>
<td>📅 Publish date (`timestamp`)</td>
</tr>
<tr>
<td>❤️ Likes (`likesCount`)</td>
<td>💬 Comments (`commentsCount`)</td>
<td>▶️ Reel plays (`videoPlayCount`)</td>
</tr>
<tr>
<td>📈 Engagement count and rate</td>
<td>🖼️ Image URLs in every size (`displayUrl`, `images`)</td>
<td>🎬 Video URL, duration, audio flag</td>
</tr>
<tr>
<td>🎵 Music: song, artist, audio type, trending</td>
<td>🏷️ Tagged users with positions</td>
<td>🤝 Co-authors and paid-partnership sponsors</td>
</tr>
<tr>
<td>📍 Location name, id, city, coordinates</td>
<td>🧩 Carousel items (`childPosts`)</td>
<td>📌 Pinned, type, product type (reel / feed / carousel)</td>
</tr>
<tr>
<td>👤 Owner username, name, id, verified, avatar, followers</td>
<td>🪪 Optional profile row: bio, links, followers, category, business address</td>
<td>🔍 Which input and keyword each row came from</td>
</tr>
</table>

On the first live run (17 posts from a profile, a keyword and a URL) every row had a caption, date, likes, comments, image URL, dimensions and owner; 65% carried hashtags, 53% a play count (every reel), 35% tagged users, 24% a location.

### How to scrape Instagram with Instagram Scraper

1. [Create a free Apify account](https://console.apify.com/sign-up) - $5 of monthly credit, no card needed.
2. Open [Instagram Scraper](https://apify.com/topapi/instagram-scraper) and click **Try for free**.
3. Paste usernames into **Profiles**, hashtags into **Hashtags or keywords**, or links into **Post or reel URLs**, and set **Max posts per profile or hashtag**.
4. Click **Start**. Rows stream into the dataset as pages are read; a 50-post profile run finishes in a few seconds.
5. Open the **Storage** tab and **Export** as JSON, CSV or Excel - or let a schedule run it for you.

### ⬇️ Input

| Parameter | Type | Description |
|---|---|---|
| **🔍 What to scrape** | | |
| `usernames` | List | Usernames or profile URLs: `nasa`, `@natgeo`, `https://www.instagram.com/instagram/`. Default: `["nasa"]` when nothing else is given |
| `hashtags` | List | Hashtags or keywords: `travel`, `#foodie`, `https://www.instagram.com/explore/tags/travel/`. Read from Instagram's public keyword page |
| `postUrls` | List | Post or reel URLs or shortcodes: `https://www.instagram.com/p/Dd9RyBWBVih/`, `Dd9RyBWBVih` |
| **🎯 Filters** (decide how far back a profile is read) | | |
| `onlyPostsNewerThan` | String | `2026-09-01`, `7 days`, `3 weeks`, or a day count. Paging stops when a whole page is older |
| `onlyPostsOlderThan` | String | Upper bound of the window, same formats |
| `skipPinnedPosts` | Boolean | Leave out posts pinned to the top of the grid. Default: `false` |
| **✂️ Refine results** | | |
| `postType` | Select | `all`, `image`, `video`, `carousel`, `reel`. Default: `all` |
| `minLikes` | Integer | Keep only posts with at least this many likes. Default: `0` |
| `keywordFilter` | String | Keep only posts whose caption, hashtags, tagged users, place, music or owner contain the word(s); comma = any |
| `withLocationOnly` | Boolean | Keep only posts tagged with a place. Default: `false` |
| **➕ Extra data** | | |
| `includeProfileSummary` | Boolean | Adds one `Profile` row per scraped profile - charged as **profile-summary** at $0.001 per profile |
| **🔁 Monitoring** | | |
| `monitorMode` | Boolean | Return only posts not delivered by previous runs; pair with a daily schedule |
| `monitorStoreName` | String | Name of the key-value store holding the monitor memory. Default: `instagram-posts-monitor` |
| **📦 Output** | | |
| `resultsLimit` | Integer | Max posts per profile or hashtag after filters. Default `50`; `0` = everything Instagram serves |
| `maxItems` | Integer | Hard cap for the whole run. Default `0` = no total cap |
| `compact` | Boolean | Core fields only, sized for AI agents and MCP |
| **⚙️ Advanced** | | |
| `proxyConfiguration` | Object | Apify proxy settings. Default: Apify datacenter proxies, which serve every request this actor makes |
| `maxConcurrency` | Integer | Parallel single-post requests. Default `4` |

#### Input JSON

```json
{
  "usernames": ["nasa", "natgeo"],
  "hashtags": ["travel"],
  "postUrls": ["https://www.instagram.com/reel/Dd9RyBWBVih/"],
  "onlyPostsNewerThan": "30 days",
  "resultsLimit": 50,
  "includeProfileSummary": true
}
```

#### Paste profiles when you want a timeline, URLs when you want specific posts

A profile walks the grid newest first and stops at your cap or date window. A post URL costs one request and returns the full record of that one post. **Do:** `nasa` in Profiles · **Don't:** `https://www.instagram.com/nasa/p/Dd9RyBWBVih/` in Profiles expecting the whole timeline (the actor routes a post URL to the single-post path and returns one row).

#### Hashtags are Instagram's public keyword page, not the signed-in hashtag feed

Signed-out visitors get a keyword page of popular reels for a term, 12 per page, in Instagram's ranking. It exists for many terms (`travel`, `foodie`, `street food` all returned pages in testing) and not for others (`sunset`, `coffee`, `nasa` returned a description and no posts). An empty term delivers nothing and says so in the run status. For a specific account's posts, use `usernames`.

#### Use the date window for scheduled Instagram runs

`onlyPostsNewerThan: "1 day"` on a profile reads one page and stops as soon as the page is older than yesterday; with `monitorMode` on, a daily schedule delivers each post exactly once.

### ⬆️ Output

Every post becomes one dataset item. Here is the table view of a run for `nasa`, `travel` and one reel URL:

<a href="https://console.apify.com/actors/5UGcwS9WCCJbVqzDY"><img src="https://api.apify.com/v2/key-value-stores/qNQ9zP0xaj2yxGeMY/records/instagram-scraper-output.png" alt="Instagram Scraper output table of Instagram posts with likes, comments, plays and engagement" style="width:70%"></a>

And one row as JSON (trimmed):

```json
{
  "id": "3998430248382584993",
  "type": "Video",
  "shortCode": "Dd9RyBWBVih",
  "url": "https://www.instagram.com/reel/Dd9RyBWBVih/",
  "caption": "DIY fish squishy 🐟 @yano4kaa.a made this squishy using stuff she already had at home...",
  "hashtags": [],
  "mentions": ["yano4kaa.a", "stuckinreboot"],
  "timestamp": "2026-10-01T09:59:45.000Z",
  "likesCount": 534292,
  "commentsCount": 11572,
  "engagementCount": 545864,
  "engagementRate": 0.08,
  "videoPlayCount": 123170887,
  "videoDuration": 16.74,
  "videoUrl": "https://scontent-....cdninstagram.com/o1/v/t2/f2/m86/....mp4?...",
  "displayUrl": "https://scontent-....cdninstagram.com/v/t51.82787-15/....jpg?...",
  "productType": "clips",
  "isPinned": false,
  "paidPartnership": false,
  "taggedUsers": [{ "id": "7198319588", "username": "yano4kaa.a", "fullName": "yano4kaa", "position": [0, 0] }],
  "musicInfo": { "audioType": "licensed_music", "songName": "Tell Me (Rap Version)", "artistName": "Wonder Girls", "isTrendingInClips": true },
  "ownerUsername": "instagram",
  "ownerFollowersCount": 686588239
}
```

#### Fields

| Field | Type | What it is | Fill on the live run |
|---|---|---|---|
| `id`, `pk`, `shortCode`, `url` | string | Instagram media id, shortcode and canonical URL (`/reel/` for reels) | 100% |
| `type` | string | `Image`, `Video` or `Sidecar` (carousel) | 100% |
| `productType` | string | `feed`, `clips` (reel), `carousel_container`, `igtv` | 100% |
| `caption`, `hashtags`, `mentions` | string / arrays | Caption text with its hashtags and @mentions parsed | 100% / 65% / 59% |
| `timestamp`, `captionCreatedAt` | string (ISO 8601) | Publish time and caption time | 100% |
| `likesCount`, `commentsCount`, `engagementCount` | integer | Likes, comments and their sum; `likesCount` is null when the owner hides likes | 100% |
| `engagementRate` | number | (likes + comments) / owner followers, percent; filled for a profile's own posts and for post URLs | 35% |
| `videoPlayCount`, `videoViewCount` | integer | Reel plays from the profile's reels tab or the keyword page; `videoViewCount` when Instagram exposes it | 53% (every reel) / 0% |
| `likeAndViewCountsDisabled`, `isCommentsDisabled` | boolean | Owner-side visibility switches | 100% / 0% |
| `displayUrl`, `images`, `dimensionsWidth`, `dimensionsHeight` | string / array | Largest image and every rendition with sizes (signed CDN links, they expire) | 100% |
| `videoUrl`, `videoDuration`, `hasAudio` | string / number / boolean | Best video rendition, seconds, audio flag | 53% (every video) |
| `isPinned`, `isInProfileGrid` | boolean | Pinned to the profile grid; shown in the grid | 100% |
| `paidPartnership`, `sponsors` | boolean / array | Paid partnership label and its sponsor accounts | 100% / 6% |
| `taggedUsers`, `coauthorProducers` | array | Tagged accounts with positions; collaborators | 35% / 24% |
| `locationName`, `locationId`, `locationCity`, `locationLat`, `locationLng` | string / number | Tagged place | 24% |
| `musicInfo` | object | `audioType`, `songName`, `artistName`, `audioId`, `usesOriginalAudio`, `isExplicit`, `isTrendingInClips`, `originalAudioOwner` | 53% (every reel) |
| `childPosts` | array | Carousel items: id, type, displayUrl, dimensions, videoUrl, duration, alt, taggedUsers | 29% (every carousel) |
| `alt`, `aiLabel`, `latestComments` | string / array | Accessibility caption, AI label, preview comments when Instagram ships them | 3% / 0% / 0% |
| `ownerUsername`, `ownerFullName`, `ownerId`, `ownerIsVerified`, `ownerProfilePicUrl`, `ownerFollowersCount` | string / boolean / integer | The account that posted (the co-author on collab posts) | 100% (followers 35%) |
| `inputUrl`, `searchTerm`, `scrapedAt` | string | Where the row came from | 100% / 47% / 100% |

A `Profile` row (add-on) carries `username`, `fullName`, `biography`, `externalUrl`, `bioLinks[]`, `followersCount`, `followsCount`, `postsCount`, `isPrivate`, `isVerified`, `isBusinessAccount`, `isProfessionalAccount`, `businessCategoryName`, `businessAddress`, `profilePicUrl`, `profilePicUrlHD`, `hasActiveStory`, `highlightReelCount`, `hasClips`, `threadsBadge`, `fbid`.

### How can I use Instagram posts data?

- 🎯 **Influencer and creator vetting** - pull a creator's last 100 posts, read `engagementRate`, `paidPartnership` and `coauthorProducers` to see real engagement and how often they run sponsored content.
- 📊 **Competitor and brand monitoring** - schedule the competitor profiles daily with `monitorMode` and get every new post, its format and its first-day likes and comments.
- 🔎 **Trend and UGC research** - read the keyword page for `travel` or `street food`, rank reels by `videoPlayCount`, pick the sounds in `musicInfo` that trend.
- 📍 **Local marketing and venue research** - `withLocationOnly` keeps posts tagged with a place; group them by `locationName` and `locationCity`.
- 🤖 **AI and research teams** - feed `caption`, `hashtags`, `alt` and the counts to an LLM with `compact: true`; every row is one post, nothing nested you did not ask for.
- 📈 **Reporting** - run weekly and track `likesCount`, `commentsCount` and `videoPlayCount` of the same posts over time.

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

Instagram Scraper is pay-per-result: **$0.40 per 1,000 posts**, no start fee. One result is one post written to the dataset. The optional profile row is $0.001 per profile.

| Rows | Cost |
|---:|---:|
| 10 | $0.004 |
| 100 | $0.04 |
| 1,000 | $0.40 |
| 10,000 | $4.00 |

There is nothing else to pay: Apify platform usage (compute, proxy) is included in these prices. The actor runs on 256 MB with no browser: a 50-post profile run read 5 pages in 3.6 seconds, a 17-post mixed run took 2.8 seconds over 20 requests.

### Integrations, API, scheduling & MCP

- **Schedules:** run Instagram Scraper hourly, daily or weekly from the **Schedules** tab; combine with `monitorMode` or `onlyPostsNewerThan` to get only new posts.
- **Webhooks:** fire a URL when a run finishes - push rows to your CRM, Slack or a sheet.
- **No-code:** Make, Zapier, n8n, Google Sheets, Airtable, Slack via [Apify integrations](https://docs.apify.com/integrations).
- **API:** call it from Node.js or Python with `apify-client` - code on the [API tab](https://apify.com/topapi/instagram-scraper/api/python) and the [Apify API reference](https://docs.apify.com/api/v2).
- **MCP / AI agents:** connect Claude, Cursor or any MCP client through the [MCP tab](https://apify.com/topapi/instagram-scraper/api/mcp) and ask for Instagram posts in plain language.

### More TopApi scrapers

<table>
<tr>
<td>🎵 <a href="https://apify.com/topapi/tiktok-scraper">TikTok Scraper</a> - videos by profile, hashtag or URL with stats, sound and transcript</td>
<td>⭐ <a href="https://apify.com/topapi/google-maps-reviews-scraper">Google Maps Reviews Scraper</a> - every review of a place with owner replies and dates</td>
<td>🧭 <a href="https://apify.com/topapi">All TopApi actors</a> - social media, reviews and lead-gen scrapers built for scheduled runs</td>
</tr>
</table>

### Limits & empty runs

- **Results per run:** Instagram serves 10 posts per profile page and 12 per keyword page; `resultsLimit` and the date window are the cost controls. A profile with 3,000 posts is about 300 pages.
- **Keyword pages are partial:** Instagram publishes a signed-out keyword page only for some terms (3 of 6 common words in testing). Terms without one deliver nothing.
- **Not available signed-out:** `postsCount` on a profile (Instagram no longer shows it to signed-out visitors), comments beyond Instagram's occasional preview, `videoViewCount` on most videos (reels carry `videoPlayCount` instead), follower counts of accounts that only appear on a keyword page.
- **Private accounts** return a `Profile` row (if requested) and no posts; the run status says which accounts were private.
- **Media links expire:** `displayUrl`, `images`, `videoUrl` and avatars are signed CDN URLs valid for a few hours; download what you need.
- **Empty dataset** means the profiles were private or do not exist, the keyword has no public page, or every post was removed by your filters - the run status names which.

### FAQ

#### How many Instagram posts can Instagram Scraper collect in one run?

As many as the cap allows: 10 per profile page, 12 per keyword page, one request per post URL. A run reads pages until `resultsLimit`, `maxItems`, the date window or the end of the profile is reached. The default 50 per profile is 5 pages; set `0` to read a whole profile.

#### Can I run Instagram Scraper on a schedule to get new Instagram posts automatically?

Yes. Save your input as a task, open **Schedules**, pick the cadence and turn on `monitorMode`: each run remembers the posts it delivered per profile or keyword. On a profile it stops at the last run's newest post; on a keyword page it walks past the posts it already delivered and returns the next ones up to your cap. A run with nothing new delivers nothing.

#### Can I scrape Instagram reels with Instagram Scraper?

Yes. Reels appear in profile timelines with `productType: "clips"`, on keyword pages and as `/reel/` URLs; `postType: "reel"` keeps only them. Reel play counts come from the profile's reels tab or the keyword page.

#### Can I integrate Instagram Scraper with other apps?

Yes - Make, Zapier, n8n, Google Sheets, Slack and more via [Apify integrations](https://docs.apify.com/integrations), or use [webhooks](https://docs.apify.com/integrations/webhooks) to trigger an action when a run finishes.

#### Can I use Instagram Scraper with the Apify API?

Yes. The API lets you start runs, fetch datasets and manage schedules. Use `apify-client` for [Node.js](https://apify.com/topapi/instagram-scraper/api/javascript) or [Python](https://apify.com/topapi/instagram-scraper/api/python); the API tab has ready-to-paste code.

#### Can I use Instagram Scraper through an MCP server?

Yes. Open the [MCP tab](https://apify.com/topapi/instagram-scraper/api/mcp), connect your MCP client (Claude Desktop, Cursor, LibreChat...), and ask for Instagram posts in plain language. Turn on `compact` to keep rows small.

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

No. Instagram Scraper reads only what Instagram shows publicly to a signed-out visitor; you pass usernames, hashtags or URLs and nothing else.

#### Why did my Instagram Scraper run return no results?

In order of frequency seen in testing: the keyword has no public page (try a broader term), the account is private or misspelled, or the date window and filters removed every post. The run status message names the cause.

#### How is Instagram Scraper different from other Instagram scrapers?

It runs without a browser on 256 MB, so a 50-post profile takes seconds; it ships `engagementRate`, `captionCreatedAt`, trending-audio flags, every image rendition and reel play counts inside profile timelines; and it filters by date window, post type, likes, keyword, place and pinned posts.

#### Is it legal to scrape Instagram data?

Instagram Scraper extracts only publicly available Instagram posts; it does not log in or collect private data. Results may still contain personal data, which is regulated (for example by GDPR). Make sure you have a legitimate purpose before you use it.

#### Your feedback

We keep improving Instagram Scraper. Found a bug or missing a field? Open an issue on the [Issues tab](https://apify.com/topapi/instagram-scraper/issues/open) - we answer within one business day.

# Actor input Schema

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

Instagram usernames or profile URLs whose posts you want, e.g. "nasa", "@natgeo", "https://www.instagram.com/instagram/". Newest posts first (pinned posts first), 10 per page, posts, reels and carousels alike.

## `hashtags` (type: `array`):

Hashtags, keywords or tag URLs, e.g. "travel", "#foodie", "https://www.instagram.com/explore/tags/travel/". Instagram shows signed-out visitors a public keyword page (mostly reels, 12 per page, Instagram's ranking); that is what is read. Every row carries searchTerm.

## `postUrls` (type: `array`):

Direct post / reel URLs or bare shortcodes, e.g. "https://www.instagram.com/p/Dd9RyBWBVih/", "https://www.instagram.com/reel/Dd9RyBWBVih/", "Dd9RyBWBVih". One row per URL, one request each.

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

Absolute date (2026-09-01, 2026-09-01T12:00:00Z), relative to now (7 days, 3 weeks, 2 months, 1 year) or a day count (1 = today's posts, 2 = yesterday and today). Leave empty for no lower bound. Pinned posts are judged by their own date.

## `onlyPostsOlderThan` (type: `string`):

Absolute date or relative (e.g. 30 days). Combine with the field above for a window such as onlyPostsNewerThan "2026-01-01" + onlyPostsOlderThan "2026-06-30".

## `skipPinnedPosts` (type: `boolean`):

Leave out the posts a profile pinned to the top of its grid (often old). They are counted in the run summary.

## `postType` (type: `string`):

Keep only one kind of post. Reels are videos with productType "clips"; carousels come back with type "Sidecar" and their items in childPosts.

## `minLikes` (type: `integer`):

Keep only posts with at least this many likes, e.g. 10000 to keep hits only. 0 = no minimum. Posts whose owner hides like counts have likesCount null and are kept.

## `keywordFilter` (type: `string`):

Keep only posts whose caption, hashtags, tagged users, location or owner name contain this word or phrase, case-insensitive, e.g. "giveaway" or "recipe, meal prep" (comma = any of them).

## `withLocationOnly` (type: `boolean`):

Keep only posts that carry a location tag (locationName, locationId, city). Useful for local lead lists and venue research. On a 30-post test sample 7% of posts had one.

## `includeProfileSummary` (type: `boolean`):

Adds one row of type "Profile" per scraped profile: followers, following, bio, bio links, verified / private / business flags, category, business address, HD avatar, highlight count. Charged as the profile-summary event, once per profile that gets one.

## `monitorMode` (type: `boolean`):

Remembers, per profile / hashtag, which posts were already delivered (in the named key-value store below) and returns only new ones. On a profile the run stops at the last run's newest post, so a daily check of a 5,000-post account costs one page; on a keyword page it skips delivered posts and returns the next ones up to the cap. A run that finds nothing new delivers nothing.

## `monitorStoreName` (type: `string`):

Name of the key-value store that keeps the per-target memory for monitor mode. Give each separate feed (a client, a Slack channel) its own name so they do not hide posts from each other. Letters, digits and hyphens.

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

Cap per target after filters (your main cost control; you pay per delivered post). 0 = everything Instagram serves (a profile with 3,000 posts is about 300 pages). Instagram serves 10 posts per profile page and 12 per keyword page.

## `maxItems` (type: `integer`):

Hard cap for the whole run across all targets. 0 = no total cap (each target is still capped above).

## `compact` (type: `boolean`):

Core fields only (id, type, shortCode, url, caption, hashtags, timestamp, likes, comments, engagement, plays, display/video URL, duration, productType, pinned, paid partnership, location, music title, owner): about a fifth of the bytes, sized for AI agents and MCP clients.

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

Apify datacenter proxies serve every request this actor makes (measured on profiles, keyword pages and single posts). The actor rotates to a fresh proxy session when Instagram asks a session to wait, and keeps one session per batch of requests.

## `maxConcurrency` (type: `integer`):

How many single-post requests run at once (keyword pages and post URLs). 4 is a safe default; raise to 8 for big URL lists.

## Actor input object example

```json
{
  "usernames": [
    "nasa"
  ],
  "hashtags": [],
  "postUrls": [],
  "skipPinnedPosts": false,
  "postType": "all",
  "minLikes": 0,
  "keywordFilter": "",
  "withLocationOnly": false,
  "includeProfileSummary": false,
  "monitorMode": false,
  "monitorStoreName": "instagram-posts-monitor",
  "resultsLimit": 12,
  "maxItems": 0,
  "compact": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 4
}
```

# Actor output Schema

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

The dataset of Instagram posts (one item per post, reel or carousel; profile summary rows have type Profile).

## `summary` (type: `string`):

Per-target counts (read, filtered, already delivered, delivered), requests made, sessions used and bytes transferred.

# 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": [
        "nasa"
    ],
    "resultsLimit": 12
};

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

# Run the Actor and wait for it to finish
run = client.actor("topapi/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 '{
  "usernames": [
    "nasa"
  ],
  "resultsLimit": 12
}' |
apify call topapi/instagram-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,topapi/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/5UGcwS9WCCJbVqzDY/builds/1VoC5qHpuFnEODzev/openapi.json
