# Instagram Profile Scraper: Follower Count, Bio, Posts, Reels (`s-r/instagram-profile-scraper`) Actor

Instagram profile scraper, no login: public profiles by username or profile URL with follower count, following, post count, bio, link-in-bio URLs, verified badge, profile picture and user id, plus posts and Reels with likes, comments and views. An Instagram scraper for marketing and research.

- **URL**: https://apify.com/s-r/instagram-profile-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Features:** Limited permissions
- **Stats:** 17 total users, 6 monthly users, 99.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 profile returneds

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 Profile Scraper - Follower Count, Posts and Reels

This Instagram profile scraper turns a list of usernames or profile URLs into a clean table of public profile data: follower count, following, post count, biography, link-in-bio URLs, verified badge, profile picture and the stable numeric user id. Use it to vet influencers, benchmark competitors or build a creator database without logging in, without cookies and without an Instagram API key.

By default you get exactly one row per profile. Ask for timeline posts or Reels and those arrive as extra rows under the profile they belong to, with likes, comments, views, captions, hashtags and mentions.

### What the Instagram profile scraper returns

- `followers`, `following` and `posts_count` - the headline counts, as numbers
- `full_name`, `username` and `pronouns` - how the account presents itself
- `biography`, `bio_links`, `bio_emails` and `related_profiles` - biography, link-in-bio URLs, email addresses written in the bio and related accounts, when available
- `is_verified`, `is_business_account` and `is_private` - badge state and account type
- `profile_pic_url` and `user_id` - image URL and the stable numeric id for joins
- `recent_post_shortcodes` and `recent_post_count` - the newest posts shown on the profile
- Posts per profile back through the account's full history (up to 1000), with exact likes, comments and views, or profile data only when set to zero
- The profile's Reels tab with play counts and audio, when `maxReelsPerProfile` is set

### Why use this Instagram profile scraper

Follower counts are the most requested and least accessible number on Instagram. The Graph API returns them only for accounts you own or manage, which rules out every competitor, prospect and creator you might actually want to measure. The public profile page carries the figure, but reading it by hand for hundreds of accounts is slow and error-prone.

This actor reads the logged-out public profile and returns it as a row. It accepts bare usernames, @handles or full profile URLs interchangeably, so a list assembled by hand from different sources works without normalising it first.

### Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `search` | array | yes | none (prefilled with `natgeo` in the console) | Instagram usernames or profile URLs, one per line. |
| `maxPostsPerProfile` | integer | no | `0` | Posts to also return per profile, newest first, back through the full history (up to 1000). Left at 0 you get one row and one charge per profile. Each post returned is billed as its own, cheaper post event. |
| `maxReelsPerProfile` | integer | no | `0` | Reels to return from the profile's Reels tab (up to 1000), billed as post events. Reels already returned as posts are returned once. |

Example input, two profiles with the three newest posts each:

```json
{
  "search": ["nasa", "https://www.instagram.com/nike/"],
  "maxPostsPerProfile": 3
}
```

### Output

One row per profile, followed by its post and Reel rows when you asked for them. `record_type` tells them apart.

#### Profile row

| Field | Description |
|---|---|
| `record_type` | `profile` |
| `username` | Instagram handle |
| `url` | Public Instagram URL of the profile |
| `full_name` | Display name |
| `user_id` | Instagram numeric user id |
| `followers` | Follower count |
| `following` | Accounts this profile follows; `null` when the public profile does not show it |
| `posts_count` | Total posts on the profile |
| `reels_count`, `highlight_reel_count` | Reels and story highlights on the profile, when available |
| `is_verified` | Whether the account carries the verified badge |
| `has_public_story` | Whether a public story is live; `null` when unknown |
| `is_private`, `is_business_account`, `is_professional_account` | Account type flags |
| `external_url`, `business_address` | External link and business address, when the account shows them |
| `pronouns` | Pronouns set on the profile |
| `profile_pic_url` | Profile picture URL |
| `recent_post_shortcodes`, `recent_post_count` | Newest posts shown on the profile |
| `biography` | Full biography text when available; string or `null` |
| `bio_links` | Link-in-bio URLs as objects with `title` (string or null) and `url` (string) |
| `bio_emails` | Array of email addresses extracted from the biography |
| `related_profiles` | Array of usernames Instagram lists as related accounts |
| `bio_snippet` | Biography snippet when the public profile response includes one |
| `category` | Business or creator category when available |
| `website` | External website URL when available |
| `phone` | Legacy public contact field; currently unavailable |
| `profile_url`, `handle`, `name`, `bio`, `emails` | The same profile in the cross-platform social field names, for joining with other social scrapers |
| `platform`, `source`, `fetched_at` | Where and when the row was collected |

