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

Scrape public Instagram profiles, posts, reels, comments, hashtags and places with no login or cookies. Get followers, bio contacts, likes, plays, captions and media links. Bulk input, auto proxy fallback. Export JSON, CSV or Excel for lead generation and influencer research.

- **URL**: https://apify.com/data_minds/instagram-scraper.md
- **Developed by:** [Data Minds](https://apify.com/data_minds) (community)
- **Features:** Limited permissions
- **Stats:** 18 total users, 10 monthly users, 99.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

### What is Instagram Scraper?

**Instagram Scraper** collects public Instagram data from profile links, @usernames, post and reel links, hashtags, topic keywords and places, for influencer research, hashtag monitoring and lead generation. Choose what to return, and it saves profile details, posts, reels, comments and related profiles in separate tables, with no login or cookies. Pay per result, from $0.002 on Free to $0.0014 on Gold.

Typical use cases:

- 👥 **Influencer research and vetting.** Find Instagram influencers and compare followers, engagement rate, posting frequency and top hashtags across many accounts.
- 📈 **Competitor content analysis.** Pull the latest posts and reels of rival brands with likes, comments and play counts.
- 🔔 **Hashtag monitoring and brand monitoring.** Monitor Instagram hashtags and topics, and use the monitoring key so each run returns only new posts.
- 📧 **Lead generation from Instagram bios.** Collect public emails, phone numbers and links shown on business and creator profiles.
- 💬 **Comment and sentiment analysis.** Export comment text, authors, likes and reply counts for social listening.
- 📍 **Social media monitoring and market research.** Read place details and posts tagged at a location for Instagram market research.

Because it runs on the Apify platform, you also get the Apify API, scheduling, webhooks, integrations and downloads in JSON, CSV, Excel, XML, HTML and RSS.

#### What can Instagram Scraper do?

- 🔗 Accept many inputs in one run: profile links, @usernames, post and reel links, #hashtags, topic keywords, place links and numeric user ids.
- 🧩 Scrape public Instagram profiles and return details, posts, reels, comments and related profiles, each in its own table.
- 🎞 Scrape Instagram reels with their play counts.
- 🔎 Scrape Instagram posts by date, and filter by post type, minimum likes, comments or video plays, caption words, pinned posts and paid partnerships.
- 📊 Add profile statistics such as average likes, engagement rate and posting cadence.
- 🔔 Remember what earlier runs returned when you set a monitoring key.
- 🛑 Stop at a maximum number of rows per run and respect your spend limit.

***

### What data can Instagram Scraper extract?

Each saved row has a `recordType` (`profile`, `post`, `comment`, `location` or `keyword`) and a `scrapedAt` time. Every input also gets one free overview row in the inputs table.

#### Profile fields

| Data | Fields |
|---|---|
| 👤 Identity | `id`, `username`, `fullName`, `url`, `isVerified`, `isPrivate`, `isBusiness`, `accountType`, `category`, `pronouns`, `isMemorialized` |
| 📝 Bio and links | `biography`, `bioHashtags`, `bioMentions`, `externalUrl`, `bioLinks` |
| 📧 Contacts | `emails`, `phones`, `whatsapp`, `address` |
| 🔢 Counts | `followersCount`, `followsCount`, `postsCount`, `postsCountIsApprox` |
| 📷 Pictures and extras | `profilePicUrl`, `profilePicUrlHD`, `hasActiveStory`, `threadsUsername`, `fbid` |
| 📈 Statistics | `stats` with `postsAnalyzed`, `avgLikes`, `medianLikes`, `avgComments`, `avgVideoPlays`, `engagementRate`, `postsPerWeek`, `reelShare`, `paidPartnershipShare`, `topHashtags`, `topMentions` |
| 👯 Related accounts | `relatedProfiles` |
| 🧾 Run details | `recordType`, `source`, `scrapedAt`, `inputUrl` |
| 🔁 Same value, common names | `verified`, `private`, `isBusinessAccount`, `businessCategoryName`, `externalUrls` |

#### Post and reel fields

| Data | Fields |
|---|---|
| 🆔 Identity | `id`, `shortCode`, `url`, `type`, `productType`, `isReel`, `isPinned` |
| 📝 Text and tags | `caption`, `captionEdited`, `hashtags`, `mentions`, `taggedUsers`, `coauthors`, `sponsors`, `isPaidPartnership` |
| 👍 Engagement | `likesCount`, `likesHidden`, `commentsCount`, `videoPlayCount`, `engagementRate`, `commentsDisabled` |
| 🕒 Time | `timestamp`, `takenAtUnix` |
| 📷 Media | `displayUrl`, `videoUrl`, `images`, `childPosts`, `width`, `height`, `videoDuration`, `hasAudio`, `alt`, `aiLabel`, `aiLabelText` |
| 👤 Author | `ownerUsername`, `ownerId`, `ownerFullName`, `ownerIsVerified`, `ownerFollowersCount` |
| 📍 Place and music | `location`, `locationName`, `locationId`, `music` |
| 💬 Comments inside the post | `latestComments` |
| 🧾 Run details | `recordType`, `source`, `scrapedAt`, `inputUrl`, `searchTerm`, `dataSource` |
| 🔁 Same value, common names | `dimensionsWidth`, `dimensionsHeight`, `musicInfo`, `coauthorProducers`, `paidPartnership`, `isCommentsDisabled` |

#### Comment fields

| Data | Fields |
|---|---|
| 💬 Comment | `id`, `text`, `hashtags`, `mentions`, `timestamp`, `createdAtUnix`, `likesCount`, `repliesCount`, `parentId`, `isGif`, `gifUrl` |
| 👤 Commenter | `ownerUsername`, `ownerId`, `ownerIsVerified`, `ownerProfilePicUrl`, `isPostOwner` |
| 🔗 Post | `postShortCode`, `postUrl`, `postOwnerUsername` |
| 🧾 Run details | `recordType`, `scrapedAt`, `inputUrl` |

#### Place, topic and input fields

| Data | Fields |
|---|---|
| 📍 Place | `id`, `name`, `slug`, `url`, `category`, `lat`, `lng`, `address`, `city`, `zip`, `phone`, `website`, `priceRange`, `postsCount`, `hours`, `source`, `recordType`, `scrapedAt`, `inputUrl` |
| 🔖 Topic | `keyword`, `url`, `relatedKeywords`, `description`, `descriptionSources`, `searchType`, `searchTerm`, `recordType`, `scrapedAt`, `inputUrl` |
| 🧭 Input overview | `input`, `kind`, `value`, `status`, `rowsSaved`, `error`, `errorDescription`, `notes`, `seconds` |

> **Note:** Fields appear only when a value is available. Emails, phones and addresses exist only on profiles that publish them, `likesCount` is empty when the owner hides likes, and `videoPlayCount` applies to videos and reels.

#### What data can't Instagram Scraper extract?

It reads public pages only, so private profiles' posts are not available, and the output has no stories, direct messages or follower lists. Comment `likesCount` and `repliesCount` are often empty.

***

### How to scrape Instagram profiles, posts and comments

1. Create a free Apify account at [console.apify.com/sign-up](https://console.apify.com/sign-up).
2. Open [Instagram Scraper](https://apify.com/data_minds/instagram-scraper) in Apify Console.
3. Add your inputs to `urls`: profile links, @usernames, post or reel links, #hashtags, topic keywords or place links.
4. Pick what to return in `resultsType`: `details`, `posts`, `reels`, `comments` or `relatedProfiles`.
5. Set `resultsLimit` for posts per input, `commentsLimit` for comments per post, and any optional filters.
6. Click Start and watch rows appear in the Output tab as they are saved.
7. Download the results as JSON, CSV, Excel, XML, HTML or RSS, or read them through the API.

The scraped site is [Instagram](https://www.instagram.com/).

***

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

Instagram Scraper uses pay-per-event pricing. You pay a small start fee per run plus a fee for each saved result, and your Apify platform usage is billed in addition. Your price per result depends on your Apify plan.

| Apify plan | Price per result | Price per 1,000 results |
|---|---|---|
| 🆓 Free | $0.002 | $2.00 |
| 🥉 Bronze | $0.0018 | $1.80 |
| 🥈 Silver | $0.0016 | $1.60 |
| 🥇 Gold | $0.0014 | $1.40 |

The start event costs $0.00005 per GB of memory, with a minimum of one event. The Actor's default memory is 1024 MB, so each run is charged one start event, $0.00005.

**Worked example:** on the Gold plan, a run that saves 1,000 results costs 1,000 x $0.0014 = $1.40, plus the $0.00005 start event and platform usage billed in addition.

Profiles, posts, comments, places and topics each count as one result. The inputs overview rows are free.

#### Is scraping Instagram free?

You can try it without paying. The $5 monthly credit on the Apify Free plan covers about 2,500 results at $0.002 each, before platform usage. See the [pricing tab](https://apify.com/data_minds/instagram-scraper/pricing) for the current prices.

***

### Input

Only `urls` is required. Everything else has a default. Open the full [input schema](https://apify.com/data_minds/instagram-scraper/input-schema) for the form layout. This is the prefilled input:

```json
{
  "urls": ["https://www.instagram.com/natgeo/"],
  "resultsType": ["details", "posts"],
  "commentsLimit": 10,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `urls` | array | Yes | none | Profile links or @usernames, post and reel links, #hashtags or hashtag links, topic keywords, place links, numeric user ids. |
| `resultsType` | array | No | `["details","posts"]` | `details`, `posts`, `reels`, `comments`, `relatedProfiles`. |
| `resultsLimit` | integer | No | 10 | Posts or reels per profile, hashtag, topic or place (1 to 100000). |
| `commentsLimit` | integer | No | 0 | Comments per post (0 to 50000). Above 0 turns comments on. |
| `search` | string | No | empty | Extra hashtag or topic added to your links. |
| `searchType` | string | No | `hashtag` | `hashtag` or `keyword`. |
| `onlyPostsNewerThan` | string | No | empty | Date or relative value such as `7 days`. |
| `onlyPostsOlderThan` | string | No | empty | Date or relative value. |
| `skipPinnedPosts` | boolean | No | false | Leave out pinned posts. |
| `postTypes` | array | No | all | `image`, `video`, `carousel`, `reel`. |
| `minLikes` | integer | No | 0 | Minimum likes. |
| `minComments` | integer | No | 0 | Minimum comments. |
| `minVideoPlays` | integer | No | 0 | Minimum plays for videos and reels. |
| `captionKeywords` | array | No | empty | Keep posts whose caption contains any of these. |
| `excludeCaptionKeywords` | array | No | empty | Drop posts whose caption contains any of these. |
| `onlyPaidPartnerships` | boolean | No | false | Keep only paid partnership posts. |
| `commentsNewerThan` | string | No | empty | Keep comments after this date. |
| `profileStats` | boolean | No | true | Add averages and engagement rate to profile rows. |
| `addParentData` | boolean | No | false | Add a `dataSource` label to posts. |
| `embedCommentsInPosts` | boolean | No | false | Store comments in `latestComments` instead of the comments table. |
| `enrichSearchResults` | boolean | No | true | Fetch full details for hashtag, topic and reel results. |
| `enrichOwners` | boolean | No | true | Read author followers so engagement rate can be calculated. |
| `addReelPlayCounts` | boolean | No | true | Fill play counts of reels found in a profile feed. |
| `playCountLookupPages` | integer | No | 10 | How far back to look for older reel play counts (0 to 100). |
| `includeAltText` | boolean | No | true | Fill the `alt` field. |
| `maxRelatedProfiles` | integer | No | 30 | Related profiles kept per profile (1 to 100). |
| `incrementalKey` | string | No | empty | Monitoring name that returns only new posts and comments. |
| `excludeIds` | array | No | empty | Post ids, short codes or comment ids to skip. |
| `maxTotalRecords` | integer | No | 1000 | Hard stop for rows in the whole run. |
| `concurrency` | integer | No | 4 | Parallel requests (1 to 10). |
| `requestDelay` | number | No | 0.4 | Pause after each request in seconds (0 to 10). |
| `proxyConfiguration` | object | No | `{"useApifyProxy": false}` | Optional proxy configuration. |

#### Tricky fields

**`commentsLimit` and `resultsType`**

- ✅ Good: set `commentsLimit` to `20` to get comments without ticking anything else.
- ❌ Bad: leaving `commentsLimit` at `0` and expecting comments without `comments` in `resultsType`.

> **Warning:** Comments count as rows. Raise `maxTotalRecords` when you ask for many comments per post, or the run stops at the limit.

**`maxTotalRecords`**

- ✅ Good: `5000` for 20 profiles with 10 posts and 20 comments each.
- ❌ Bad: keeping `1000` and wondering why a large comment run ends early.

**`incrementalKey`**

- ✅ Good: `brand-watch` on a scheduled run to get only posts not returned before.
- ❌ Bad: changing the name every run, which returns everything again.

**`onlyPostsNewerThan`**

- ✅ Good: `7 days` or `2026-10-01`.
- ❌ Bad: `last week`, which is not a valid format.

> **Warning:** Pinned posts may still appear in date filters. Use `skipPinnedPosts` to remove them.

***

### Output

Results appear in the Output tab as separate tables: profiles, posts and reels, comments, places, topics and an inputs overview. The default dataset holds every row in the order it was found. Download any table as JSON, CSV, Excel, XML, HTML or RSS, or read it through the API. A `SUMMARY` record lists totals such as `rows`, `rowsBilled`, `rowsByType`, `durationSeconds`, `stoppedBecause`, `inputs` and `notices`.

#### JSON example

Profile row for the prefilled input (shortened):

```json
{
  "recordType": "profile",
  "id": "787132",
  "username": "natgeo",
  "fullName": "Example Profile",
  "url": "https://www.instagram.com/natgeo/",
  "biography": "Example bio text",
  "externalUrl": "https://example.com",
  "emails": ["press@example.com"],
  "phones": [],
  "followersCount": 1000000,
  "followsCount": 150,
  "postsCount": 32000,
  "isVerified": true,
  "isPrivate": false,
  "accountType": "business",
  "stats": { "postsAnalyzed": 10, "avgLikes": 45000.5, "engagementRate": 2.4 },
  "source": { "type": "profile", "value": "natgeo" },
  "scrapedAt": "2026-10-12T10:00:00.000Z",
  "inputUrl": "https://www.instagram.com/natgeo/"
}
```

Post row (shortened):

```json
{
  "recordType": "post",
  "id": "3800000000000000000",
  "shortCode": "ABC123",
  "url": "https://www.instagram.com/p/ABC123/",
  "type": "Image",
  "caption": "Example caption",
  "hashtags": ["example"],
  "timestamp": "2026-09-10T12:00:00.000Z",
  "likesCount": 79600,
  "commentsCount": 577,
  "displayUrl": "https://example.com/post.jpg",
  "ownerUsername": "natgeo",
  "engagementRate": 2.4,
  "source": { "type": "profile", "value": "natgeo" },
  "scrapedAt": "2026-10-12T10:00:00.000Z",
  "inputUrl": "https://www.instagram.com/natgeo/"
}
```

Comment row (shortened):

```json
{
  "recordType": "comment",
  "id": "18000000000000000",
  "postShortCode": "ABC123",
  "postUrl": "https://www.instagram.com/p/ABC123/",
  "text": "Example comment",
  "timestamp": "2026-09-10T13:00:00.000Z",
  "likesCount": 3,
  "repliesCount": 0,
  "ownerUsername": "example_user",
  "isPostOwner": false,
  "scrapedAt": "2026-10-12T10:00:00.000Z",
  "inputUrl": "https://www.instagram.com/natgeo/"
}
```

Place row (shortened):

```json
{
  "recordType": "location",
  "id": "213385402",
  "name": "Example Place",
  "city": "New York",
  "lat": 40.71,
  "lng": -74.0,
  "postsCount": 12000000,
  "url": "https://example.com/place",
  "scrapedAt": "2026-10-12T10:00:00.000Z"
}
```

Topic row (shortened):

```json
{
  "recordType": "keyword",
  "keyword": "travel",
  "searchType": "hashtag",
  "relatedKeywords": ["travel photography"],
  "url": "https://example.com/topic",
  "scrapedAt": "2026-10-12T10:00:00.000Z",
  "inputUrl": "#travel"
}
```

Inputs overview row:

```json
{
  "input": "https://www.instagram.com/natgeo/",
  "kind": "profile",
  "value": "natgeo",
  "status": "ok",
  "rowsSaved": { "profile": 1, "post": 10 },
  "error": null,
  "errorDescription": null,
  "notes": [],
  "seconds": 12.4
}
```

#### Notes and limitations

- It collects public data only and needs no login or cookies.
- Comment `likesCount` and `repliesCount` can be empty.
- `likesCount` can be empty when the owner hides likes.
- Hashtag, topic and place results can include fewer fields unless `enrichSearchResults` is on.
- A run stops at `maxTotalRecords` or at your spend limit. Rows already saved are kept.

***

### Tips and advanced usage

- Start small: the default of 10 posts per input finishes quickly. Raise `resultsLimit` once the output looks right.
- Turn off `profileStats`, `enrichSearchResults`, `enrichOwners` and `includeAltText` when you do not need them. Each extra detail adds run time.
- Use `postTypes`, `minLikes` and `captionKeywords` to keep only the posts you need, so you pay for fewer rows.
- Schedule a run with `incrementalKey` to monitor a profile or hashtag without paying for the same posts twice.
- If a run returns fewer rows than expected, check the inputs overview table for the status and notes of each input.

***

### Integrations and API

#### Can I use Instagram Scraper as an API?

Yes. Start runs and read results with the [Apify API](https://docs.apify.com/api/v2) or the apify-client packages for Node.js and Python. Open the [API tab](https://apify.com/data_minds/instagram-scraper/api) for ready-made calls.

#### How to scrape Instagram with Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("data_minds/instagram-scraper").call(run_input={
    "urls": ["https://www.instagram.com/natgeo/"],
    "resultsType": ["details", "posts"],
    "commentsLimit": 10,
    "proxyConfiguration": {"useApifyProxy": False},
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

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

Yes. Apify connects with Make, Zapier, Google Sheets and Slack, and supports [webhooks](https://docs.apify.com/integrations/webhooks) that fire when a run finishes. You can also schedule runs, for example a daily hashtag check with a monitoring key.

#### Can I use Instagram Scraper with AI agents (MCP)?

Yes. Connect it through the Apify MCP server and the [MCP tab](https://apify.com/data_minds/instagram-scraper/api/mcp), so an AI assistant can run it and read the results.

***

### Other Instagram and social media scrapers

| Actor | What it does |
|---|---|
| 🔗 [Facebook Ads Library Scraper](https://apify.com/data_minds/facebook-ads-library-scraper) | Scrape public ads from the Meta Ad Library by keyword, Facebook page or Ad Library link: ad copy, creatives, landing pages, run dates, advertiser... |
| 🔗 [Facebook Event Scraper](https://apify.com/data_minds/facebook-event-scraper) | Scrape public Facebook events in bulk from search queries, search/explore links, page and group event lists or single event links: dates, places... |
| [Facebook Pages Scraper](https://apify.com/data_minds/facebook-pages-scraper) | Scrapes public Facebook Page data in bulk: name, category, likes, followers, email, phone, website and address. |
| [Facebook Reels Scraper](https://apify.com/data_minds/facebook-reels-scraper) | Scrapes Facebook Reels from public pages, profiles or reel URLs: captions, play counts, reactions and comments. |
| 🔗 [X (Twitter) Scraper Unlimited – No Limits](https://apify.com/data_minds/twitter-x-scraper-unlimited-no-limits) | Scrape X (Twitter) posts, profiles, articles, threads and analytics from links, handles or search terms. |

***

### FAQ

#### Is it legal to scrape Instagram?

Scraping publicly available data is generally considered lawful in many places, but the rules depend on your country, the data and how you use it. Avoid collecting private information, and respect Instagram's terms and data protection laws. Read [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/). This is not legal advice.

#### How does Instagram Scraper work?

You give it Instagram links, usernames, hashtags, topics or places and choose what to return. The Actor then reads the public information for each input and saves one row per profile, post, comment, place or topic. Rows appear in the Output tab as they are saved, and each input gets an overview row.

#### Why scrape Instagram data?

People scrape Instagram for influencer research, competitor content analysis, hashtag and brand monitoring, lead generation from public bio contacts, and comment analysis. Structured exports let you compare accounts, track engagement rate over time and feed spreadsheets, dashboards or other tools without copying data by hand.

#### Can you scrape Instagram without login?

Yes. Instagram Scraper needs no login, cookies or Instagram account, and it collects only public information. Private profiles are not available. Add public profile links, hashtags, topics or places, choose what to return, and start the run to get structured rows in your results tables.

#### Why did I get fewer results than expected?

Several settings can limit a run: `resultsLimit`, `maxTotalRecords`, your spend limit and the post filters you set. Check the inputs overview table for each input's status and notes. A profile may also simply have fewer posts than requested, or hide its like counts.

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

Yes. Open the Output tab, choose a table such as profiles, posts or comments, and download it as CSV, Excel, JSON, XML, HTML or RSS. You can also fetch the same data through the Apify API for use in spreadsheets, databases or reporting tools.

#### How do I get only new Instagram posts?

Set `incrementalKey` to a name such as `brand-watch` and schedule the Actor. Each later run with the same name skips posts and comments that earlier runs already returned, so you pay only for new rows when monitoring a profile or hashtag over time.

#### Instagram Scraper is not working. What should I do?

Open the run log and the inputs overview table to see which input failed and why. Check that links are public and spelled correctly, then retry later. If the problem continues, report it in the [Issues tab](https://apify.com/data_minds/instagram-scraper/issues/open) with the run link and your input.

***

### Support and feedback

Found a bug or need a field added? Open the [Issues tab](https://apify.com/data_minds/instagram-scraper/issues/open). For custom solutions or questions, email hello.dataminds@gmail.com.

Built and maintained by the [data_minds team on Apify](https://apify.com/data_minds).

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Instagram or Meta. You are responsible for using the data in line with applicable laws and platform terms.

# Actor input Schema

## `urls` (type: `array`):

Add one or hundreds, and mix them freely: profile links or @usernames, post and reel links, #hashtags or hashtag links, topic keywords, place links, or numeric user ids. Examples: https://www.instagram.com/natgeo/ , @natgeo , #travel , street food bangkok.

## `resultsType` (type: `array`):

Profile details returns the account card. Posts and Reels return their feeds. Comments adds the comments of every post collected. Related profiles adds the accounts Instagram suggests. Post links always return the post itself.

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

How many posts or reels to collect for each profile, hashtag, topic or place.

## `commentsLimit` (type: `integer`):

How many comments to collect for every post. Any number above 0 turns comments on by itself. 0 collects none, unless Comments is ticked above (then 10 per post). Instagram shows visitors who are not logged in only part of a post's comments, and no like or reply counts.

## `search` (type: `string`):

Optional extra search term added to your links. Use a hashtag such as travel or a topic such as street food bangkok.

## `searchType` (type: `string`):

Whether the search term above is a hashtag or a topic keyword.

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

Keep posts published after this date. Pick a date, or type a relative value such as 7 days, 2 months or 1 year. Times are UTC. Pinned posts may still appear. Leave empty for no limit.

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

Keep posts published before this date. Same formats as 'Posts newer than'; use both for a date range. Leave empty for no limit.

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

Leave out posts pinned to the top of a profile.

## `postTypes` (type: `array`):

Keep only these kinds of posts. Leave empty for all.

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

Keep only posts with at least this many likes. 0 keeps all.

## `minComments` (type: `integer`):

Keep only posts with at least this many comments. 0 keeps all.

## `minVideoPlays` (type: `integer`):

Keep only videos and reels with at least this many plays. 0 keeps all.

## `captionKeywords` (type: `array`):

Keep only posts whose caption contains any of these words or phrases. Leave empty to keep all.

## `excludeCaptionKeywords` (type: `array`):

Drop posts whose caption contains any of these words or phrases.

## `onlyPaidPartnerships` (type: `boolean`):

Keep only posts marked as a paid partnership.

## `commentsNewerThan` (type: `string`):

Keep comments posted after this date. Pick a date, or type a relative value such as 3 days or 1 month. Leave empty for no limit.

## `profileStats` (type: `boolean`):

Add averages for likes, comments, plays, engagement rate, posting cadence and top hashtags to every profile row.

## `addParentData` (type: `boolean`):

Add a dataSource field to every post: profile for profile posts, hashtag for hashtag posts, keyword, location or post.

## `embedCommentsInPosts` (type: `boolean`):

Store the comments in each post's latestComments field instead of as separate rows in the Comments table.

## `enrichSearchResults` (type: `boolean`):

Hashtag, topic and reel results arrive with few fields. Switch on to fetch likes, date, tags and music for each (adds run time for every post).

## `enrichOwners` (type: `boolean`):

Read the follower count of each post author so engagement rate can be calculated for hashtag, topic, single-post and collaboration posts (adds run time for every author).

## `addReelPlayCounts` (type: `boolean`):

Fill the play count of reels found in a profile feed.

## `playCountLookupPages` (type: `integer`):

How far back to look for the play count of older reels that have none yet. Higher values take longer.

## `includeAltText` (type: `boolean`):

Fill the alt field with Instagram's image description (adds run time).

## `maxRelatedProfiles` (type: `integer`):

Most related profiles to keep for each profile. Used when Related profiles is selected.

## `incrementalKey` (type: `string`):

Give a name such as brand-watch to return only posts and comments that earlier runs with the same name have not returned yet. Leave empty to return everything every time.

## `excludeIds` (type: `array`):

Post ids, short codes or comment ids that must never be returned.

## `maxTotalRecords` (type: `integer`):

Hard stop for the whole run (profiles, posts and comments together). Comments count as rows, so raise it when you ask for many comments per post.

## `concurrency` (type: `integer`):

How many requests run at the same time. Lower it if Instagram slows you down.

## `requestDelay` (type: `number`):

Pause after each request in seconds. A little random variation is added.

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

Optional. Choose an Apify proxy or your own proxy if you want requests to go through one. Leave the default if you do not need it.

## Actor input object example

```json
{
  "urls": [
    "https://www.instagram.com/natgeo/"
  ],
  "resultsType": [
    "details",
    "posts"
  ],
  "resultsLimit": 10,
  "commentsLimit": 10,
  "searchType": "hashtag",
  "skipPinnedPosts": false,
  "minLikes": 0,
  "minComments": 0,
  "minVideoPlays": 0,
  "onlyPaidPartnerships": false,
  "profileStats": true,
  "addParentData": false,
  "embedCommentsInPosts": false,
  "enrichSearchResults": true,
  "enrichOwners": true,
  "addReelPlayCounts": true,
  "playCountLookupPages": 10,
  "includeAltText": true,
  "maxRelatedProfiles": 30,
  "maxTotalRecords": 1000,
  "concurrency": 4,
  "requestDelay": 0.4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `profiles` (type: `string`):

Followers, bio, contact details, statistics and related profiles per account.

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

Captions, likes, comments, plays, media links, tags, places and music.

## `comments` (type: `string`):

Comment text, author, likes, replies and time per post.

## `locations` (type: `string`):

Place details: address, coordinates, contacts and post count.

## `keywords` (type: `string`):

Searched hashtags and topics with related topics.

## `sources` (type: `string`):

One row per input: status, rows saved and what went wrong.

## `all` (type: `string`):

Every saved row in the order it was found, all types together.

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

Totals for the whole 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 = {
    "urls": [
        "https://www.instagram.com/natgeo/"
    ],
    "resultsType": [
        "details",
        "posts"
    ],
    "commentsLimit": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_minds/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 = {
    "urls": ["https://www.instagram.com/natgeo/"],
    "resultsType": [
        "details",
        "posts",
    ],
    "commentsLimit": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("data_minds/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 '{
  "urls": [
    "https://www.instagram.com/natgeo/"
  ],
  "resultsType": [
    "details",
    "posts"
  ],
  "commentsLimit": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call data_minds/instagram-scraper --silent --output-dataset

```

## MCP server setup

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