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

Scrape public Instagram in 14 modes: profile posts, Reels and tagged posts, profiles with bio and business contacts, comments and replies, followers, following, post likers, hashtag, location and audio feeds, search, stories and highlights. Flat JSON, no login or cookies needed.

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

## Pricing

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

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 extracts public Instagram data as clean, flat JSON. List the posts, Reels and tagged posts of any public profile, read profile details, post details, comments and replies, collect the posts of a hashtag, location or audio, search accounts, posts, Reels, hashtags, locations and audios, and list followers, following, post likers, similar accounts, stories and highlights. Every post comes with likes, plays, comments, caption, hashtags, mentions, location, music, carousel slides and the owner's name, ID and verified flag. No Instagram account, API keys, proxies or cookies are needed.

### What data can you get?

The Actor has 14 modes. Post modes share one flat post output, so one pipeline handles them.

#### Modes

| Mode | Give it | You get |
|---|---|---|
| `userPosts` | usernames | the latest posts of each public profile, pinned posts first |
| `profiles` | usernames | one full profile record per username: bio, links, counts, business details, related accounts, latest posts |
| `userReels` | usernames | the Reels of each profile |
| `taggedPosts` | usernames | the posts each profile is tagged in |
| `postDetails` | post or Reel links | one full post record per link |
| `comments` | post or Reel links, optional `commentSort`, `includeReplies` | the comments of each post, optionally with replies |
| `postLikers` | post or Reel links | the accounts that liked the post (as many as Instagram lists) |
| `hashtagPosts` | hashtags, optional `hashtagFeed` (top, recent, reels) | the posts under each hashtag |
| `locationPosts` | location IDs or links | the posts at each location |
| `audioPosts` | audio IDs or links | the Reels that use each audio |
| `search` | keywords, `searchType` | accounts, posts, Reels, hashtags, locations or audios found for each keyword |
| `followers` | usernames, `followType` | the accounts that follow each profile, or that it follows |
| `similarAccounts` | usernames | the accounts Instagram suggests as similar |
| `stories` | usernames, `storyType` | current stories, the highlight reels, or the stories inside each highlight reel |

#### Post fields (post modes, `search` posts and Reels, `stories`)

| Field | What it is |
|---|---|
| `postId`, `shortCode`, `url` | Instagram ID, shortcode and link of the post |
| `postType` | Image, Video or Sidecar (carousel) |
| `productType` | feed, clips (Reel), carousel_container, igtv or story |
| `caption`, `hashtags`, `mentions` | Caption as published, and the hashtags and @mentions in it |
| `createdAt` | Publish time, ISO 8601 UTC |
| `likeCount`, `commentCount` | Likes (null when hidden) and comments |
| `playCount`, `viewCount` | Plays and views of a video or Reel |
| `shareCount`, `repostCount`, `saveCount` | Shares, reposts and saves, when Instagram shows them |
| `durationSeconds`, `width`, `height` | Video length and size |
| `displayUrl`, `videoUrl` | Image and video file links (temporary) |
| `altText` | Accessibility caption, when present |
| `isVideo`, `isPinned`, `isSponsored`, `commentsDisabled`, `likesHidden` | Flags; null when the source does not say |
| `ownerId`, `ownerUsername`, `ownerFullName`, `ownerVerified`, `ownerPrivate`, `ownerProfilePicUrl` | The account that posted |
| `taggedUsers`, `coauthors` | Usernames tagged in the post and co-authors of collab posts |
| `locationId`, `locationName` | The tagged location |
| `musicId`, `musicTitle`, `musicArtist`, `isOriginalAudio` | The audio of a Reel |
| `childPosts` | Slides of a carousel: `postId`, `postType`, `displayUrl`, `videoUrl`, `width`, `height`, `durationSeconds` |
| `sourceInput` | The input that produced the item |
| `type` | `post` (stories: `story`; they also have `expiresAt`, `highlightId`, `highlightTitle`) |

#### Profile fields (mode `profiles`)

`userId`, `username`, `url`, `fullName`, `biography` (as published, with any contact details), `externalUrl`, `externalUrls` (every link in the bio), `followerCount`, `followingCount`, `postCount`, `igtvVideoCount`, `highlightReelCount`, `isVerified`, `isPrivate`, `isBusinessAccount`, `isProfessionalAccount`, `businessCategory`, `categoryName`, `businessEmail`, `businessPhone`, `businessAddress`, `hasClips`, `hasChannel`, `isJoinedRecently`, `pronouns`, `fbId`, `profilePicUrl`, `relatedProfiles` (identity fields of suggested accounts), `latestPosts` (post items), `type` = `profile`.

