# Instagram User Search Scraper (`dami_studio/instagram-user-search-scraper`) Actor

Instagram user search scraper: search accounts by keyword the way the app's search box does: username, name, verified and private flags, picture. Add profile details for followers, bio, links, category and business contacts. Also finds hashtags and places.

- **URL**: https://apify.com/dami_studio/instagram-user-search-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Social media
- **Features:** Limited permissions
- **Stats:** 6 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.47 / 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.

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 user search scraper: search accounts by keyword, the way the app's search box does**: type words like "coffee roaster" or "yoga teacher" and get one row per account Instagram returns, with username, name, verified and private flags and picture, and on request each account's followers, bio, links, category and the contact details a business chooses to show.

Instagram's search is shallow on purpose: for most words it goes a few dozen accounts deep, ranked its own way. Run more words to cover more ground. The same search also finds hashtags with their post counts, or places with their map position.

| | |
|---|---|
| **Input** | Up to 20 search words, as you'd type them into Instagram's search |
| **Output** | One row per account: username, name, user id, profile link, verified, private, picture; with profile details also followers, following, posts, bio, website and bio links, category, account type, published business e-mail, phone and address; on request also its latest posts with engagement figures, related profiles, and country and join date |
| **Ceiling** | 200 results per word, 2,000 per run |
| **Account needed** | None from you |
| **Price** | $0.47 per 1,000 results, plus $2.60 per 1,000 accounts with profile details and $1.30 per 1,000 for each other add-on when you turn them on, the same on every plan. The free plan's $5 a month covers about 10,600 results |

| Using an AI agent? | |
|---|---|
| Actor | `dami_studio/instagram-user-search-scraper` |
| Set one field | `searchQueries`, labelled "Search words" in the Console |
| Cap the bill | `maxTotalChargeUsd` on the run, for example `0.10`: it never charges past that |
| MCP, one link | `https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/instagram-user-search-scraper` |
| How often | Weekly, to see which accounts rise for your niche's words |

### 🔍 What Instagram User Search Scraper does

Each word goes through Instagram's own account search, and the accounts come back in Instagram's order, with `rank` saying where each one stood and `searchQuery` which word found it. An account two words found arrives once.

With **Add profile details** on, each account's profile is read too. That's what the follower, account type, bio and contact filters work on, so they need it.

**Search for** switches the same words to hashtags (name, post count, link) or places (name, address, city, latitude, longitude, link).

### 📋 What data you get from each Instagram account

| What you get | Field |
|---|---|
| Username, name, user id, profile link | `username`, `fullName`, `userId`, `profileUrl` |
| Verified and private flags, picture | `isVerified`, `isPrivate`, `profilePicUrl` |
| Rank and the word that found it | `rank`, `searchQuery` |
| Followers as Instagram writes them in search, when it does | `searchSubtitle`, `followersFromSearch` |
| Followers, following, posts (profile details) | `followerCount`, `followingCount`, `postCount` |
| Bio, website, bio links (profile details) | `biography`, `externalUrl`, `bioLinks` |
| Category and account type (profile details) | `category`, `accountType`, `isBusinessAccount` |
| What a business publishes to be contacted (profile details) | `publicEmail`, `publicPhone`, `businessAddress` |
| Large picture (profile details) | `profilePicUrlHd` |
| Latest posts and their figures (add-on) | `latestPosts`, `avgLikes`, `avgComments`, `medianViews`, `engagementRate`, `postsPerWeek`, `lastPostAt`, `daysSinceLastPost` |
| Related profiles (add-on) | `relatedProfiles` |
| Country and join date (add-on) | `country`, `dateJoined`, `accountAgeDays`, `formerUsernameCount` |
| Hashtag rows | `name`, `url`, `mediaCount`, `mediaCountText` |
| Place rows | `name`, `placeId`, `url`, `address`, `city`, `latitude`, `longitude` |

### ▶️ How to search Instagram users by keyword

