# Instagram Related Profiles Scraper — Instagram Competitors (`steadyfetch/instagram-similar-profiles-scraper`) Actor

Instagram competitors and lookalikes: the accounts Instagram itself suggests as similar to any handle — username, full name, profile link, verified and private flags, and Instagram's own ranking. No login, no start fee. From $0.50 per 1,000 profiles. An undelivered profile is never charged.

- **URL**: https://apify.com/steadyfetch/instagram-similar-profiles-scraper.md
- **Developed by:** [Steadyfetch Team](https://apify.com/steadyfetch) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 similar 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?

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 Related Profiles Scraper — Instagram Competitors

Give it an Instagram account and get back the accounts Instagram itself suggests as similar to it: username, full name, profile link, whether they are verified or private, Instagram's own one-line reason for the suggestion, and its place in Instagram's ranking. No login, no cookies, no proxy to configure. **Your result limit is exact — set 80 and you get 80**, a profile we could not deliver is never charged, and **nothing at all is charged for starting a run**.

**Using an AI agent?** Pin this actor in Apify's MCP server with one link: `https://mcp.apify.com?tools=steadyfetch/instagram-similar-profiles-scraper`

- **Actor id:** `steadyfetch/instagram-similar-profiles-scraper`
- **Input:** `{ "usernames": ["nasa"], "resultsLimit": 80 }` — the one field you have to set. A profile link works too.
- **Cap the bill:** set `maxTotalChargeUsd` on the run (a run option, not Actor input), e.g. `0.50` — the run stops when it reaches it.
- **Price:** from **$0.50 per 1,000 profiles** on Gold and above, $2.00 per 1,000 on the Apify free plan. No start fee, no per-account fee, and a profile we could not deliver is never charged. Full table below.
- **How often it changes:** the suggestion list drifts as the account’s audience changes rather than hour to hour, so weekly or monthly is the useful re-run and `rank` makes each move visible when you diff it. Daily would mostly hand you the same list back, and you would be charged for it.

### What you get

One row per suggested account, with everything the suggestion exposes at one price — there is no second charge for "details":

| Column | What it holds |
|---|---|
| `username` · `fullName` · `profileUrl` | the suggested account, and a link straight to it |
| `similarTo` · `similarToUserId` | which of your accounts this suggestion came from |
| `rank` | its place in Instagram's own ordering of the suggestions, starting at 1 |
| `isVerified` · `isPrivate` | the blue check, and whether the account is locked |
| `socialContext` | Instagram's own one-line reason for the suggestion, passed through as served |
| `userId` · `profilePicUrl` | the numeric account id, and the profile picture |
| `source` | always `instagram` |
| `charged` · `status` · `statusReason` | whether this row was billed, and why, so your invoice reconciles from the dataset itself |

Profile pictures are signed and time-limited by Instagram, so download what you need in the same session. The requesting network address is stripped out of every link before it reaches your dataset.

### What a row looks like

One delivered row from a real run — the handle `nasa`, 2026-09-12. Each suggested account is one `similar-profile` charge, and `rank` is Instagram's own order, not ours. Profile pictures are signed and time-limited by Instagram, so they are shown here as placeholders.

```json
{
  "userId": "5951848929",
  "username": "nasahubble",
  "fullName": "Hubble Space Telescope",
  "profileUrl": "https://www.instagram.com/nasahubble/",
  "profilePicUrl": "https://…",
  "isPrivate": false,
  "isVerified": true,
  "socialContext": "Hubble Space Telescope",
  "similarTo": "nasa",
  "similarToUserId": "528817151",
  "rank": 2,
  "source": "instagram",
  "input": "nasa",
  "sourceIndex": 0,
  "scrapedAt": "2026-09-12T07:18:55.837Z",
  "charged": true,
  "status": "delivered",
  "retryable": false,
  "statusReason": null,
  "#k": "5951848929",
  "#ce": {"similar-profile":1},
  "#ask": {"delivered":1}
}
```

### Price

One charged event, `similar-profile`, and it lands only on a profile that was actually delivered. There is no start fee, no per-account fee and no search fee.

| Apify plan | Per profile | Per 1,000 profiles |
|---|---|---|
| Free plan | $0.002 | $2.00 |
| Bronze | $0.00117 | $1.17 |
| Silver | $0.00075 | $0.75 |
| Gold and above | $0.0005 | **$0.50 per 1,000** |

Platform usage is included in that price — there is no separate compute bill on top. Set `maxTotalChargeUsd` on the run and it is a hard ceiling: the run stops cleanly under it and the last row says what is left.

### Honest rows: what "not charged" actually means

Every run closes its own books. A profile that was not delivered leaves an uncharged row saying which of eight things happened, and none of them is billed:

- **`account_not_found`** — Instagram has no account under that name. Proved by Instagram's own account lookup answering that it does not exist, not guessed from an empty answer.
- **`private_account`** — the account is private, so Instagram will not say which accounts it treats as similar.
- **`no_suggestions`** — Instagram answered and listed no more similar accounts than were delivered. A definitive answer, not a failure.
- **`stopped_at_limit`** — one of your own limits, or the run clock, stopped it first. The row names which.
- **`vendor_unavailable`** — the read did not go through. Temporary, says nothing about the account, and a re-run is the fix.
- **`source_refused`** — Instagram refused to answer for that account at all, and it refuses the same way every time, so a re-run cannot change it. Check the spelling in a browser; if the account works there, say so on the Issues tab.
- **`unsupported_shape`** — Instagram answered in a shape this actor does not read yet. That is on us, not on your account, and a re-run gets the same answer — tell us on the Issues tab which account it was and support for it will be added.
- **`vendor_budget`** — this actor reached its own monthly collection allowance and stopped rather than collecting more.

The last row of every run is a receipt: delivered, asked for, what stopped it, and the charged-event totals. A time limit ends the collecting, never the delivering — profiles already in hand are always written out.

### How often this data changes

Instagram's suggestion list is a ranked recommendation set, not a feed: it is rebuilt from who follows the account and who those people follow, so it drifts as the account's audience changes rather than changing hour to hour. We do not have a measured cadence for it and will not invent one — what we can say is what we measured on 11 September 2026: a very large account returned about 80 suggestions in one read, a five-follower account about 20, and neither list is paginated, so one run gets everything Instagram holds for that account at that moment.

The practical advice that follows from that: for a watchlist, re-run weekly or monthly and diff the `username` column against your previous dataset — the rows carry `rank`, so a move up or down Instagram's own ordering is visible without any extra work. Re-running daily will mostly hand you the same list back, and you would be charged for it, so we say so here rather than letting you find out on the invoice. This actor deliberately keeps no memory of what it gave you before: a remembered suggestion list would be a stale one, and the second run is exactly the run where staleness would hurt.

### Reliability

The suggestions come from a licensed data feed rather than from scraping Instagram's own web pages, which is why there is nothing to log into and nothing to configure. When that feed cannot answer, the run says so on an uncharged row and finishes successfully — a failed read is never billed and never dressed up as an account with nothing similar.

### Related actors

- One account's own posts: **Instagram Profile Posts Scraper** — https://apify.com/steadyfetch/instagram-profile-posts
- The posts published under a hashtag: **Instagram Hashtag Scraper** — https://apify.com/steadyfetch/instagram-hashtag-scraper
- The spoken words inside a reel: **Instagram Reel Transcript Scraper** — https://apify.com/steadyfetch/instagram-reel-transcript-scraper

### Limits and good manners

**Max profiles** and **Max run seconds** take any number you type: this actor delivers at most 5,000 profiles in one run and runs for at most an hour (and for at least 30 seconds), so a bigger ask runs at the ceiling instead of being refused, and one uncharged row says what was asked for and what was used.

Only Instagram's own public suggestion surface is read, and only for accounts that exist. Some accounts have no suggestion list at all — Instagram simply declines to chain from them — and the run says so on an uncharged row instead of padding. This actor may stop working if Instagram changes how the data is served; if it does, undelivered items are never charged.

### Support

Something off, or a column you need that is not here? Open an issue on the Issues tab — we usually reply within a couple of hours.

If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

# Actor input Schema

## `usernames` (type: `array`):

Instagram account names, one per line — "nasa", "@nasa" or an https://www.instagram.com/nasa/ profile link all work. Letters, numbers, dots and underscores only, exactly as Instagram writes them. An account that does not exist, a private one or one with no suggestions is never charged. A hashtag or a post link is refused with an uncharged row naming the actor that does take it. Leave it empty and the run returns built-in sample rows instead of collecting anything, so you can see the output shape at no result fee.

## `resultsLimit` (type: `integer`):

Hard cap on the profiles this run delivers in total. With more than one account the limit is split evenly between them, so 80 across 2 accounts collects 40 from each; an account whose suggestion list is shorter than its share leaves an uncharged row saying so rather than borrowing another account's share. Instagram returned about 80 suggestions for a large account and about 20 for a small or private one, so a much higher limit simply collects everything there is. This actor delivers at most 5,000 profiles in one run: ask for more and the run continues at 5,000, with one uncharged row saying so.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly before this many seconds and reports what is left, instead of being killed by a timeout. A time limit ends the collecting, never the delivering: profiles already in hand are always written out. One run lasts at most 3,600 seconds and needs at least 30: ask outside that and the run continues at the nearest of the two, with one uncharged row saying so.

## Actor input object example

```json
{
  "usernames": [],
  "resultsLimit": 80,
  "maxRunSeconds": 600
}
```

# Actor output Schema

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

One row per suggested account: username, full name, profile link, verified and private flags, Instagram's own one-line reason for the suggestion, and its place in Instagram's ranking. Every row carries `charged` and `status`, so the invoice reconciles from the dataset itself — only rows with charged = true were billed, at one price for the whole row, with no second charge for details and no fee for starting the run. An account suggested for two of your handles is delivered once and charged once.

## `misses` (type: `string`):

One uncharged row for every account that returned less than it was asked for, saying which of eight things happened: `account_not_found` (Instagram has no such account), `private_account` (it is private, so Instagram will not say what it treats as similar), `no_suggestions` (Instagram listed no more similar accounts — a real answer), `stopped_at_limit` (one of your own limits or the run clock stopped it first), `vendor_unavailable` (the read failed and a re-run is the fix), `source_refused` (Instagram refused to answer for that account at all, the same way every time — a re-run cannot change it), `unsupported_shape` (Instagram answered in a shape this actor does not read yet — on us, and a re-run gets the same answer), `vendor_budget` (this actor reached its own monthly collection allowance). A limit you typed above this actor's own ceiling adds one `input_note` row instead of refusing the run, saying what was asked and what was used. None of these is charged.

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

Profiles delivered, what was asked for, accounts that appeared under more than one of your handles, what stopped the run, and the charged-event totals.

# 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 = {
    "usernames": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/instagram-similar-profiles-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 = { "usernames": [] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyfetch/instagram-similar-profiles-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/nM3I5LKIjDdtIaQhU/builds/Lln5oMoihB6NDdOdk/openapi.json