#### Comment fields (mode `comments`)

`commentId`, `text`, `createdAt`, `likeCount`, `replyCount`, `isPinned`, `parentCommentId` and `postId` (replies), `ownerId`, `ownerUsername`, `ownerFullName`, `ownerVerified`, `ownerPrivate`, `ownerProfilePicUrl`, `mentions`, `hashtags`, `sourceInput`, `type` = `comment`.

#### Account fields (followers, following, post likers, similar accounts, account search)

`userId`, `username`, `url`, `fullName`, `isVerified`, `isPrivate`, `profilePicUrl`, `relation` (follower, following, liker or similar), `sourceInput`; `type` is `user`, or `searchUser` for account search.

#### Other records

Highlight reels (`type` `highlight`): `itemId`, `title`, `mediaCount`, `createdAt`, `updatedAt`, `coverUrl`, `isPinned`. Hashtags (`hashtag`): `itemId`, `name`, `mediaCount`, `url`, `profilePicUrl`. Locations (`location`): `itemId`, `name`, `address`, `city`, `latitude`, `longitude`, `url`. Audios (`audio`): `itemId`, `audioId`, `title`, `artist`, `durationSeconds`, `isExplicit`, `coverUrl`, `previewUrl`.

### How to use Instagram Scraper

1. Open Instagram Scraper in Apify Console.
2. Choose a **Mode**.
3. Fill in the list that belongs to the mode: `usernames`, `postUrls`, `hashtags`, `keywords`, `locations` or `audios`, plus the mode option if it has one.
4. Set `maxResults`, the limit for each input.
5. Start the run, then export the dataset as JSON, CSV or Excel, or read it through the API.

### Input

| Field | Type | What it does | Default |
|---|---|---|---|
| `mode` | string | One of the 14 modes above | `userPosts` |
| `usernames` | array | `nasa`, `@nasa` or a profile link | `nasa` |
| `postUrls` | array | Post or Reel links, or shortcodes | a sample post |
| `hashtags` | array | `nasa`, `#nasa` or an explore/tags link | `nasa` |
| `keywords` | array | Search keywords | `travel` |
| `locations` | array | Location IDs or explore/locations links | a sample location |
| `audios` | array | Audio IDs or reels/audio links | a sample audio |
| `followType` | string | `followers` or `following` | `followers` |
| `searchType` | string | `users`, `posts`, `reels`, `hashtags`, `locations` or `audio` | `users` |
| `storyType` | string | `stories`, `highlights` or `highlightStories` | `stories` |
| `hashtagFeed` | string | `top`, `recent` or `reels` | `top` |
| `commentSort` | string | `recent` or `popular` | `recent` |
| `includeReplies` | boolean | Also fetch replies of comments with two or more | `false` |
| `maxResults` | integer | Items per input, 1 to 5000. Ignored by `profiles` and `postDetails` | `20` |

An empty input `{}` lists 20 posts of `nasa`. At most 50 inputs are used per run in the listing modes (1,000 in `profiles` and `postDetails`); extra ones are ignored without a warning.

```json
{"mode": "userPosts", "usernames": ["nasa", "https://www.instagram.com/natgeo/"], "maxResults": 50}
```

```json
{"mode": "comments", "postUrls": ["https://www.instagram.com/p/DeTUk4sDSp-/"], "commentSort": "popular", "includeReplies": true, "maxResults": 200}
```

```json
{"mode": "search", "searchType": "reels", "keywords": ["travel"], "maxResults": 50}
```

### Output example

Values are illustrative.

```json
{
  "type": "post",
  "postId": "4000000000000000001",
  "shortCode": "Dexample01",
  "url": "https://www.instagram.com/reel/Dexample01/",
  "postType": "Video",
  "productType": "clips",
  "caption": "Launch day #space",
  "hashtags": ["space"],
  "mentions": [],
  "createdAt": "2026-10-10T15:15:02Z",
  "likeCount": 7190,
  "commentCount": 71,
  "playCount": 105090,
  "durationSeconds": 43.766,
  "ownerUsername": "sample.account",
  "ownerVerified": true,
  "taggedUsers": [],
  "coauthors": [],
  "musicTitle": "Original audio",
  "isOriginalAudio": true,
  "childPosts": [],
  "sourceInput": "sample.account"
}
```

### How much does it cost?