1. Open the actor and go to the **Input** tab.
2. Type your words into **Search words**, one per line.
3. Turn on **Add profile details** if you need followers, bios or the filters, and any of the other add-ons under **More about each account**.
4. Set **Results per search word** and **Maximum results in all**, then press **Start**.
5. Open the **Output** tab; the **Accounts** view shows the main columns.

### 💰 How much does it cost to search Instagram users?

$0.47 per 1,000 results on every plan. With profile details, each account costs $2.60 per 1,000 on top, so $3.07 per 1,000 detailed accounts. Latest posts, related profiles, and country and join date are $1.30 per 1,000 accounts each, charged only for an account that has them. The free plan's $5 a month covers about 10,600 results, or about 1,620 with profile details.

Not charged: note rows (a word with no results, a filter nothing passed, a stop), accounts a filter leaves out, and duplicates inside a run.

### 📥 What you give it

| Field | What it does | Default |
|---|---|---|
| `searchQueries` | Words or phrases, up to 20 | none |
| `searchType` | `accounts`, `hashtags` or `places` | `accounts` |
| `maxResultsPerQuery` | Results kept for each word, up to 200 | 20 |
| `maxResults` | The most results a run delivers, up to 2,000 | 100 |
| `includeProfileDetails` | Read each account's profile (paid) | false |
| `verifiedOnly` | Keep only accounts with the blue check | false |
| `includePrivateProfiles` | Keep private accounts (name and picture only) | true |
| `excludeAccounts` | Handles or profile links to leave out | none |
| `minFollowers`, `maxFollowers` | Follower range (needs profile details) | none |
| `accountType` | `any`, `personal`, `business`, `creator` or `professional` (business or creator), needs profile details | `any` |
| `bioKeywords`, `excludeBioKeywords` | Words the bio or name must or must not contain (needs profile details) | none |
| `onlyWithEmail`, `onlyWithWebsite` | Keep accounts that publish an e-mail, or that have a website or bio links (needs profile details) | false |
| `includeLatestPosts` | Add each account's latest posts and their figures (paid) | false |
| `includeRelatedProfiles` | Add the accounts Instagram suggests beside each account (paid) | false |
| `includeAccountAbout` | Add the country, join date and former-username count (paid) | false |

A filter that needs profile details is refused, before anything is looked up, when profile details are off. With such a filter on, a run reads at most twice as many profiles as the results it keeps for each word, so a tight filter can return fewer than you asked for; a free note says so.

```json
{
  "searchQueries": ["coffee roaster"],
  "includeProfileDetails": true,
  "minFollowers": 5000,
  "maxResultsPerQuery": 20
}
```

### 📤 What you get back

A real row from a run on 7 November 2026, trimmed:

```json
{
  "recordType": "account",
  "ok": true,
  "charged": true,
  "rank": 3,
  "searchQuery": "coffee roaster",
  "username": "stumptowncoffee",
  "fullName": "Stumptown Coffee Roasters",
  "userId": "11498596",
  "profileUrl": "https://www.instagram.com/stumptowncoffee/",
  "isVerified": true,
  "isPrivate": false,
  "searchSubtitle": "308K followers",
  "followersFromSearch": 308000,
  "hasDetails": true,
  "followerCount": 308253,
  "followingCount": 2541,
  "postCount": 4141,
  "biography": "Highest Quality ☕️ Roasted Daily\nCertified B Corporation",
  "externalUrl": "http://linktr.ee/stumptowncoffee",
  "bioLinks": ["http://linktr.ee/stumptowncoffee"],
  "category": null,
  "accountType": "business",
  "isBusinessAccount": true,
  "publicEmail": null,
  "publicPhone": null,
  "businessAddress": null
}
```

| Field | Worth knowing |
|---|---|
| `followersFromSearch` | Rounded, from the text under the account in search; filled for a few accounts per search. `followerCount` is exact |
| Profile detail fields | Empty without profile details, and empty when the account doesn't show that part |
| `engagementRate` | Average likes plus comments of the latest posts, over the followers, in percent: needs profile details as well as latest posts |
| `latestPosts` | The first page of the account's grid, newest first; `isPinned` marks a post the account pinned to the top |
| `profilePicUrl`, `profilePicUrlHd` | Links on Instagram's servers that expire after a few days |

