# Instagram Profile Scraper (`automation-lab/instagram-public-profile-details`) Actor

Fetch supplied public Instagram profiles with identity, biography, audience and post counts, verification, category, links, profile image, canonical URL, and observation time.

- **URL**: https://apify.com/automation-lab/instagram-public-profile-details.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 3 total users, 2 monthly users, 81.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 item extracteds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Instagram Profile Scraper

Turn supplied public Instagram usernames or profile URLs into clean, typed profile records. This **Instagram profile scraper** returns identity, biography, follower and following counts, post count, verification, account category, public external links, profile image URL, canonical URL, and an observation timestamp.

Use it to refresh creator research lists, enrich public business leads, qualify profiles, or feed recurring account-monitoring pipelines. No Instagram login is required. The Actor does not retrieve private posts, Stories, followers, or contact details that the profile owner has not made public.

### What does Instagram Profile Scraper do?

For every unique username, the Actor requests Instagram's public structured profile surface, normalizes the result, and writes one record to the default Apify dataset.

It supports:

- usernames such as `nasa` or `@nasa`;
- canonical profile URLs such as `https://www.instagram.com/nasa/`;
- mixed username and URL batches;
- up to 1,000 supplied entries per run;
- duplicate removal by case-insensitive username;
- bounded retries with fresh datacenter proxy sessions;
- partial-batch preservation when one profile is unavailable.

### Who is this Actor for?

- **Creator researchers** refreshing audience size, biography, verification, and category.
- **Lead-enrichment teams** adding public Instagram context to existing prospect lists.
- **Influencer marketers** qualifying a supplied shortlist before deeper campaign analysis.
- **Data analysts** collecting timestamped profile snapshots for their own comparison models.
- **Automation builders** sending typed records into a CRM, spreadsheet, warehouse, or webhook.

This is a supplied-profile enrichment Actor, not a search engine. It does not discover accounts from keywords or scrape follower lists.

### Why use this public profile extractor?

The output is intentionally focused on the profile record rather than posts or private account activity. You receive consistent field names across username and URL inputs, one observation timestamp per record, all biography links exposed by Instagram, and a canonical URL suitable for joins.

Failed profiles are never charged as profile items. When at least one profile succeeds, useful results remain available even if another supplied username is missing or Instagram rejects that profile. If every profile fails, the run fails instead of returning a misleading successful empty dataset.

### What Instagram profile data is extracted?

| Field | Meaning |
| --- | --- |
| `instagramUserId` | Instagram's stable profile identifier |
| `username` | Current username |
| `displayName` | Public display name |
| `biography` | Public biography text |
| `followersCount` | Visible follower count at observation time |
| `followingCount` | Visible following count at observation time |
| `postsCount` | Visible post count at observation time |
| `isVerified` | Instagram verification flag |
| `isPrivate` | Whether the account is private |
| `isBusinessAccount` | Business-account flag |
| `isProfessionalAccount` | Professional-account flag |
| `category` | Public profile category, when exposed |
| `businessCategory` | Public business category, when exposed |
| `externalUrl` | Primary external URL, when exposed |
| `externalLinks` | All biography links exposed by Instagram |
| `profileImageUrl` | Current profile image URL |
| `canonicalUrl` | Canonical Instagram profile URL |
| `observedAt` | ISO 8601 observation timestamp |

Instagram may omit category, biography, links, or business flags. Those values are returned as `null`, `false`, or an empty array rather than guessed.

### How to scrape Instagram public profiles

1. Open the Actor input page.
2. Add one or more usernames or public profile URLs to **Instagram usernames or profile URLs**.
3. Optionally lower **Maximum profiles** to process only the first part of the list.
4. Keep three attempts per profile for normal recurring runs.
5. Click **Start**.
6. Open the **Profile details** dataset view or export it as JSON, CSV, Excel, XML, or RSS.

A working input:

```json
{
  "profileInputs": [
    "nasa",
    "@natgeotravel",
    "https://www.instagram.com/instagram/"
  ],
  "maxProfiles": 3,
  "maxRetries": 3
}
```

### Input parameters

#### `profileInputs`

Required array of 1–1,000 public Instagram usernames or profile URLs. Post, Reel, Story, Explore, login, and other non-profile URLs are rejected. Duplicate usernames are fetched once.

#### `maxProfiles`

Optional integer from 1 to 1,000. The Actor processes this many unique profiles from the supplied order. The default is 1,000.

