# Instagram Profile API (`truefetch/instagram-profile-api`) Actor

- **URL**: https://apify.com/truefetch/instagram-profile-api.md
- **Developed by:** [TrueFetch](https://apify.com/truefetch) (community)
- **Categories:** Social media, Automation, Integrations
- **Stats:** 128 total users, 38 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $4.50 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 is a bulk Instagram profile scraper API that turns up to 1,000 usernames, handles, or profile URLs into one fixed 35-field JSON record per public account, so data teams can store profiles without writing per-account parsing branches.**

- **One required input and no credentials.** Send an array of 1–1,000 strings; the Actor never asks for an Instagram login.
- **A fixed 35-key contract.** Resolved profiles and explicit not-found rows carry identical keys, so a table schema stays stable across runs.
- **Recent post engagement is included.** Each row carries the profile's recent public post links with type, publish time, likes, comments, and views.
- **Per-row billing.** One Result event is charged per returned Dataset row, and a target that returns nothing is not billed as a result.

[**Run a one-result test**](https://apify.com/truefetch/instagram-profile) · [**View API**](https://apify.com/truefetch/instagram-profile/api)

The smallest useful run is one username such as `instagram`: one Actor Start plus one Result event, or $0.01500 on the FREE tier.

### What does Instagram Profile do?

Instagram Profile takes a list of public profile targets and returns one normalized record for each target it resolves. It accepts three input shapes for the same account — a bare username, an `@handle`, and a full `instagram.com` profile URL — and reduces all of them to one canonical username before the lookup. Each record folds identity text, audience and content counts, account flags, category labels, bio details, optional business fields, a recent-post sample, and related-profile suggestions into one flat object, alongside `status`, `requested_input`, `processor`, and `processed_at`.

The anti-definition matters as much as the definition. Instagram Profile is not a post, reel, story, comment, follower-list, hashtag, location, or ad-library scraper. It does not log in, accept credentials, or reach private content. It returns no `email` or `phone` fields, no full post history, and no engagement-rate, growth, or authenticity scores. It reads public profile surfaces and reports what they expose; it is not affiliated with or endorsed by Instagram or Meta.

### How do I run Instagram Profile?

1. Put one known public username into **Instagram Profiles** — `instagram` is a good first target.
2. Start the run and read the Dataset before scaling.
3. Compare the Dataset item count with the number of submitted targets.
4. Add the rest of your list once the single-target shape looks correct.

Smallest useful run:

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

The prefilled Console example sends two targets so you see both input shapes:

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

Result limits apply per input item, not per run: each resolved target produces at most one Dataset row, and there is no separate result cap to configure. The 1,000-entry ceiling limits submitted array entries; it is not a promise that a maximum-size run resolves all 1,000 accounts.

### What data does Instagram Profile return?

Every row has the same 35 top-level keys.

| Group | Fields |
|---|---|
| Identity | `username`, `full_name`, `user_id`, `facebook_id`, `avatar_url`, `profile_url` |
| Audience and content | `followers`, `following`, `posts`, `reels`, `highlights` |
| Account flags | `is_verified`, `is_private`, `is_professional`, `is_business`, `has_clips`, `has_threads`, `hide_counts` |
| Classification | `category`, `category_type`, `business_category` |
| Bio details | `bio`, `bio_mentions`, `bio_hashtags`, `pronouns`, `website`, `bio_links` |
| Business contact | `contact_method`, `address` |
| Discovery | `related_profiles`, `recent_posts` |
| Run state | `status`, `requested_input`, `processor`, `processed_at` |

`status` is `success` or `not found`. `recent_posts` entries contain `url`, `type` (`image`, `video`, `carousel`, or `reel`), `posted_at`, `likes`, `comments`, and `views`. It is a profile-page sample, not the full post history, and it is empty for private accounts and accounts with no visible posts even when `posts` is above zero. When `hide_counts` is true, the account hides counts on its public pages while `recent_posts` values still come from the source response.

Abbreviated illustrative item for `instagram`; counts and links change between runs:

```json
{
  "status": "success",
  "requested_input": "instagram",
  "user_id": "25025320",
  "username": "instagram",
  "full_name": "Instagram",
  "bio": "Discover what's new on Instagram",
  "bio_mentions": [],
  "bio_hashtags": [],
  "pronouns": [],
  "website": "https://help.instagram.com/",
  "bio_links": ["https://help.instagram.com/"],
  "contact_method": "UNKNOWN",
  "address": null,
  "category": null,
  "category_type": "MEDIA_NEWS_COMPANY",
  "business_category": null,
  "is_private": false,
  "is_verified": true,
  "is_professional": true,
  "is_business": false,
  "has_clips": true,
  "has_threads": true,
  "hide_counts": false,
  "followers": 700857201,
  "following": 242,
  "posts": 8407,
  "reels": 273,
  "highlights": 15,
  "related_profiles": ["threads", "creators"],
  "avatar_url": "https://scontent.example/profile-hd.jpg",
  "profile_url": "https://www.instagram.com/instagram/",
  "recent_posts": [
    {
      "url": "https://www.instagram.com/reel/DbWPkbGSC3M/",
      "type": "reel",
      "posted_at": "2026-07-28T19:02:42+00:00",
      "likes": 258922,
      "comments": 8040,
      "views": 10842673
    }
  ]
}
```

Unavailable source values stay empty rather than disappearing. `category`, `business_category`, `contact_method`, `address`, `pronouns`, `bio_mentions`, `bio_hashtags`, and `related_profiles` are frequently null or empty, and an empty value is not evidence that the account lacks that attribute. Keep null and `[]` distinct in storage.

### What inputs can I configure?

| Field | Type | Required | Behavior |
|---|---|---|---|
| `instagram_url` | array of strings | Yes | 1–1,000 usernames, `@handles`, or `instagram.com` profile URLs |

There is one public input and no optional fields. Accepted list items for the same account include `instagram`, `@instagram`, `instagram.com/instagram`, and `https://www.instagram.com/instagram/`.

Normalization strips the `instagram.com/` prefix, any query string, any fragment, a leading `@`, surrounding slashes, and any trailing path segment. Entries that normalize to a non-profile route — `p`, `reel`, `reels`, `stories`, `tv`, `explore`, `graphql`, or `accounts` — are discarded. Duplicates are looked up once and the check ignores letter case, so `NatGeo` and `natgeo` produce one row and one Result event. If nothing valid remains, the run exits with an input error rather than producing an empty Dataset. The Console prefill exists for discovery; API and Scheduler callers always send their own array.

### What platforms and markets does Instagram Profile cover?

Coverage is one platform and one entity type: publicly reachable Instagram profile pages. There is no country, language, or vertical restriction on the usernames you submit, because the Actor resolves accounts rather than browsing a regional index.

What varies by account is field availability, not market eligibility. Personal accounts often expose no category or business fields, while professional and business accounts more often populate `category_type`, `business_category`, `contact_method`, and `address`. Bio text, link labels, and category names come back in the account's own language. Private and restricted accounts stay in scope only as far as their public shell is visible: identity fields and `is_private` still arrive, content-derived fields stay empty.

### Why use Instagram Profile?

| Capability | What it gives your team |
|---|---|
| Fixed 35-key output | A table or model that keeps its shape across account types |
| `status` plus preserved `requested_input` | Deterministic reconciliation of targets against rows |
| Three input shapes, case-insensitive de-duplication | Messy CRM and spreadsheet columns submit without pre-cleaning |
| `recent_posts` with engagement counts | An activity signal in the same row, without a second join |
| Per-row event billing | Cost scales with delivered data, not attempted targets |

The main trade-off is breadth versus depth. Every row is a profile snapshot, so you get wide account coverage cheaply but no post history, comments, followers lists, or time series. If the question is "how did this account perform last quarter", this is the wrong starting point; if it is "give me a current, uniform record for these 800 accounts", it is the right one.

### Who is Instagram Profile for?

The primary audience is developers and data teams putting Instagram profile data into an existing pipeline: enriching a CRM with `website`, `bio_links`, `contact_method`, `business_category`, and the professional and business flags; building an internal creator database keyed on `user_id` with dated snapshots; or giving an agent or MCP tool a bounded lookup it can call without special-case parsing. Research teams use `related_profiles` and `bio_mentions` to seed discovery loops, and `followers` with `recent_posts` engagement as a quick activity check.

The reverse persona is anyone needing private or authorized data. For follower identities, direct messages, owned-account insights, comment threads, story archives, or ad-library records, use official Instagram or Meta access instead. This Actor is also wrong if you need a guaranteed row per submitted username, because public source availability is outside its control.

### How can I use Instagram Profile through the API or MCP?

The Actor ID is `truefetch/instagram-profile`. Keep the Apify token in an environment secret rather than in code.

```bash
curl -X POST "https://api.apify.com/v2/acts/truefetch~instagram-profile/runs?token=$APIFY_TOKEN&waitForFinish=180" \
  -H "Content-Type: application/json" \
  -d '{"instagram_url":["instagram","https://www.instagram.com/natgeo/"]}'
```

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("truefetch/instagram-profile").call(
    run_input={"instagram_url": ["instagram", "https://www.instagram.com/natgeo/"]}
)
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
```

MCP call arguments:

```json
{
  "actor": "truefetch/instagram-profile",
  "input": {
    "instagram_url": ["instagram", "https://www.instagram.com/natgeo/"]
  },
  "callOptions": {"build": "latest", "memory": 256, "timeout": 180}
}
```

Generated SDK snippets and the OpenAPI definition live on the [API page](https://apify.com/truefetch/instagram-profile/api). After an MCP call, read the default Dataset separately when rows are not returned inline.

For batch integrations, persist your job ID, the submitted string, the normalized username, the run ID, and the returned row. That separates three per-target outcomes: a `success` row, a `not found` row, and no row. Retry only missing targets; replaying a whole batch creates duplicate Result events and snapshots.

### How much does Instagram Profile cost?

Instagram Profile uses pay-per-event pricing with two billed events.

| Event | Billing unit | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|---|---|---:|---:|---:|---:|---:|---:|
| Actor Start | Per charged start event, by memory (one per GB, minimum one) | $0.01000 | $0.01000 | $0.01000 | $0.01000 | $0.01000 | $0.01000 |
| Result | Per returned Dataset row | $0.00500 | $0.00450 | $0.00400 | $0.00375 | $0.00375 | $0.00375 |

Smallest useful run on the FREE tier: one username returns one row, so the run is $0.01000 + $0.00500 = **$0.01500**. The Actor runs at 256 MB, charged as one Actor Start event.

Only returned rows create Result events, so a target that yields no row costs nothing beyond the start. Set a maximum total charge in the calling platform for a hard ceiling, and check the [Store page](https://apify.com/truefetch/instagram-profile) for current prices before budgeting a large batch — prices can change.

### How does Instagram Profile compare with alternatives?

Compared with a narrow post or reel Actor, Instagram Profile trades content depth for account breadth. A post-level Actor answers what an account published; this one answers who the account is and how large and active it looks now. Many teams run both and join on `user_id`.

Compared with official Instagram or Meta access, the trade-off is authorization and scope. Official access reaches data this Actor never touches, including owned-account insights and private content, but requires app review, permissions, and integration work; Instagram Profile needs an API token and a list of usernames. Compared with your own automation, you keep more control but take on normalization, retries, schema ownership, and maintenance whenever the source changes.

Do not choose Instagram Profile when you need guaranteed completeness, contact-verified leads, historical time series, or authorized private data. Choose it when a wide, current, uniformly shaped public profile snapshot is the actual requirement.

### What are the limits and troubleshooting steps?

**Fewer rows than submitted targets.** Some targets normalized away, some returned a not-found row, and some failed before a usable response arrived. Compare normalized targets against returned `requested_input` values, then retry only the gaps in a small batch after a short delay. Keep the first Dataset so a retry does not overwrite a good snapshot.

**The run exits with an input error.** The input must be an array of 1–1,000 text entries, and at least one must normalize to a valid username. A list of only post or reel URLs normalizes to nothing.

**No profiles could be returned.** Every target failed. Re-run a single known-public username such as `instagram` to separate a source-side problem from an input problem before touching the batch.

**`recent_posts` is empty although `posts` is non-zero.** The account is private, or the source did not expose the recent-post sample in that response.

**Counts disagree with another tool.** Values are snapshots taken at `processed_at`. Compare timestamps and confirm the same `user_id` before treating a difference as an error, and store dated runs.

**A username stopped resolving.** Accounts get renamed, deactivated, or restricted. `user_id` is the stable key, so keep it and a renamed account can still be matched.

The smallest reproducible bug report input is `{"instagram_url": ["instagram"]}`. Report issues from the Actor page with the run ID, Dataset ID, non-secret input, expected target, and the exact field involved.

### Frequently asked questions

**Do I get one row for every submitted username?**
Not guaranteed. Not-found responses produce a row, but a target whose requests all fail produces none. Reconcile with `requested_input` and the Dataset count.

**Does the output include email or phone numbers?**
No. There are no `email` or `phone` fields. You get `contact_method` and a structured `address` when the source exposes them, and both are frequently null.

**Are duplicate usernames billed twice?**
No. Duplicates are de-duplicated case-insensitively before the lookup, so they produce one row and one Result event.

**Can I submit post, reel, or story URLs?**
No. Those routes are discarded during normalization. Use [Instagram Post Scraper](https://apify.com/truefetch/instagram-post-scraper) for post-level records.

**What exactly does `is_verified` mean?**
It is the raw boolean the source returns. It is not independent verification of identity, ownership, safety, or business legitimacy, and it should not be used as a trust signal on its own.

**What is the difference between `posts` and `recent_posts`?**
`posts` is the total timeline count for the account. `recent_posts` is the small recent public sample shown on the profile page, so its length is far smaller.

**Do private accounts work?**
Partly. You receive the public shell and the `is_private` flag, while content-derived fields stay empty. The Actor does not bypass access controls.

**Can I schedule this Actor?**
Yes. Because prefills apply only to the Console, a scheduled task must carry its own `instagram_url` array.

**What legal and privacy controls should I apply?**
Review the [Instagram Terms of Use](https://www.instagram.com/legal/terms/), the [Meta Privacy Policy](https://privacycenter.instagram.com/policy/), and applicable privacy and anti-spam law. Apply data minimization, purpose limitation, access controls, and retention limits, and do not infer protected traits from bios, pronouns, names, images, or related accounts.

### Related TrueFetch Actors

- [Instagram Post Scraper](https://apify.com/truefetch/instagram-post-scraper) — use when you already have the account and now need its posts, reels, and carousel records.
- [Instagram Explore Post](https://apify.com/truefetch/instagram-explore-post) — use when you have no usernames yet and need country-scoped Explore discovery to generate candidates.
- [X User Profile](https://apify.com/truefetch/x-user-profile) — use when the same brand or person needs a matching public profile record on X.

### Support

Open issues from the [Actor page](https://apify.com/truefetch/instagram-profile), browse endpoints on the [API page](https://apify.com/truefetch/instagram-profile/api), join the [TrueFetch community](https://t.me/TrueFetch), or contact [direct support](https://t.me/AiAgentApi). Include the run ID, Dataset ID, UTC time, non-secret input, expected targets, returned `requested_input` values, and the exact missing or unexpected field. Never post API tokens or private personal data.

[**Run a one-result test**](https://apify.com/truefetch/instagram-profile) · [**View API**](https://apify.com/truefetch/instagram-profile/api)

# Actor input Schema

## `instagram_url` (type: `array`):

Enter 1–1,000 usernames, @handles, or instagram.com profile URLs. Post, reel, story, and explore routes are discarded, and a valid input does not guarantee that Instagram returns profile data.

## Actor input object example

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

# Actor output Schema

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

Table view of returned profiles led by the avatar image, username, profile link, audience and content counts, account flags, categories, bio details, recent posts, and run-state fields; source-dependent values can be empty or null.

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

// Run the Actor and wait for it to finish
const run = await client.actor("truefetch/instagram-profile-api").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 = { "instagram_url": [
        "instagram",
        "https://www.instagram.com/natgeo/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("truefetch/instagram-profile-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "instagram_url": [
    "instagram",
    "https://www.instagram.com/natgeo/"
  ]
}' |
apify call truefetch/instagram-profile-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=truefetch/instagram-profile-api",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/nU312PzlPsPH0na31/builds/c73YQecfrGS4idH5h/openapi.json