### 🧾 Reading the output

Real rows carry `ok: true` and `charged: true`, and `recordType` is `account`, `hashtag` or `place`. Each is billed as a result; rows with `hasDetails: true` are billed profile details as well, and `hasLatestPosts`, `hasRelatedProfiles` and `hasAccountAbout` mark the other add-ons billed on that row.

Note rows carry `recordType: "note"`, `ok: false` and an `errorCode`, and are never billed:

| Code | Meaning |
|---|---|
| `BAD_INPUT` | A field couldn't be used; `details` says which |
| `NO_RESULTS` | Instagram returned nothing for this word |
| `FILTERED_OUT` | Profiles were read but too few passed your filters |
| `NOT_SERVED` | Instagram didn't serve this word in this run; re-run it later |
| `MAX_ITEMS`, `COST_LIMIT`, `TIME_LIMIT` | The run stopped at your result limit, spending limit or time limit |
| `FREE_PLAN_LIMIT` | A free-plan run stopped early; a paid plan runs the whole input |
| `UNEXPECTED_ERROR` | The run stopped on an error on our side; rows before it are kept |

To keep only results, filter on `ok == true`.

### 💡 What people use it for

- Brands looking for creators in a niche: search the niche's words, keep business or creator accounts between 5,000 and 100,000 followers, and read the bios.
- Agencies listing the cafés, gyms or studios of a city: "yoga studio lisbon", with the address and the e-mail they publish.
- Checking which accounts own a keyword before a launch, by `rank`.
- Finding the hashtags people actually use around a topic, with their post counts.