The Actor uses pay-per-event pricing:

| Event | Price | When it is charged |
|---|---|---|
| Start fee (`run-start`) | $0.0025 | For each input of the listing modes (and once per run in `profiles` and `postDetails`). The first one is charged when the first request to the data source succeeds. Each further one is charged before that input's first request and is kept even if that input returns nothing. |
| Result (`result`) | $0.0023 | For each post, story, comment, reply, profile, highlight, hashtag, location, audio or account-search hit returned. |
| Account (`user`) | $0.0007 | For each follower, following, post liker or similar account returned. |

The start fee is not charged when the data source fails from the start or your spending limit cannot cover it.

Worked examples:

- 100 posts of one profile cost $0.0025 + 100 x $0.0023 = **$0.2325**.
- 1,000 followers of one profile cost $0.0025 + 1,000 x $0.0007 = **$0.7025**.
- 20 profile records cost $0.0025 + 20 x $0.0023 = **$0.0485**.

On the free Apify plan, every run returns a sample dataset: a real result of this Actor's prefilled input, captured on the date shown in the run status, so you can see exactly what the output looks like. Your own input is not used and nothing is charged. To run your own queries, use any paid Apify plan.

You never pay for more than `maxResults` items per input, and the run stops by itself if your spending limit is reached. An input that returns nothing (an account that does not exist, a hashtag with no posts) still costs its start fee. If the data source is down for the whole run, nothing is charged.

### Use cases

- **Influencer research**: pull profiles with followers, bio, business category and contact details, then their latest posts and Reels.
- **Competitor and brand monitoring**: track posts tagging a brand, hashtag feeds and location feeds with likes, plays and comments.
- **Audience analysis**: list followers, following and post likers, and read comment text with commenter profiles.
- **Trend research**: search Reels and audios by keyword, then list the Reels that use a trending audio.
- **Lead generation**: search accounts by keyword and read business email, phone and links from their profiles.
- **AI and data projects**: captions, hashtags and counts as clean rows for classification and dashboards.

### Integrations and API