#### `maxRetries`

Optional integer from 1 to 4. It controls bounded attempts for transient source or network failures. The default is 3. Retries use a fresh SHADER datacenter proxy session; users cannot trigger an unmeasured residential or browser fallback.

### Output example

A current public profile produces a record shaped like this:

```json
{
  "instagramUserId": "528817151",
  "username": "nasa",
  "displayName": "NASA",
  "biography": "Exploring the universe and our home planet.",
  "followersCount": 104427475,
  "followingCount": 92,
  "postsCount": 4891,
  "isVerified": true,
  "isPrivate": false,
  "isBusinessAccount": false,
  "isProfessionalAccount": false,
  "category": null,
  "businessCategory": null,
  "externalUrl": "https://www.nasa.gov/",
  "externalLinks": [
    {
      "title": null,
      "url": "https://www.nasa.gov/",
      "linkType": null
    }
  ],
  "profileImageUrl": "https://scontent.cdninstagram.com/profile-image.jpg",
  "canonicalUrl": "https://www.instagram.com/nasa/",
  "observedAt": "2026-08-26T06:07:21.709Z"
}
```

Counts and profile metadata change over time. The example describes the schema; treat each run's dataset as the current observation.

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

The Actor uses pay-per-event pricing:

- a **$0.00005 one-time start event** per run;
- one **public profile event** for each useful record written to the dataset;
- no profile event for invalid, missing, rejected, or failed profiles.

The exact per-profile price depends on your Apify subscription tier. At the Bronze tier, the reviewed market target is **$0.00184 per profile**. Bronze-tier billing examples are straightforward:

| Useful profiles | Charged events |
| ---: | --- |
| 1 | 1 start + 1 public profile |
| 10 | 1 start + 10 public profiles |
| 100 | 1 start + 100 public profiles |
| 1,000 | 1 start + 1,000 public profiles |

For each example, multiply useful profiles by the active per-profile price and add the one-time start event. Apify displays the active tier price before a run.

### Schedule recurring creator research

Use an Apify schedule to run the same input daily, weekly, or monthly. Keep each dataset's `observedAt` value and compare it with your previous snapshot to identify changes in biography, category, links, verification, or public counts.

The Actor returns observations; it does not maintain history, calculate deltas, send alerts, or guarantee that a source field changed at a particular instant. Store snapshots in your own dataset, warehouse, or spreadsheet when historical comparison is required.

### Export profile data to a spreadsheet or pipeline

Every successful record is written to the run's default dataset. From Apify Console you can export JSON, CSV, Excel, XML, or RSS. You can also:

- connect the dataset to Google Sheets through Make;
- trigger a webhook after the run finishes;
- import records into Airtable or a CRM;
- fetch dataset items from a data warehouse job;
- use `canonicalUrl` or `instagramUserId` as a join key.

### Run through the Apify API

Replace `YOUR_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~instagram-public-profile-details/runs?token=YOUR_TOKEN&waitForFinish=300" \
  -H "Content-Type: application/json" \
  -d '{"profileInputs":["nasa","instagram"],"maxProfiles":2,"maxRetries":3}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/instagram-public-profile-details').call({
    profileInputs: ['nasa', 'https://www.instagram.com/instagram/'],
    maxProfiles: 2,
    maxRetries: 3,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/instagram-public-profile-details').call(run_input={
    'profileInputs': ['nasa', 'instagram'],
    'maxProfiles': 2,
    'maxRetries': 3,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use Instagram Profile Scraper with MCP

Add the Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/instagram-public-profile-details"
```

#### Claude Desktop

