# Instagram Profile Scraper | $2.0/1K on Starter (`publicsignallabs/instagram-profile-scraper`) Actor

Scrape public Instagram profile data from usernames, profile URLs, or IDs. Extract names, audience and content counts, bios, links, business categories, contact details, verification and privacy status, and profile images. Export results as JSON, CSV, Excel, or through the API.

- **URL**: https://apify.com/publicsignallabs/instagram-profile-scraper.md
- **Developed by:** [Public Signal Labs](https://apify.com/publicsignallabs) (community)
- **Categories:** Social media, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 28 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 profile lookup 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 Profile Scraper

Scrape public Instagram profile data from usernames, `@usernames`, profile URLs, or numeric IDs. Extract names, follower and following counts, post counts, biographies, links, business categories, public contact details, verification and privacy status, and profile images.

Use the data for creator research, public business enrichment, CRM preparation, account verification, and automated Instagram research. Batch up to 50 unique profiles on paying plans, then export the results as JSON, CSV, Excel, XML, or through the API. No Instagram login, cookies, browser, or proxy setup.

### What this Actor does

- Resolves usernames, `@usernames`, profile URLs, and numeric profile IDs
- Verifies that every response matches the requested identity
- Returns normalized public profile and business/contact fields when found
- Preserves input order and returns a `succeeded` or `not_found` row for every completed valid lookup
- Deduplicates equivalent inputs before making requests
- Exports one stable row schema across all supported identifier forms

Use it for creator research, public business enrichment, CRM preparation, account verification, and resolving profiles discovered by other Public Signal Labs Instagram Actors.

### Quick start

```json
{
  "profiles": ["instagram", "@natgeo", "https://www.instagram.com/nasa/"]
}
```

### Input

| Field | Rules |
|---|---|
| `profiles` | Required array of 1–50 Instagram usernames, `@usernames`, canonical profile URLs, or numeric IDs. Equivalent values are deduplicated while first occurrence order is retained. Plan-specific effective limits are detailed in Pricing. |

Unknown properties, unsupported URLs, malformed usernames/IDs, empty values, and invalid types are rejected before credentials, network work, or charging.

### Dataset rows

Each completed valid lookup creates one row with the following fields:

| Field | Description |
|---|---|
| `source_input` | Original submitted username, URL, or numeric ID. |
| `input_index` | Zero-based position of the normalized input. |
| `status` | `succeeded` when profile facts were found; otherwise `not_found`. |
| `id` | Stable Instagram profile ID. |
| `username` | Current Instagram username. |
| `full_name` | Display name. |
| `profile_url` | Canonical Instagram profile URL. |
| `is_private` | Whether the account is private. |
| `is_verified` | Whether Instagram marks the account as verified. |
| `profile_pic_url` | Current standard-resolution profile image URL. |
| `profile_pic_url_hd` | Higher-resolution profile image URL when exposed. |
| `follower_count` | Current follower count. |
| `following_count` | Current followed-account count. |
| `media_count` | Current published-media count. |
| `biography` | Public profile biography. |
| `external_url` | Primary external profile link. |
| `bio_links` | Structured links exposed in the biography. |
| `account_type` | Instagram account-type value. |
| `category` | Public professional or business category. |
| `is_business` | Whether Instagram marks the account as a business. |
| `is_professional_account` | Whether Instagram marks the account as professional. |
| `public_email` | Public business email when exposed. |
| `public_phone_number` | Public business phone number when exposed. |
| `business_contact_method` | Preferred public business contact method. |
| `address_street` | Public business street address. |
| `city_name` | Public business city. |
| `zip_code` | Public business postal code. |
| `latitude`, `longitude` | Public business coordinates when exposed. |

Profile fields are `null` and `bio_links` is empty when `status` is `not_found`. Optional values can also be `null` or empty when Instagram does not expose them. Missing contact values are not lookup failures. Profile images and external URLs can change or expire.

### Pricing

**$2.0 per 1,000 completed valid profile lookups. One lookup result row costs exactly `$0.0020`.**

| Outcome | Dataset row | Exact event charge |
|---|---|---:|
| Profile found | `status: succeeded` with available profile facts | `$0.0020` |
| Valid lookup with no profile information found | `status: not_found` with profile fields empty | `$0.0020` |
| Malformed customer input rejected before lookup | None | `$0.0000` |
| Provider, identity-check, or malformed-response failure | None | `$0.0000` |

A completed valid profile lookup is charged even when no profile information can be found. Syntactically malformed handles, unsupported URLs, and other inputs rejected before upstream work are never charged. The single profile-result event both saves the status-bearing row and charges it. The Actor verifies that the requested maximum workload fits the run spending limit before starting upstream work.

#### FREE demo limits

FREE Apify accounts can run this Actor up to 5 times per UTC calendar month. Each admitted FREE run accepts exactly one unique profile and returns the same row fields and billing semantics as paid runs. Console, CLI, API, schedules, webhooks, MCP, and other launch methods share the same account allowance. A run counts once admitted even when it is later aborted or unsuccessful, and resurrecting it does not start another extraction. Creating another task or API token does not reset the allowance. Paid Apify users are not subject to these demo limits.

### Run summary and audit

The default key-value store contains:

- **`OUTPUT`** — overall status, exact prices, maximum and actual event charge, delivered/charged totals, and sanitized per-input outcomes
- **`AUDIT`** — aggregate request attempts, request units, response bytes, retries, status counts, operation counts, storage reconciliation, and non-sensitive FREE admission metadata

Source summaries contain only input indexes, status, row count, and a stable sanitized error code. They never contain usernames, IDs, profile data, credentials, provider paths, or raw responses.

### Status behavior

Per-input status is one of:

- `succeeded` — one identity-matching profile row was saved with available facts;
- `not_found` — the valid lookup completed and a charged status row was saved with empty profile fields;
- `failed` — the request, response validation, or identity check failed safely; no row is saved or charged.

`OUTPUT` uses `schemaVersion: 2`: `status` is `SUCCEEDED` for completed work and graceful stops, or `FAILED` for internal faults (`RUNNING` denotes a checkpoint). Check `outcome` (`COMPLETED`, `NO_RESULTS`, `PARTIAL`, `INPUT_REJECTED`, `POLICY_REJECTED`, `UPSTREAM_UNAVAILABLE`, `DEPENDENCY_UNAVAILABLE`, `LIMIT_REACHED`, `INTERNAL_ERROR`) and `message`/`issues`; platform success does not guarantee data. Runtime input/policy rejections and external outages finish normally; confirmed rows remain available. Ambiguous writes or charges use `reconciliation: "unknown"`. External reporting outages can leave summaries unavailable; platform-enforced aborts and resource failures remain outside this guarantee.

### Limitations and data quality

This Actor returns current public profile facts. It does not retrieve private content, posts, Reels, Stories, followers/following lists, historical profile changes, engagement rates, email verification, or linked-website data. Public contact fields are sparse, can be outdated, are not independently verified, and are never guaranteed.

### API and CLI use

```bash
apify actors call publicsignallabs/instagram-profile-scraper \
  --input '{"profiles":["instagram"]}' \
  --output-dataset
```

The Actor also works with Apify clients, the Runs API, schedules, webhooks, and platform integrations.

### Responsible use

Collect and use public data only where you have a lawful purpose. Respect privacy, intellectual-property rights, platform rules, anti-spam requirements, and applicable data-protection law. Minimize retained data, secure exports, and honor deletion obligations.

This Actor is unofficial and is not affiliated with or endorsed by Instagram or Meta.

### Support

Use the **Issues** tab on this Actor's Apify page. Include the run ID and a sanitized input shape. Never include API tokens, cookies, credentials, personal contact values, or other private data.

# Actor input Schema

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

Instagram usernames, @usernames, canonical profile URLs, or numeric profile IDs. Paying runs accept up to 50 unique values; plan-specific limits are detailed in Store Pricing.

## Actor input object example

```json
{
  "profiles": [
    "instagram"
  ]
}
```

# Actor output Schema

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

One status-bearing row per completed valid Instagram profile lookup.

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

Run status, delivered totals, pricing, and sanitized per-input outcomes.

## `audit` (type: `string`):

Aggregate request, usage, storage, charge, and FREE admission metrics without input values or credentials.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("publicsignallabs/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("publicsignallabs/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 '{}' |
apify call publicsignallabs/instagram-profile-scraper --silent --output-dataset

```

## MCP server setup

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