# Instagram Followers & Following Scraper (`dami_studio/instagram-followers-following-scraper`) Actor

Scrape Instagram followers and following lists from public profiles. Extract username, full name, verified and private flags, profile picture and profile URL. No login, no cookie, no app review. Export JSON/CSV/Excel. $0.60 per 1,000 rows.

- **URL**: https://apify.com/dami\_studio/instagram-followers-following-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/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 Followers & Following Scraper

Extract follower and following profile rows from public Instagram accounts. Give it up to five
usernames, `@handles` or profile URLs and it returns one clean row per relationship profile —
account ID, username, full name, private and verified flags, profile picture and profile URL —
ready to export as JSON, CSV, Excel or XML, or to pull straight from the Apify API.

Follower lists run with no setup: **no login, no cookie, no app review.**

**What people use it for**

- Building an audience list for a creator, brand or competitor account.
- Finding the overlap between two accounts' follower lists.
- Filtering an audience down to verified accounts, or excluding private ones.
- Tracking audience growth by running on a schedule and diffing the datasets.
- Feeding usernames into the [Instagram Profile Scraper](https://apify.com/dami_studio/instagram-profile-scraper)
  to enrich each follower with bio, counts and category.

### Input

- `profiles`: up to five usernames, handles, or Instagram profile URLs.
- `listType`: `followers`, `following`, or `both`. Default `followers`. A `following` list needs
  your own account cookie — see [Coverage and limits](#coverage-and-limits).
- `maxItemsPerProfile`: 1–1,000 rows per source profile and list; default 100.
- `sessionCookies`: optional. Your own Instagram account cookie.
- `proxyConfiguration`: proxy configuration. Your own `proxyUrls` are used exactly as supplied;
  metered Apify groups (`RESIDENTIAL`, `GOOGLE_SERP`) are not offered and are replaced with rotating
  datacenter addresses, with a warning in the log and run status.
- `maxAttempts`: 1–12 bounded attempts; default 8.
- `requestTimeoutSeconds`: 5–30 seconds per request.
- `maxRunSeconds`: 20–180 second run deadline; default 120.

Minimal input:

```json
{
  "profiles": ["nasa"],
  "listType": "followers",
  "maxItemsPerProfile": 100
}
```

Empty `profiles` returns one clearly labeled `_sample` row and makes no request, proxy connection, or
billing event.

### Output

One row per relationship profile.

| Field | Type | What it is |
| :--- | :--- | :--- |
| `ok` | boolean | `true` on a genuine data row, `false` on an uncharged diagnostic row. |
| `recordType` | string | Always `relationship_profile` for a data row. |
| `id` | string | Numeric Instagram account ID of the follower / followed account. |
| `username` | string | Their Instagram handle. |
| `fullName` | string | null | Display name. `null` when the account has none. |
| `isPrivate` | boolean | Whether their account is private. |
| `isVerified` | boolean | Whether their account carries the blue check. |
| `profilePicUrl` | string | null | Profile picture URL. Instagram CDN links expire — download promptly. |
| `sourceUsername` | string | The profile you asked about. |
| `sourceProfileId` | string | Numeric ID of the profile you asked about. |
| `listType` | string | `followers` or `following` — which list this row came from. |
| `profileUrl` | string | `https://www.instagram.com/<username>/` |

#### Sample output

Values below are illustrative, but the shape and field names are exactly what a real run writes to
the dataset:

```json
{
  "ok": true,
  "recordType": "relationship_profile",
  "id": "1783412996",
  "username": "aurora.makes",
  "fullName": "Aurora Bennett",
  "isPrivate": false,
  "isVerified": false,
  "profilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/379204118_1122_n.jpg",
  "sourceUsername": "nasa",
  "sourceProfileId": "528817151",
  "listType": "followers",
  "profileUrl": "https://www.instagram.com/aurora.makes/"
}
```

### Coverage and limits

Everything here is worth knowing, and none of it is hidden behind a silent empty result: every
constraint below arrives in the dataset as a labeled, **uncharged** row carrying an `errorCode` and a
plain-English `details` field.

**Follower lists work out of the box.** Instagram serves relationship lists only to a signed-in
caller, so this actor reads them through a licensed data source. You supply nothing.

**`following` lists need your own cookie.** The licensed source covers **follower** lists only. Ask
for a `following` list without supplying a cookie and you get an uncharged `PROVIDER_UNSUPPORTED`
row explaining exactly that — never a silent empty result, and never a charge:

```json
{
  "ok": false,
  "errorCode": "PROVIDER_UNSUPPORTED",
  "error": "When no Instagram session is available this Actor falls back to a paid data source that can return follower lists only. To collect a following list, supply your own account cookie in sessionCookies.",
  "_notice": "This record is diagnostic only and is never charged.",
  "sourceUsername": "nasa",
  "sourceProfileId": "528817151",
  "listType": "following"
}
```

To unlock `following`, or to run on your own account's rate limit rather than a shared one, put your
own cookie in `sessionCookies`:

- In Chrome: `F12` → Application → Cookies → `https://www.instagram.com` → copy the `sessionid`
  value. Pasting the whole cookie string works too.
- Your cookie takes priority over everything else. The run uses it and nothing else, which is the
  point — you are buying isolation and full `following` support.
- Use an account you own and are authorized to automate.

Cookie values, proxy URLs, and request headers are never logged or written to output. Logs contain
only slot numbers, counts, retry reasons, and result totals.

**Other limits, stated plainly:**

- **Private source accounts.** If the account you ask about is private, its relationship lists are
  not available to this actor and you get an uncharged diagnostic row instead of rows.
- **Five profiles per run, 1,000 rows per profile and list.** Both are hard schema ceilings. Split
  larger jobs across runs.
- **The run deadline can stop a large collection early.** `maxRunSeconds` caps the run at 180
  seconds. Everything already collected is delivered and correct, and one uncharged `PARTIAL` row
  records that it stopped and why. There is no cross-run cursor, so a re-run starts the list again
  from the top — if you hit `PARTIAL` repeatedly, lower `maxItemsPerProfile` or raise
  `maxRunSeconds` rather than expecting the next run to resume.
- **`fullName` and `profilePicUrl` can be `null`.** They are `null` when the data source does not
  carry them for that account — not silently dropped, and not invented.
- **No follower counts, bios, emails or post history here.** This actor returns the relationship
  list itself. Enrich the usernames with the profile actor linked at the bottom of this page.
- **Metered proxy groups are not offered.** Requests for `RESIDENTIAL` or `GOOGLE_SERP` are replaced
  with rotating datacenter addresses and the substitution is announced in the log and run status.
- **Ordering is Instagram's, not ours.** Rows arrive in the order the source returns them; duplicate
  accounts across pages are removed within a run.

### What you are charged for

You are charged **per delivered follower row, once each**, and for nothing else.

Every other outcome is free and clearly labeled. Sample rows, unresolvable profiles, unsupported
`following` requests, and runs that stop early all arrive as uncharged diagnostic rows carrying an
`errorCode` and a plain-English `details` field. A run that returns nothing costs nothing.

If a run stops before reaching your requested limit, everything it already collected is delivered and
correct, and one uncharged row tells you it stopped and why.

### How it works

The source username is resolved from the public, logged-out profile endpoint first, because that
answers a guest request and costs nothing. Only if Instagram gates that lookup is a paid resolution
used. The relationship list itself has no logged-out route, so it is read from the licensed source,
or from your cookie when you supply one.

Failures are named for what they are rather than flattened into one generic error: a rate limit reads
as a rate limit, an upstream outage as an upstream outage, and a problem on our side is never
reported as a problem on yours.

### FAQ

**Is it legal to scrape Instagram?**
We can't give legal advice, so here is exactly what the actor does and does not do. It reads
relationship lists for the public accounts you name, through a licensed data source. It does not
break, bypass or brute-force any login, it does not crack private accounts, and it does not reach
anything gated behind a follow request or a friendship approval. What it returns is profile-level
information — handle, display name, public flags, picture URL. Whether *you* may collect and store
that data is a question about your jurisdiction, your purpose, and your relationship to those
people: follower lists are personal data, so GDPR, CCPA and Instagram's own terms apply to how you
use them. That responsibility is yours, and if the use case is at all sensitive, ask a lawyer rather
than a README.

**Do I need an Instagram account or cookie?**
Not for follower lists — those run with nothing from you at all. You only need a cookie for
`following` lists, or if you want a private rate limit instead of a shared one. See
[Coverage and limits](#coverage-and-limits).

**How much does it cost, and what am I charged for?**
$0.60 per 1,000 delivered rows, charged once per unique relationship profile actually written to
your dataset. Samples, diagnostics, unsupported `following` requests and early stops are never
charged.

**What happens if it returns nothing?**
You pay nothing, and you get a labeled row telling you why: `NO_RESULTS` when the list itself came
back empty, `NOT_FOUND` when the username could not be resolved to an account,
`PROVIDER_UNSUPPORTED` for a `following` request with no cookie, `PARTIAL` when the run ran out of
time or budget. A silent empty dataset is the one outcome this actor is built never to produce.

**Can I actually get a `following` list?**
Yes — with your own account cookie in `sessionCookies`. Without one, the answer is no, and you get
the uncharged `PROVIDER_UNSUPPORTED` row shown above rather than an empty result. This is the
actor's single real constraint and it is stated plainly rather than discovered at run time.

**Can I scrape a private account's followers?**
No. If the source profile is private, its relationship lists are not available and you get an
uncharged diagnostic row. There is no setting that changes this.

**How many followers can I pull in one run?**
Up to 1,000 per profile per list, across up to five profiles. Large pulls can hit the
`maxRunSeconds` deadline first; when that happens you keep everything collected plus one uncharged
`PARTIAL` row.

**What can I put in `profiles`?**
Bare usernames (`nasa`), handles (`@nasa`), or full profile URLs
(`https://www.instagram.com/nasa/`). All three are accepted and normalised. Anything unparseable
comes back as an uncharged `BAD_INPUT` row identifying which input index was wrong.

**Do I need to bring a proxy?**
No. The actor manages its own egress. If you supply `proxyUrls`, they are used exactly as given.
Metered Apify groups (`RESIDENTIAL`, `GOOGLE_SERP`) are not selectable and are swapped for rotating
datacenter addresses, with a warning in the run status.

**Is my cookie stored or logged anywhere?**
No. Cookie values, proxy URLs and request headers are never written to the log or the dataset. Logs
carry only slot numbers, counts, retry reasons and totals.

**Are the profile picture URLs permanent?**
No — Instagram CDN links expire. If you need the images, download them soon after the run rather
than storing the URL for later.

**Can I run it on a schedule or from my own code?**
Yes. It is a standard Apify actor: run it from the API, the JS/Python clients, the CLI, an Apify
schedule, or any of the platform integrations, and export the dataset as JSON, CSV, Excel or XML.

### Need other Instagram data?

This actor is built for the follower and following lists behind a public profile. If you need a
different Instagram surface, use the dedicated actor for it:

| Actor | What it returns | Price |
| :--- | :--- | :--- |
| [Instagram Profile Scraper](https://apify.com/dami_studio/instagram-profile-scraper) | Profile stats and account flags, full payload | $0.70 / 1,000 |
| [Instagram Profile Scraper](https://apify.com/dami_studio/instagram-profile-scraper-v1) | Profile stats and account flags, lean payload | $0.55 / 1,000 |
| [Instagram Mentions Scraper](https://apify.com/dami_studio/instagram-mentions-scraper) | Posts that tagged or mentioned an account | $0.44 / 1,000 |
| [Instagram Comments Scraper](https://apify.com/dami_studio/instagram-comments-scraper) | Comments on a specific post or reel | $0.40 / 1,000 |
| [Instagram Scraper](https://apify.com/dami_studio/instagram-scraper) | Profiles, posts and reels from usernames or URLs — the general-purpose one | $0.45 / 1,000 |
| [Instagram Post Scraper](https://apify.com/dami_studio/instagram-post-scraper) | A single post by URL, full payload | $0.18 / 1,000 |
| [Instagram Post Scraper](https://apify.com/dami_studio/instagram-post-scraper-v1) | A single post by URL, lean payload | $0.09 / 1,000 |
| [Instagram Reel Scraper](https://apify.com/dami_studio/instagram-reel-scraper) | A single reel by URL, full payload | $0.35 / 1,000 |
| [Instagram Reel Scraper](https://apify.com/dami_studio/instagram-reel-scraper-v1) | A single reel by URL, lean payload | $0.18 / 1,000 |
| [Instagram Reels Search](https://apify.com/dami_studio/instagram-reels-search-scraper) | Reels found by keyword or hashtag search | $0.40 / 1,000 |
| [Instagram Hashtag Scraper](https://apify.com/dami_studio/instagram-hashtag-scraper) | Posts under any hashtag, top feed | $0.40 / 1,000 |
| [Instagram Location Scraper](https://apify.com/dami_studio/instagram-location-scraper) | Posts tagged at a place, ranked and recent tabs | $0.40 / 1,000 |
| [Instagram Stories Scraper](https://apify.com/dami_studio/instagram-stories-scraper) | Stories a public account has live right now | $0.40 / 1,000 |
| [Instagram Transcript Scraper](https://apify.com/dami_studio/instagram-transcript-scraper) | Spoken-word transcript of a reel or video | $2.50 / 1,000 |
| [Instagram Reel Uploader](https://apify.com/dami_studio/instagram-reel-uploader) | Publishes a reel to your own account | $100.00 / 1,000 |

# Actor input Schema

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

Public Instagram usernames, @handles, or profile URLs. Empty input emits one labeled, uncharged sample row without using credentials or proxy.

## `listType` (type: `string`):

Extract followers, following, or both relationship lists.

## `maxItemsPerProfile` (type: `integer`):

Maximum relationship profiles returned for each source profile and selected list.

## `sessionCookies` (type: `array`):

Optional. Runs use a built-in session by default, which is shared with everyone else running this Actor. Supply your own Instagram account cookie here to get a private rate limit that no other user shares. In Chrome: F12 -> Application -> Cookies -> https://www.instagram.com, then copy the sessionid value. Pasting the whole cookie string works too. Cookie values are never logged or written to the output.

## `proxyConfiguration` (type: `object`):

Proxy used for authenticated Instagram friendship requests. A sticky datacenter IP is retained until a bounded account/IP rotation is necessary. Your own proxy servers in proxyUrls are used exactly as given; metered Apify groups (RESIDENTIAL, GOOGLE\_SERP) are not offered and are replaced with rotating datacenter addresses.

## `maxAttempts` (type: `integer`):

Bounded retries across rotating configured accounts and sticky proxy sessions.

## `requestTimeoutSeconds` (type: `integer`):

Timeout for each Instagram web API request.

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

Hard wall-clock bound for profile resolution and relationship pagination.

## Actor input object example

```json
{
  "profiles": [
    "nasa",
    "natgeo"
  ],
  "listType": "followers",
  "maxItemsPerProfile": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "BUYPROXIES94952"
    ]
  },
  "maxAttempts": 8,
  "requestTimeoutSeconds": 15,
  "maxRunSeconds": 120
}
```

# Actor output Schema

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

One row per authenticated follower or following profile. Samples and diagnostics are never charged.

# 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": [
        "nasa"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/instagram-followers-following-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": ["nasa"] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/instagram-followers-following-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/sI4UdrelMLSIGfMC1/builds/fnGm0du9azyCiuoqY/openapi.json