Profile details depend on the public response Instagram returns for that account. `biography` can be `null`; `bio_links`, `bio_emails` and `related_profiles` can be empty or absent when unavailable. The historical fields `bio_snippet`, `category`, `website` and `phone` remain supported, but do not assume every optional detail will be filled.

Selected fields from a real profile row of a run on `@natgeo` (the full row also carries `profile_pic_url` and 39 `related_profiles`):

```json
{
  "record_type": "profile",
  "username": "natgeo",
  "url": "https://www.instagram.com/natgeo/",
  "full_name": "National Geographic",
  "user_id": 787132,
  "followers": 268456498,
  "following": 108,
  "posts_count": 32036,
  "reels_count": 90,
  "biography": "Step into wonder and find your inner explorer with National Geographic 🌎",
  "bio_links": [
    {
      "title": null,
      "url": "http://visitstore.bio/natgeo"
    },
    {
      "title": "Subscribe Here!",
      "url": "https://ngmdomsubs.nationalgeographic.com/servlet/OrdersGateway?cds_mag_code=NGM&cds_page_id=283562&cds_response_key=I5FX10002"
    }
  ],
  "bio_emails": [],
  "is_verified": true,
  "is_business_account": true,
  "is_private": false,
  "highlight_reel_count": 1,
  "pronouns": [],
  "recent_post_shortcodes": ["Dd_irlvg4ar", "Dd8u0tIFz1F", "Dd97mt9AeqL", "Dd9nPU7Azb6", "Dd9IsqgFYoS", "Dd8_vklopMD"],
  "recent_post_count": 6,
  "platform": "instagram",
  "fetched_at": "2026-10-02T15:31:58.765Z",
  "profile_url": "https://www.instagram.com/natgeo/",
  "handle": "natgeo",
  "name": "National Geographic",
  "bio": "Step into wonder and find your inner explorer with National Geographic 🌎",
  "emails": []
}
```

#### Post and Reel rows

Each post row carries `shortcode`, `url`, `caption`, `likes`, `comments_count`, `views`, `posted_at`, `product_type`, `is_video`, `hashtags`, `mentions`, `tagged_users`, `coauthors`, `is_paid_partnership`, media URLs, music details, `comments`, the owner fields (`owner_username`, `owner_followers`, `owner_is_verified`, ...) and derived figures such as `engagement_rate` and `went_viral`.

By default, the actor returns up to 30 comments on each profile's 12 newest timeline posts; `comments_count` is always filled. Older timeline posts and posts returned only from the Reels tab have an empty `comments` list. Selected fields from a real post row of a run on `@nasa`:

```json
{
  "record_type": "reel",
  "shortcode": "DdHyaYAifb6",
  "url": "https://www.instagram.com/p/DdHyaYAifb6/",
  "owner_username": "nasa",
  "owner_followers": 104305884,
  "engagement_rate": 0.114,
  "likes": 118947,
  "comments_count": 873,
  "views": null,
  "posted_at": "2026-09-10T21:20:24Z",
  "product_type": "carousel_container",
  "is_video": false,
  "mentions": ["nasakennedy", "europeanspaceagency", "astro_luca", "astro_frankrubio", "astrokomrade", "astroandred", "astro_farmerbob"],
  "is_paid_partnership": false,
  "source_profile": "nasa",
  "went_viral": false
}
```

### Use cases

**Influencer vetting at list scale.** Before outreach, pull the whole candidate list in one run and filter on follower count, verification and recent engagement. Turning on a few posts per profile shows whether the audience actually reacts, which a follower count alone never tells you.

**Competitive benchmarking on a schedule.** Track a competitor set weekly and the follower deltas become a growth-rate table. Growth rate is far more informative than absolute size, and it is the number that reveals which competitor's content strategy is actually working.

**Instagram follower count checks in bulk.** Free follower count checkers look up one account at a time in a browser. This actor takes hundreds of handles at once and returns the counts as data you can export to CSV, Excel or JSON, or feed into a spreadsheet or dashboard through the Apify API.

**Building a creator database.** `user_id` is stable even when a handle changes, so it is the right join key for a database that has to survive rebrands. Combined with follower count and post activity it supports a creator index that stays correct over time.