A recipe with our other actors: search accounts here, keep the ones you want by `followerCount` or `category`, then pass their usernames to [Instagram Profile Scraper](https://apify.com/dami_studio/instagram-profile-scraper) for their latest posts, or to [Instagram Reel Scraper](https://apify.com/dami_studio/instagram-reel-scraper) for their reels.

### 🚧 What it does not do

- No private profile details: a private account comes back with its name and picture only.
- No lists of who follows an account.
- No posts or reels in the rows; see the routing table below.
- It is not an official Instagram tool. Dami's Studio is independent and is not affiliated with or endorsed by Instagram or Meta, or by any other company named on this page.

### 🧭 Which Instagram scraper do you need?

| If you want | Use |
|---|---|
| Accounts, hashtags or places for a word | This one, [Instagram User Search Scraper](https://apify.com/dami_studio/instagram-user-search-scraper) |
| Full profiles and latest posts of accounts you already know | [Instagram Profile Scraper](https://apify.com/dami_studio/instagram-profile-scraper) |
| Reels for a keyword or hashtag | [Instagram Reels Search Scraper](https://apify.com/dami_studio/instagram-reels-search-scraper) |
| Posts under a hashtag | [Instagram Hashtag Scraper](https://apify.com/dami_studio/instagram-hashtag-scraper) |
| Posts at a place | [Instagram Location Scraper](https://apify.com/dami_studio/instagram-location-scraper) |

### ❓ Questions people ask

#### Do I need an Instagram account to search users?

No, you don't need one, and there's no cookie to paste.

#### Why do I get fewer accounts than I asked for?

Instagram's account search stops after a few dozen results for most words. Add more words, or nearby phrasings, to reach further.

#### Why don't the results match what I see in the app?

Instagram ranks search for each viewer, so your app shows its own order. Follower counts keep moving and the app rounds them.

#### Can I call it from code or connect it to an AI assistant?

Yes. The **API** tab on the actor page has ready code. For an assistant, use the MCP link `https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/instagram-user-search-scraper`.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("dami_studio/instagram-user-search-scraper").call(
    run_input={"searchQueries": ["coffee roaster"], "maxResultsPerQuery": 20},
    max_total_charge_usd=0.10,
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("ok") is False:
        continue
    print(row["username"], row["fullName"])
```

#### Is scraping Instagram legal?

This reads public search results and public profiles only, never private accounts or messages, and you need no account. Results contain personal data, which GDPR and similar laws cover, so keep only what you need, and mind the rules on cold contact before you use a published e-mail or phone number. Instagram's own terms still apply to what you do with the data. Apify's write-up on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good starting point, and we are not lawyers.

### 🆘 If something breaks

Open the **Issues** tab on the actor page. Include the run ID and the search words you used.

# Actor input Schema

## `searchQueries` (type: `array`):

Words, names or phrases, one per line, as you'd type them into Instagram's search: "yoga teacher", "coffee roaster berlin", "nasa". Up to 20 a run.

## `searchType` (type: `string`):

Accounts (the default), hashtags with their post counts, or places with their address and map position.

## `maxResultsPerQuery` (type: `integer`):

How many results to keep for each search word. Instagram's own search goes a few dozen deep for most words.

## `maxResults` (type: `integer`):

The run stops after this many results across every search word, so a long list can't cost more than you expect.

## `includeProfileDetails` (type: `boolean`):

Accounts only. Read each account's profile: followers, following, posts, bio, website and bio links, category, account type, and the e-mail, phone and address a business chooses to show. Charged per account it's added to, on top of the result.

## `verifiedOnly` (type: `boolean`):

Keep only accounts with Instagram's blue check.

## `includePrivateProfiles` (type: `boolean`):

Private accounts come back with their name and picture only. Turn this off to leave them out.

## `excludeAccounts` (type: `array`):

Handles or profile links to leave out, for example accounts you already have.

## `minFollowers` (type: `integer`):

Needs "Add profile details". Keep accounts with at least this many followers.

## `maxFollowers` (type: `integer`):

Needs "Add profile details". Keep accounts with at most this many followers.

## `accountType` (type: `string`):

Needs "Add profile details". Personal, business or creator; professional means business or creator.

## `bioKeywords` (type: `array`):

Needs "Add profile details". Keep accounts whose bio or name contains any of these words.

## `excludeBioKeywords` (type: `array`):

Needs "Add profile details". Leave out accounts whose bio or name contains any of these words.

## `onlyWithEmail` (type: `boolean`):

Needs "Add profile details". Keep business accounts that publish a contact e-mail on their profile.

## `onlyWithWebsite` (type: `boolean`):

Needs "Add profile details". Keep accounts that have a website or links in their bio.

## `includeLatestPosts` (type: `boolean`):

Paid. Each account's latest posts, the first page of its grid, newest first (link, type, date, likes, comments, views, caption), with average likes and comments, median views, posts a week and days since the last post. The engagement rate needs "Add profile details" too.

## `includeRelatedProfiles` (type: `boolean`):

Paid. The accounts Instagram suggests beside each account: username, name, id, verified, private, link.

## `includeAccountAbout` (type: `boolean`):

Paid. From each account's "About this account" panel: the country, the date it joined and how many former usernames it has, when Instagram shows them.

## Actor input object example

```json
{
  "searchQueries": [
    "coffee roaster"
  ],
  "searchType": "accounts",
  "maxResultsPerQuery": 20,
  "maxResults": 100,
  "includeProfileDetails": false,
  "verifiedOnly": false,
  "includePrivateProfiles": true,
  "accountType": "any",
  "onlyWithEmail": false,
  "onlyWithWebsite": false,
  "includeLatestPosts": false,
  "includeRelatedProfiles": false,
  "includeAccountAbout": false
}
```

# Actor output Schema

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

Every row in the default dataset. recordType is account, hashtag, place, or note for a free row that explains something.

## `accounts` (type: `string`):

The accounts in the Accounts view.

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

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/instagram-user-search-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 = { "searchQueries": ["coffee roaster"] }

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

```

## MCP server setup

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