Start runs through the Apify API, schedule them in Apify Console, and connect the dataset to Apify integrations and your own tools. Results can be downloaded as JSON, CSV or Excel.

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("clover_folktale/instagram-scraper").call(run_input={
    "mode": "userPosts",
    "usernames": ["nasa"],
    "maxResults": 50
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Tips and limits

- **Pages are small.** Profile posts and Reels come about 12 per request, comments about 15, followers 30 to 50. Large limits take many requests.
- **Thin pages end a listing.** A page that brings too few new items to pay for its own request ends the listing, so a listing can end before `maxResults`.
- **Highlights with one story are skipped** in `highlightStories`; list them with `highlights` if you need them.
- **Stories expire after 24 hours.** `stories` returns what is live at the time of the run.
- **Likers and some follower lists are partial.** Instagram lists only part of a very large audience; `postLikers` returns what Instagram shows.
- **Location, audio and hashtag inputs must exist.** Find location IDs with `search` and `searchType` `locations`. Audio IDs are the number in the audio page link.
- **Links are temporary.** Image, video, audio and profile picture links expire; download what you need soon after the run.
- **Numbers are a snapshot.** Counts are what Instagram shows at the time of the run; hidden like counts are null.
- **Often-empty fields:** `viewCount`, `shareCount`, `saveCount` and `repostCount` only exist for some post types; `commentsDisabled` and `isSponsored` are null when the source does not say; `taggedPosts`, hashtag and location items from the secondary source have fewer fields.
- **Free plan.** Every run on the free Apify plan returns a stored sample dataset (a real result of the prefilled input); your own input is not used and nothing is charged.

### FAQ

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

No. No account, API keys, proxies or cookies are needed. Private profiles are not readable.

#### Is it legal to scrape Instagram?

The Actor returns only public information: posts, counts, public profiles with their bio, public comments and public account lists. It does not return private messages or anything behind a login. Bios are returned as published, including contact details the account owner wrote there. You are responsible for how you use the data and for following the laws that apply to you.

#### How fresh is the data?

It is read live during the run.

#### Why are some fields empty?

Fields Instagram does not send are `null`; lists such as `hashtags` are empty `[]`. Some counts only exist for some post types.

#### How many results can I get?

Up to 5,000 items per input, with up to 50 inputs per run in the listing modes.

#### Can I schedule runs and export the data?

Yes, in Apify Console or through the API, as JSON, CSV or Excel.

#### What if a username, post or hashtag does not exist?

It returns nothing and still costs its start fee, because the request was made. Missing a field or a mode? Open an issue from the Actor page.

### More tools from the same developer

- [TikTok Scraper - Video Search, Hashtags & Author Profiles](https://apify.com/clover_folktale/tiktok-scraper)
- [Threads Scraper - Posts, Replies & User Profiles, No Login](https://apify.com/clover_folktale/threads-scraper)
- [YouTube Scraper - Shorts, Channel Videos & Video Search](https://apify.com/clover_folktale/youtube-scraper)
- [Reddit Scraper - Posts, Comments & User IDs, No Login](https://apify.com/clover_folktale/reddit-scraper)
- [Telegram Scraper - Channel Messages, Search & Info, No Login](https://apify.com/clover_folktale/telegram-scraper)

# Actor input Schema

## `mode` (type: `string`):

What to scrape. Each mode reads the list field named in its title below.

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

Profiles as nasa, @nasa or a link (https://www.instagram.com/nasa/). Falls back to "nasa" when empty.

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

Post or Reel links (https://www.instagram.com/p/DeTUk4sDSp-/) or shortcodes. Falls back to a sample post when empty.

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

Hashtags as nasa, #nasa or a link (https://www.instagram.com/explore/tags/nasa/). Falls back to "nasa" when empty.

## `keywords` (type: `array`):

Search keywords; each keyword is a separate search. Falls back to "travel" when empty.

## `locations` (type: `array`):

Location IDs (115963528414384) or links such as https://www.instagram.com/explore/locations/115963528414384/houston-texas/. Find IDs with search type locations. Falls back to a sample location when empty.

## `audios` (type: `array`):

Audio page IDs (18294184831034406) or links such as https://www.instagram.com/reels/audio/18294184831034406/. Falls back to a sample audio when empty.

## `followType` (type: `string`):

Whether to list the accounts that follow the profile or the accounts it follows.

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

What the keyword searches: accounts, posts, Reels, hashtags, locations or audios.

## `storyType` (type: `string`):

Current stories, the list of highlight reels, or the stories inside each highlight reel (reels with a single story are skipped).

## `hashtagFeed` (type: `string`):

Top posts, latest posts or Reels only.

## `commentSort` (type: `string`):

Newest or most popular comments first.

## `includeReplies` (type: `boolean`):

Also fetch the replies of comments that have two or more. Replies count toward maxResults.

## `maxResults` (type: `integer`):

Maximum items for each username, post, hashtag, location, audio or keyword (up to 5000). Ignored by modes profiles and postDetails, which return one record per input. You are charged $0.0023 per item ($0.0007 per account in followers, postLikers and similarAccounts), plus a $0.0025 start fee for each input (not in profiles and postDetails, which have one start fee per run).

## Actor input object example

```json
{
  "mode": "userPosts",
  "usernames": [
    "nasa"
  ],
  "postUrls": [
    "https://www.instagram.com/p/DeTUk4sDSp-/"
  ],
  "hashtags": [
    "nasa"
  ],
  "keywords": [
    "travel"
  ],
  "locations": [
    "115963528414384"
  ],
  "audios": [
    "18294184831034406"
  ],
  "followType": "followers",
  "searchType": "users",
  "storyType": "stories",
  "hashtagFeed": "top",
  "commentSort": "recent",
  "includeReplies": false,
  "maxResults": 20
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items (JSON, CSV, Excel via the dataset API).

# 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"
    ],
    "postUrls": [
        "https://www.instagram.com/p/DeTUk4sDSp-/"
    ],
    "hashtags": [
        "nasa"
    ],
    "keywords": [
        "travel"
    ],
    "locations": [
        "115963528414384"
    ],
    "audios": [
        "18294184831034406"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("clover_folktale/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"],
    "postUrls": ["https://www.instagram.com/p/DeTUk4sDSp-/"],
    "hashtags": ["nasa"],
    "keywords": ["travel"],
    "locations": ["115963528414384"],
    "audios": ["18294184831034406"],
}

# Run the Actor and wait for it to finish
run = client.actor("clover_folktale/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"
  ],
  "postUrls": [
    "https://www.instagram.com/p/DeTUk4sDSp-/"
  ],
  "hashtags": [
    "nasa"
  ],
  "keywords": [
    "travel"
  ],
  "locations": [
    "115963528414384"
  ],
  "audios": [
    "18294184831034406"
  ]
}' |
apify call clover_folktale/instagram-scraper --silent --output-dataset

```

## MCP server setup

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