Add this server in Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/instagram-public-profile-details"
    }
  }
}
```

#### Cursor

Use the same `mcpServers.apify.url` value in Cursor's MCP settings.

#### VS Code

Add the same HTTP MCP server URL through VS Code's MCP server configuration.

Example prompts:

- “Fetch the current public Instagram profile details for nasa and instagram.”
- “Enrich these supplied Instagram profile URLs, then summarize follower count and category.”
- “Run my saved creator list and export username, biography, links, and observation time.”

### Limits and failure behavior

- Only public profile metadata exposed by Instagram is returned.
- Private-account post content is not accessed.
- Usernames are limited to Instagram's 30-character format.
- A profile-specific upstream error can occur even when other profiles work.
- Removed, renamed, restricted, or malformed profiles are omitted and not charged as items.
- A partial batch succeeds with warnings and preserves useful records.
- A batch with zero useful profiles fails with a diagnostic message.
- Instagram can change its public response fields or rate limits without notice.
- Profile image URLs may be temporary CDN URLs; download authorized images promptly if your workflow needs a durable copy.

### Tips for reliable recurring runs

- Prefer current canonical profile URLs or exact usernames.
- Keep retries at 3 unless you are intentionally minimizing latency.
- Use `maxProfiles` to test a small prefix before running a large new list.
- Deduplicate your source list upstream when you also need to preserve source-row provenance.
- Join recurring snapshots on `instagramUserId` when available, because usernames can change.
- Read run warnings before assuming a partial dataset represents every requested profile.

### Responsible and legal use

Use this Actor only for lawful purposes and public data you are permitted to process. Follow Instagram's terms, applicable privacy and data-protection laws, intellectual-property rules, and your organization's retention policy.

Do not use profile data for harassment, discrimination, deceptive outreach, unauthorized surveillance, or attempts to access private content. Minimize collected fields, retain data only as long as needed, and honor deletion or objection requests where applicable. You are responsible for your input list and downstream use.

### FAQ

#### Does it require an Instagram login?

No. The selected route retrieves anonymous public profile metadata. The Actor does not accept or store Instagram credentials.

#### Can it scrape private profiles?

It can identify that an account is private when Instagram exposes the public profile shell, but it does not retrieve private posts, followers, Stories, or other restricted content.

#### Can I enter both usernames and URLs?

Yes. Mix usernames, `@usernames`, and canonical profile URLs in the same `profileInputs` list. Duplicate usernames are processed once.

#### Why is one requested profile missing?

The username may be removed, renamed, restricted, malformed, or affected by a profile-specific Instagram response error. Check warnings in the run log. Failed profiles do not emit profile item charges.

#### Why did the whole run fail?

The Actor fails when input validation fails or when every requested profile returns no usable public record. This prevents a misleading successful empty run.

#### Does it track follower changes automatically?

It returns the current count and `observedAt`. Schedule recurring runs and compare snapshots in your own workflow; this Actor does not calculate or alert on changes.

### Related automation-lab Actors

- [Instagram Profile Stats Scraper](https://apify.com/automation-lab/instagram-profile-stats-scraper) adds engagement-summary calculations for supplied profiles.
- [Instagram Public Contact Scraper](https://apify.com/automation-lab/instagram-contact-scraper) focuses on owner-published contact fields.
- [Instagram Profile Posts Scraper](https://apify.com/automation-lab/instagram-profile-posts-scraper) collects public post records from supplied profiles.
- [Instagram Post & Reel Details Scraper](https://apify.com/automation-lab/instagram-post-reel-details-scraper) enriches supplied post and Reel URLs.

Choose this Actor when the unit you need is one lightweight, current public profile record.

# Actor input Schema

## `profileInputs` (type: `array`):

Public usernames (with or without @) or canonical Instagram profile URLs. Duplicate usernames are fetched once. Posts, Reels, Stories, and other non-profile URLs are rejected.

## `maxProfiles` (type: `integer`):

Maximum number of unique profiles to process from the supplied list.

## `maxRetries` (type: `integer`):

Maximum bounded attempts for transient Instagram or network failures. A fresh datacenter proxy session is used on retry.

## Actor input object example

```json
{
  "profileInputs": [
    "nasa",
    "natgeotravel",
    "https://www.instagram.com/instagram/"
  ],
  "maxProfiles": 3,
  "maxRetries": 3
}
```

# Actor output Schema

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

Normalized public Instagram profile records.

# 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 = {
    "profileInputs": [
        "nasa",
        "natgeotravel",
        "https://www.instagram.com/instagram/"
    ],
    "maxProfiles": 3,
    "maxRetries": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/instagram-public-profile-details").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 = {
    "profileInputs": [
        "nasa",
        "natgeotravel",
        "https://www.instagram.com/instagram/",
    ],
    "maxProfiles": 3,
    "maxRetries": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/instagram-public-profile-details").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 '{
  "profileInputs": [
    "nasa",
    "natgeotravel",
    "https://www.instagram.com/instagram/"
  ],
  "maxProfiles": 3,
  "maxRetries": 3
}' |
apify call automation-lab/instagram-public-profile-details --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/instagram-public-profile-details"
        }
    }
}

```

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/LVTCJFHWyBfeVAfiw/builds/61UEtHsMcdWZcu0S4/openapi.json
