# Instagram Profile Scraper (`harpoon/ig-profile-scraper`) Actor

Scrape public Instagram profiles - bio, full name, follower and following counts, profile picture, links, and highlights - without logging in.

- **URL**: https://apify.com/harpoon/ig-profile-scraper.md
- **Developed by:** [Harpoon](https://apify.com/harpoon) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/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 — public profile data, one clean row per account

Turn any list of public Instagram handles into a structured table of profile data: full name,
bio, follower and following counts, verification and privacy status, profile picture, bio links,
and story highlights. Paste profile URLs or `@handles`, press Start, and download the results as
JSON, CSV, Excel, or XML. Each profile returns exactly one row, so the output drops straight into
a spreadsheet, CRM, or database.

#### What can Instagram Profile Scraper do?

- Fetch public profile data for one profile or thousands in a single run
- Accept profile URLs (`https://www.instagram.com/markruffalo/`), `@handles` (`@markruffalo`), plain handles, or numeric IDs
- Return audience size, bio, external links, verification, privacy, and highlight metadata
- Flag private, unpublished, or memorialized accounts instead of failing the run
- Export to JSON, CSV, Excel, or XML; run via the API, schedule runs, and connect through MCP

### What data can I extract?

<table>
<tr><th>What you get</th><th>Features</th></tr>
<tr><td>

- **Profile identity** — username, full name, profile URL, profile picture, profile IDs
- **Audience** — follower count, following count, post count when available
- **Bio and links** — biography text, bio links (title + URL), pronouns
- **Account status** — verified, private, unpublished, memorialized, has clips
- **Highlights** — highlight count plus each highlight's title and cover image

</td><td>

- One row per profile, keyed by username
- Optional highlight details to keep rows lean
- Deduplicates repeated handles automatically
- Export to JSON, CSV, Excel, XML
- API access, webhooks, scheduling, LLM-ready output for MCP

</td></tr>
</table>

### How to use Instagram Profile Scraper

1. [Create](https://console.apify.com/sign-up) a free Apify account.
2. Open **Instagram Profile Scraper** in Apify Console.
3. Paste one or more public profile URLs or `@handles` into **Instagram profiles**, one per line.
4. Leave **Include highlights** on, or turn it off for a leaner dataset.
5. Click **Save & Start**.
6. Download the results in JSON, CSV, Excel, or XML from the **Storage** tab.

### Input

There is a single way to run it: give it a list of profiles. Every profile in the list produces
one dataset row, and duplicates are removed before the run.

- `profiles` — public profile URLs, `@handles`, plain handles, or numeric IDs.
- `include_highlights` — include each profile's story highlights and their cover images (default on).

**Example input**

```json
{
  "profiles": ["https://www.instagram.com/markruffalo/", "@markruffalo"],
  "include_highlights": true
}
```

See the **Input** tab above for every parameter.

### Output

Results land in a dataset under the **Storage** tab. View as a table (three built-in views:
**Overview**, **About**, and **Growth tracker**), download in JSON, CSV, Excel, or XML, or pull
them via the API.

```json
{
  "id": "17841401914858621",
  "pk": "1191807828",
  "username": "markruffalo",
  "url": "https://www.instagram.com/markruffalo/",
  "full_name": "Mark Ruffalo",
  "biography": "A husband, father, actor, director, and a climate justice and renewable energy advocate with an...",
  "profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/404601009_728153775882418_5195097191064167935_n.jpg",
  "is_verified": true,
  "is_private": false,
  "is_unpublished": false,
  "is_memorialized": false,
  "is_coppa_enforced": false,
  "has_any_clips": true,
  "latest_reel_media": 0,
  "follower_count": 20714550,
  "following_count": 1589,
  "media_count": null,
  "pronouns": ["he", "him"],
  "highlight_reel_count": 4,
  "highlights": [
    { "id": "18053423362909587", "title": "Vote 2024",      "cover_url": "https://scontent.cdninstagram.com/v/t51.82787-15/584804620_18066887114_n.jpg" },
    { "id": "17869069943343819", "title": "AAPI Resources", "cover_url": "https://scontent.cdninstagram.com/v/t51.2885-15/162436437_849875285593_n.jpg" },
    { "id": "17869055039248765", "title": "BHM Takeover",   "cover_url": "https://scontent.cdninstagram.com/v/t51.2885-15/465693856_106851802172_n.jpg" },
    { "id": "18057609532230187", "title": "BLM",            "cover_url": "https://scontent.cdninstagram.com/v/t51.2885-15/102419640_143916770545_n.jpg" }
  ],
  "bio_links": [
    { "title": "", "url": "https://linktr.ee/markruffalo", "link_type": "external", "is_pinned": false }
  ],
  "scraped_at": "2026-09-17T13:33:43Z"
}
```

Field names are lowercase snake\_case, and the input keys match them. Image URLs above are
abbreviated for readability — the dataset contains the full links.

### What can you do with the data?

#### 1. Shortlist influencers

1. Run the Actor over a list of candidate handles.
2. Open the **Overview** view and sort by `follower_count`.
3. Filter `is_verified = true` and `is_private = false` to keep public, verified accounts.

#### 2. Track competitors over time

1. Schedule the Actor to run weekly over the same handles.
2. Use the **Growth tracker** view to compare `follower_count`, `following_count`, and `media_count`.
3. Export to Sheets or your BI tool to chart growth.

#### 3. Enrich leads with websites and contacts

1. Run the Actor over target accounts.
2. Read `bio_links` and `biography` to find company websites, contact pages, and self-reported details.
3. Join the results to your CRM by `username`.

### How much does Instagram Profile Scraper cost?

This Actor is billed **per profile returned** (pay-per-event) on top of standard Apify platform
usage. A run over 250 handles is billed as 250 results, no matter how the run is configured.
There is no per-profile data cap.

See the **Pricing** tab for current rates and your plan's discounts.

### FAQ

**Do I need an Instagram account, cookies, or an API key?**
No. The Actor reads publicly available profile data, so no login or credentials are required.

**Can it scrape private or restricted profiles?**
Private profiles are still returned, but with the limited public information that is visible
(`is_private` is `true`, and fields such as `biography` may be empty). Nothing behind a login is
accessed.

**How many profiles can I scrape?**
As many as you list — one row each. Large lists simply take longer and are billed per profile.

**Is it legal to scrape Instagram?**
The Actor returns public data only. Review Apify's guidance on legal and ethical scraping and the
terms that apply to your use case.

**Can I use it with the API, SDKs, or MCP?**
Yes — see the **API** tab above, or connect through the Apify MCP server.

**A profile is missing from the results.**
That handle is logged in the run log with the reason (for example, it does not exist or was
temporarily throttled). The rest of the run continues; re-run just that handle if needed.

### Notes and limitations

- `media_count` is frequently `null`: Instagram does not expose the post count to visitors who
  are not logged in. The field is populated when it is available.
- `profile_pic_url` and highlight `cover_url` values are time-limited image links. Download the
  files soon after the run if you need to keep them.
- `latest_reel_media` is an internal media ID, not a date (`0` means the profile has no such media).
- Very long lists over busy accounts can hit temporary rate limiting; affected profiles are
  skipped and logged rather than aborting the run.
- Attempting to use a post, reel, or story URL as a profile raises a clear error for that entry.

### Run locally

```
go run ./cmd/actor
```

Input is read from the Apify key-value store; see `INPUT_SCHEMA.json`.

### Support

Found a bug or have feedback? Open an issue in the **Issues** tab.

# Actor input Schema

## `profiles` (type: `array`):

<b>Public profile URLs, @handles, or numeric IDs</b>, one per line. Accepts <code>https://www.instagram.com/markruffalo/</code>, <code>@markruffalo</code>, or <code>markruffalo</code>. Duplicates are removed automatically, and every profile returns exactly one row.

## `include_highlights` (type: `boolean`):

Add the profile's story highlights (title, cover image, and total count) to each row. Turn it off for a leaner dataset.

## Actor input object example

```json
{
  "profiles": [
    "@markruffalo",
    "https://www.instagram.com/markruffalo/"
  ],
  "include_highlights": true
}
```

# Actor output Schema

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

One row per scraped profile. Export as JSON, CSV, Excel, or XML.

# 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 = {
    "profiles": [
        "https://www.instagram.com/markruffalo/"
    ],
    "include_highlights": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("harpoon/ig-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 = {
    "profiles": ["https://www.instagram.com/markruffalo/"],
    "include_highlights": True,
}

# Run the Actor and wait for it to finish
run = client.actor("harpoon/ig-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 '{
  "profiles": [
    "https://www.instagram.com/markruffalo/"
  ],
  "include_highlights": true
}' |
apify call harpoon/ig-profile-scraper --silent --output-dataset

```

## MCP server setup

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