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

Find Instagram users by keyword with bios, follower counts, verified and business flags, contact hints and provenance. No login. $0.005/user.

- **URL**: https://apify.com/khadinakbar/instagram-user-search-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Social media, MCP servers, Lead generation
- **Stats:** 14 total users, 8 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 instagram user founds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 User Search Scraper — Find Users by Keyword

Search Instagram for public users by keyword and the Actor returns structured, filterable user rows: username, full name, bio, follower/following/post counts, verified and business flags, Instagram category, bio links, and email or phone contacts parsed from public bios. Marketers, agencies, and researchers use it to turn niche phrases like "vegan bakery london" into deduplicated user lists with the audience-count and account-type fields they need for outreach. No Instagram login, no cookies, and no browser are involved — the Actor routes each keyword through managed public-data APIs and works with public accounts only.

### Best fit for this Actor

Use this Actor when you start from a **keyword** and need a list of matching **Instagram users** — for example "vegan bakery london", "dental clinic dubai", or "fitness coach nyc" — with audience-size and account-type filtering applied before you pay for a row.

- Best fit: niche creator discovery, micro-influencer shortlists (set a follower band), local-business lead lists with public contact hints, and competitor account mapping by keyword.
- For posts, reels, or stories from the users you find, run [Instagram Posts Scraper](https://apify.com/khadinakbar/instagram-posts-scraper) on the returned handles next.
- For hashtag-centered research, use [Instagram Hashtag Scraper](https://apify.com/khadinakbar/instagram-hashtag-scraper) instead, and it covers hashtag volumes and top media.
- When you already know the exact handle, use [Instagram Profile Scraper](https://apify.com/khadinakbar/instagram-profile-scraper) for a single deep profile, then enrich from there.
- Sibling routing: [Instagram User Scraper](https://apify.com/khadinakbar/instagram-user-scraper) covers a similar keyword-to-profile job with contact parsing focused on a single research thread; this Actor adds follower bands, verified-only and account-type filters, a global results cap, and a second provider route for resilience.

### Focused standalone workflow

This Actor is designed as a focused standalone workflow: an agency building a micro-influencer outreach list for a fitness brand enters keywords like "fitness coach" with a 10K–100K follower band, includes business and creator accounts, and runs it. The dataset that comes back is already deduplicated across keywords, filtered to the audience band, and carries parsed bio emails where they are public — then feed it straight into a CRM. To map the audience behind a specific shortlisted creator, pass the handles to [Instagram Followers Scraper](https://apify.com/khadinakbar/instagram-followers-scraper) as the next step.

### Quick start

1. Add one or more keywords to **Search keywords** (e.g., `fitness coach`).
2. Optionally set a follower band (**Minimum followers** / **Maximum followers**), **Verified accounts only**, or an **Account type**.
3. Start the run. Each keyword returns up to **Maximum results per keyword** unique public users; the whole run stops at **Maximum total results**.

#### Input example

```json
{
  "searchQueries": ["fitness coach", "personal trainer london"],
  "maxResultsPerQuery": 20,
  "maxResults": 100,
  "minimumFollowers": 10000,
  "maximumFollowers": 100000,
  "verifiedOnly": false,
  "accountType": "any",
  "includePrivateProfiles": false,
  "parseContacts": true,
  "provider": "auto"
}
```

### Input contract

| Field | Type | Default | Purpose |
| --- | --- | --- | --- |
| `searchQueries` | string\[] (required) | `["fitness coach"]` | Keyword phrases used to find users; deduplicated, max 50. |
| `maxResultsPerQuery` | integer | `20` | Cap on unique users saved per keyword after filters (1–100). |
| `maxResults` | integer | `200` | Global cap across all keywords in the run (1–1000). |
| `minimumFollowers` | integer | `0` | Exclude accounts below this follower count; `0` keeps everyone. |
| `maximumFollowers` | integer | `0` | Exclude accounts above this follower count; `0` sets no ceiling. |
| `verifiedOnly` | boolean | `false` | Keep only Instagram-verified accounts. |
| `accountType` | enum | `any` | `any`, `personal`, `business`, or `professional`. |
| `includePrivateProfiles` | boolean | `false` | Also save private accounts when they match. |
| `parseContacts` | boolean | `true` | Parse public email/phone from bio text and bio links. |
| `provider` | enum | `auto` | `auto`, `scrapeCreators`, or `sociaVault`. |

### Output: what one dataset row represents

Each dataset item is **one unique public Instagram user matched by one keyword**, already filtered and deduplicated. Field list verified against live runs:

| Field | Meaning |
| --- | --- |
| `username`, `fullName`, `profileUrl`, `userId` | Identity and canonical profile link. |
| `biography`, `bioLinks[]`, `externalUrl` | Public bio text and the links published in it. |
| `followerCount`, `followingCount`, `mediaCount` | Audience and activity counts at discovery time. |
| `isVerified`, `isPrivate`, `isBusinessAccount`, `isProfessionalAccount`, `category` | Account flags and Instagram category label. |
| `email`, `phone` | Contacts parsed from public bio text; `null` when the bio publishes none. |
| `matchedQuery`, `position` | Which keyword surfaced this user and its rank for that keyword. |
| `provider`, `scrapedAt` | Which data route returned the record and when it was collected. |

#### Output example

```json
{
  "userId": "57054133744",
  "username": "shotzbydreww",
  "fullName": "Travel Photographer",
  "biography": "Full Stack Creator \nOwner | Of @motionshiftmedia",
  "followerCount": 84000,
  "followingCount": 1200,
  "mediaCount": 340,
  "isVerified": true,
  "isPrivate": false,
  "isBusinessAccount": false,
  "isProfessionalAccount": true,
  "category": "Photography Videography",
  "externalUrl": null,
  "bioLinks": [],
  "email": null,
  "phone": null,
  "profileUrl": "https://www.instagram.com/shotzbydreww/",
  "matchedQuery": "travel photographer",
  "position": 1,
  "provider": "scrapeCreators",
  "scrapedAt": "2026-08-18T00:00:00.000Z"
}
```

### How collection works

The Actor is a plain Node.js runtime with no browser. For each keyword it calls a managed Instagram-native profile-search API (ScrapeCreators) and normalizes every returned profile against the dataset contract. When that route is rejected, rate-limited, or down, the `auto` provider mode retries the keyword through a secondary route (SociaVault Google site-search) and rebuilds records from profile URLs and public count snippets. Both routes return public data only. You can force either route with the `provider` input.

### Pricing and cost control

Billing is **Pay per event + platform usage**:

- `$0.005` per unique `user-found` — charged only when a filtered, validated user row is actually saved.
- `$0.00005` actor start.
- Platform compute usage is passed through and billed separately; the live Pricing tab is the current source of truth for effective pricing.

Before the first charge the run prints its maximum event cost, e.g. 5 keywords × 20 results × $0.005 = **$0.50 event cap**, and it stops early at `maxResults`, `maxResultsPerQuery`, or the run-level charge limit (`ACTOR_MAX_TOTAL_CHARGE_USD`), whichever comes first. Filtering happens **before** charging, so rows rejected by your follower band or verified-only filter are free.

### API example

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~instagram-user-search-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchQueries": ["specialty coffee shop"],
    "maxResultsPerQuery": 10,
    "minimumFollowers": 1000,
    "parseContacts": true
  }'
```

The response contains a `defaultDatasetId`; fetch rows with `GET /v2/datasets/{defaultDatasetId}/items?clean=true`.

### AI agent and MCP use

This Actor is MCP-ready through `mcp.apify.com`. Point an MCP client at `khadinakbar/instagram-user-search-scraper` and call it with a narrow, bounded prompt:

> Find Instagram users matching the keyword "vegan bakery london". Keep public accounts in the 5K–100K follower band, parse public emails from bios, and return at most 20 matching profiles. Report username, followerCount, isVerified, email, and profileUrl per profile.

Agent guidance: every run ends with a terminal outcome in `OUTPUT` (`COMPLETE`, `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, `UPSTREAM_FAILED`, `CONFIG_ERROR`); read the dataset back via the run's `defaultDatasetId` for full rows; each row carries `provider` and `scrapedAt` provenance; event cost is `$0.005` per saved row plus platform usage, so cap spend with `maxResults`; scope is public keyword search only, and pagination is controlled by `maxResultsPerQuery` per keyword.

### Outcome and recovery semantics

Every run writes `OUTPUT` and `RUN_SUMMARY` with one terminal outcome: `COMPLETE`, `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, `UPSTREAM_FAILED`, or `CONFIG_ERROR`. Partial results (some keywords succeeded) succeed with the data saved; provider outages with zero useful rows end with a truthful `UPSTREAM_FAILED` record. A `STATE` record tracks seen usernames and counters so an aborted-and-resumed run skips users it already saved.

### Guidance for reliable results

- Provide natural niche phrases (2–4 words) rather than single head terms; broad terms like "fitness" can legitimately return zero indexed matches, reported as `VALID_EMPTY`.
- Combine `minimumFollowers` and `maximumFollowers` to define your audience band once, at collection time.
- Runs are fastest and lightest with `parseContacts: false` when you only need identity and counts.
- If a keyword repeatedly returns nothing, retry it later or rephrase it; provider coverage of the public search index varies over time.
- Start with a small `maxResults` while you tune filters, then scale up once the rows look right.

### Workflow example

Keyword discovery here, then enrichment downstream: pass the `username` values from this dataset to [Instagram Profile Scraper](https://apify.com/khadinakbar/instagram-profile-scraper) for full profile detail, then feed the same handles to [Instagram Posts Scraper](https://apify.com/khadinakbar/instagram-posts-scraper) for recent content, and then to [Instagram Followers Scraper](https://apify.com/khadinakbar/instagram-followers-scraper) to map the audience of shortlisted accounts.

### Builder's note

I built this Actor after probing both provider routes with live keywords: the native profile-search route returns verified, business, and category flags directly, while the Google site-search route surfaces different, often larger accounts with count snippets that need careful parsing. I designed the filter set (follower bands, verified-only, account type) to run before any charge fires, because paying for rows you would discard is the fastest way to burn trust in a discovery tool. In my testing, the same broad keyword sometimes returned zero matches hours after returning a full page, so I made per-keyword coverage visible in `RUN_SUMMARY` instead of hiding it.

### Data and legal boundary

This Actor processes publicly accessible Instagram profile data via managed APIs. It accesses public profiles only, and it respects Instagram's platform protections. Use it lawfully, respect Instagram's Terms of Service, only process data you have a lawful basis to collect, and honor data-subject requests for the lists you build.

# Actor input Schema

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

Keywords used to find public Instagram users, one keyword phrase per entry (e.g., "fitness coach" or "vegan bakery london"). Plain natural-language phrases work best; avoid hashtags and URLs. Runs each keyword independently and deduplicates users found across keywords.

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

Upper bound on unique users saved for each keyword after filters are applied. Defaults to 20 and cannot exceed 100. Lower it to cap Pay per event charges for exploratory runs.

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

Global cap on unique users saved across all keywords in one run. Defaults to 200. The actor stops early once this many users have been saved, even if keywords remain.

## `minimumFollowers` (type: `integer`):

Excludes users with fewer than this many followers, e.g., 10000 keeps accounts with 10K or more. Defaults to 0, which keeps everyone. Use with maximumFollowers to define an audience-size band.

## `maximumFollowers` (type: `integer`):

Excludes users with more than this many followers, e.g., 100000 keeps accounts under 100K. Defaults to 0, which sets no upper bound. Useful for finding micro-influencers instead of celebrities.

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

Keeps only Instagram-verified accounts (blue check) in the results. Defaults to false so unverified niche accounts are included. Turn on when assembling brand-safe partnership shortlists.

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

Filters by Instagram account class: any keeps all, personal keeps non-professional profiles, business keeps business accounts, professional keeps creator and professional accounts. Defaults to any. Category detail for professional accounts is returned in the category field of each result.

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

Also saves private (locked) accounts when they match the keyword. Defaults to false because private accounts hide most public data. Turn on only when the username itself is the deliverable.

## `parseContacts` (type: `boolean`):

Extracts public email addresses and phone numbers found in each user's bio text and bio links into separate contact fields. Defaults to true; parsing is text-only and never guesses missing values. Contacts are optional nulls when a bio has none.

## `provider` (type: `string`):

Routes the keyword search through a specific data provider: auto uses ScrapeCreators native search and falls back to SociaVault Google site-search when blocked, scrapeCreators forces the native route only, sociaVault forces the Google site-search route only. Defaults to auto. Both providers return public data only and need no Instagram login.

## Actor input object example

```json
{
  "searchQueries": [
    "fitness coach"
  ],
  "maxResultsPerQuery": 20,
  "maxResults": 200,
  "minimumFollowers": 0,
  "maximumFollowers": 0,
  "verifiedOnly": false,
  "accountType": "any",
  "includePrivateProfiles": false,
  "parseContacts": true,
  "provider": "auto"
}
```

# Actor output Schema

## `users` (type: `string`):

No description

## `output` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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": [
        "fitness coach"
    ],
    "maxResultsPerQuery": 20,
    "maxResults": 200,
    "minimumFollowers": 0,
    "maximumFollowers": 0,
    "verifiedOnly": false,
    "accountType": "any",
    "includePrivateProfiles": false,
    "parseContacts": true,
    "provider": "auto"
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/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": ["fitness coach"],
    "maxResultsPerQuery": 20,
    "maxResults": 200,
    "minimumFollowers": 0,
    "maximumFollowers": 0,
    "verifiedOnly": False,
    "accountType": "any",
    "includePrivateProfiles": False,
    "parseContacts": True,
    "provider": "auto",
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/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": [
    "fitness coach"
  ],
  "maxResultsPerQuery": 20,
  "maxResults": 200,
  "minimumFollowers": 0,
  "maximumFollowers": 0,
  "verifiedOnly": false,
  "accountType": "any",
  "includePrivateProfiles": false,
  "parseContacts": true,
  "provider": "auto"
}' |
apify call khadinakbar/instagram-user-search-scraper --silent --output-dataset

```

## MCP server setup

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