### How this Instagram profile scraper compares

| Option | Follower counts for any public account | Bulk lists | Login needed | Price |
|---|---|---|---|---|
| Instagram Graph API | No, only accounts you manage | Yes | Yes, app review | Free |
| Free follower count checker websites | Yes | No, one at a time | No | Free, manual |
| `apify/instagram-profile-scraper` | Yes, with a broader profile field set | Yes | No | $0.0026 per profile on the free plan |
| This actor | Yes | Yes | No | $0.0012 per profile |

The platform-official actor is the bigger tool, with the trust and default ranking that implies. The honest comparison is price and simplicity: three inputs here against a broader configuration surface there. If you need follower counts, verification and posts for a list of handles at under half the rate, this one is narrower on purpose. Competitor price as listed in the Apify Store on 2 October 2026.

### Pricing

$0.0012 per profile returned, which is $1.20 per 1,000 profiles. Posts and Reels are opt-in and bill separately at $0.0010 each, so leaving both at 0 means exactly one charge per profile. All pricing is pay-per-event: you only pay for results you receive. A handle that does not exist returns no row and costs nothing. No actor-start fee, no per-compute-unit charges.

### Limits and gotchas

- Public accounts only. Private accounts return counts without content.
- Follower count, not the follower list. The list needs authentication and is out of scope.
- Biography, links, category and website depend on the available public profile data. `bio_emails` contains addresses written in the biography when available; `phone` is currently unavailable.
- Posts go back through the full history, up to 1000 per profile; deep runs take a few minutes.
- Free Apify plans are capped at 10 rows per run. Paid plans have no cap.
- Handles that have been renamed or deleted return no row; the run still succeeds and nothing is charged for them.

### FAQ

**Can I get Instagram follower counts without the API?**

Yes. The Graph API only returns follower counts for accounts you own or manage. The public profile page publishes the figure for any public account, and this actor reads it there.

**Is this an Instagram follower count checker for many accounts at once?**

Yes. Put every handle in `search` and each one comes back as its own row with `followers` and `posts_count`. Schedule the run daily or weekly to track growth.

**Does this work on private accounts?**

No. Private accounts publish only their name, picture and counts. There is no logged-out route to their content, and this actor does not attempt one.

**Can I get the list of followers?**

No. This returns the follower count, not the follower list. Exporting a follower list requires an authenticated session, which this actor deliberately does not use.

**Do I need cookies or a session?**

No. Everything comes from the logged-out public profile, which is why there is no account to get rate limited or banned.

**Can I pass profile URLs instead of usernames?**

Yes, and you can mix them. Bare usernames, @handles and full profile URLs all work in the same run.

**How much does a run of 1,000 profiles cost?**

$1.20 with posts and Reels left at 0. Each post or Reel you ask for adds $0.0010.

### Related Actors

- [Instagram Post Scraper](https://apify.com/s-r/instagram-post-scraper)
- [Instagram Keyword Scraper](https://apify.com/s-r/instagram-keyword-scraper)
- [Instagram Location Scraper](https://apify.com/s-r/instagram-location-scraper)

# Actor input Schema

## `search` (type: `array`):

Instagram usernames or profile URLs, one per line.

## `maxPostsPerProfile` (type: `integer`):

Posts to also return per profile, newest first, back through the account's full history (up to 1000). Left at 0 you get one row and one charge per profile. Each post returned is billed as its own, cheaper post event.

## `maxReelsPerProfile` (type: `integer`):

Reels to return from each profile's Reels tab, with play counts and audio. Includes reels the creator made together with other accounts. 0 skips the Reels tab. Reels that also appear among the posts are returned once.

## Actor input object example

```json
{
  "search": [
    "natgeo",
    "https://www.instagram.com/nasa/"
  ],
  "maxPostsPerProfile": 0,
  "maxReelsPerProfile": 0
}
```

# Actor output Schema

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

Scrape public Instagram profiles by username or profile URL. Returns follower count, following, post count, bio, category, verified status, website and recent posts. No login, cookies or API key required.

## `output` (type: `string`):

OUTPUT record with the run's counts and status flags.

## `errors` (type: `string`):

Failures with a code and a redacted message. Absent when the run had none.

# 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 = {
    "search": [
        "natgeo"
    ],
    "maxReelsPerProfile": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/instagram-profile-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 = {
    "search": ["natgeo"],
    "maxReelsPerProfile": 0,
}

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

```

## MCP server setup

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