# Instagram Popular Search Scraper (`fetch_cat/instagram-search-scraper`) Actor

Export public Instagram popular-topic search results for keywords, including topics, reels, posts, profiles, hashtags, and per-query status.

- **URL**: https://apify.com/fetch\_cat/instagram-search-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 instagram search item saveds

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 Search Scraper

Instagram Search Scraper exports public Instagram popular-topic search results for one or more keywords. Use it to monitor topic pages, collect public reels/posts/profile links, export Instagram search data, and feed social listening or creator research dashboards when Instagram exposes the data on logged-out public pages.

This Actor is intentionally scoped to the confirmed public `/popular/<topic>/` route. It does not require Instagram login and does not claim private, authenticated, business, place, or full blended Instagram search data.

### Ready-to-run examples

Start from these verified public Apify task examples:

- [Instagram travel topic search](https://apify.com/fetch_cat/instagram-search-scraper/examples/instagram-travel-topic-search) — collect public topic, reel, post, and profile signals for travel search research.
- [Instagram fitness reels search](https://apify.com/fetch_cat/instagram-search-scraper/examples/instagram-fitness-reels-search) — export public search results for fitness reels discovery.
- [Instagram skincare trend monitor](https://apify.com/fetch_cat/instagram-search-scraper/examples/instagram-skincare-trend-monitor) — monitor public skincare topic results for trend analysis.
- [Instagram creator economy export](https://apify.com/fetch_cat/instagram-search-scraper/examples/instagram-creator-economy-export) — build a small creator-economy topic dataset for dashboards or API pipelines.
- [Instagram coffee recipes search](https://apify.com/fetch_cat/instagram-search-scraper/examples/instagram-coffee-recipes-search) — collect public Instagram search results for coffee recipe content research.

### What it collects

For each keyword the Actor can save:

- Topic records with title, slug, URL, description/snippet, related topics, and reel counts when exposed
- Public reel and post URLs with shortcodes
- Public profile URLs/usernames when exposed on the topic page
- Hashtags, mentions, thumbnail/media URLs, accessibility text, and public engagement counts when present
- Transparent source/result status on saved dataset rows, with full per-keyword `succeeded`, `empty`, or `failed` diagnostics in the `QUERY_STATUS` key-value-store record

### Input

- `keywords` — Instagram popular-topic keywords, for example `travel` or `ceramic mugs`.
- `maxItems` — maximum records across the whole run.
- `maxItemsPerKeyword` — maximum records saved for each keyword.
- `maxRetries` — retry count with fresh proxy sessions/backoff for transient blocks.
- `locale` — `Accept-Language` header.
- `proxyConfiguration` — Apify Proxy settings. The default SHADER proxy group is the lowest-cost verified route; use Residential only if Instagram blocks your keywords.

### Input recipes

#### Monitor two topics

```json
{
  "keywords": ["travel", "ceramic mugs"],
  "maxItems": 100,
  "maxItemsPerKeyword": 50,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["SHADER"] }
}
```

#### Small test run

```json
{
  "keywords": ["fitness reels"],
  "maxItems": 20,
  "maxItemsPerKeyword": 20
}
```

#### Scheduled monitoring run

```json
{
  "keywords": ["summer skincare", "trail running", "coffee recipes"],
  "maxItems": 90,
  "maxItemsPerKeyword": 30,
  "locale": "en-US,en;q=0.9",
  "maxRetries": 3,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["SHADER"] }
}
```

Use this pattern for daily or weekly monitoring. Keep each keyword specific enough that the topic page has a clear intent, and set `maxItemsPerKeyword` to the number of new public records your dashboard can review. If one keyword is much broader than the others, split it into a separate schedule so it cannot consume the whole run limit.

#### API pipeline run

```json
{
  "keywords": ["creator economy", "instagram reels tips"],
  "maxItems": 50,
  "maxItemsPerKeyword": 25,
  "locale": "en-US"
}
```

Use this lighter input when an external app starts runs through the Apify API and downloads the dataset after completion. The output keeps enough context to join records back to the source keyword without parsing the run input again.

### Output

Dataset items include fields such as `sourceKeyword`, `queryStatus`, `rank`, `resultType`, `topicTitle`, `topicSlug`, `topicUrl`, `url`, `shortcode`, `username`, `profileUrl`, `captionText`, `hashtags`, `mentions`, `viewCount`, `playCount`, `likeCount`, `commentCount`, `thumbnailUrls`, `mediaUrls`, `sourcePage`, and `scrapedAt`.

The Actor also writes `QUERY_STATUS` to the key-value store so you can see which keywords succeeded, returned no items, or failed after retries. Dataset rows carry their source/result status, while full per-keyword diagnostics live in `QUERY_STATUS`.

#### Example dataset item

```json
{
  "sourceKeyword": "travel",
  "queryStatus": "succeeded",
  "rank": 1,
  "resultType": "topic",
  "topicTitle": "Travel",
  "topicSlug": "travel",
  "topicUrl": "https://www.instagram.com/popular/travel/",
  "topicDescription": "Public Instagram topic page exposed for this keyword.",
  "topicReelCount": null,
  "relatedTopics": ["adventure", "vacation"],
  "url": "https://www.instagram.com/popular/travel/",
  "shortcode": null,
  "username": null,
  "profileUrl": null,
  "captionText": null,
  "hashtags": ["travel"],
  "mentions": [],
  "viewCount": null,
  "playCount": null,
  "likeCount": null,
  "commentCount": null,
  "thumbnailUrls": ["https://instagram.example/cdn/thumb.jpg"],
  "mediaUrls": [],
  "accessibilityText": null,
  "sourcePage": "https://www.instagram.com/popular/travel/",
  "scrapedAt": "2026-08-01T00:00:00.000Z"
}
```

#### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `sourceKeyword` | string | Keyword from the run input that produced the row. |
| `queryStatus` | string | Row-level status for saved dataset rows. Dataset rows are emitted only for successful keyword queries, so this value is always `succeeded`. Empty, failed, and skipped keyword diagnostics live in the `QUERY_STATUS` key-value-store record. |
| `rank` | integer / null | Order of the record within the source keyword results. |
| `resultType` | string | Normalized record type such as topic, reel, post, profile, or hashtag. |
| `topicTitle`, `topicSlug`, `topicUrl`, `topicDescription`, `topicReelCount` | mixed | Public topic metadata when Instagram exposes it. |
| `relatedTopics` | string\[] | Related public topics found on the source page. |
| `url`, `shortcode` | string / null | Result URL and Instagram shortcode when available. |
| `username`, `profileUrl` | string / null | Public creator/profile hints exposed near the result. |
| `captionText`, `hashtags`, `mentions`, `accessibilityText` | mixed | Text-analysis fields extracted from public page content. |
| `viewCount`, `playCount`, `likeCount`, `commentCount` | integer / null | Optional public counters; missing means not exposed, not zero. |
| `thumbnailUrls`, `mediaUrls` | string\[] | Public media URLs observed on the page. |
| `sourcePage` | string | Instagram popular-topic page requested for the keyword. |
| `scrapedAt` | string | ISO timestamp when the row was saved. |

#### `QUERY_STATUS` key-value-store record

```json
{
  "statuses": [
    {
      "sourceKeyword": "travel",
      "status": "succeeded",
      "itemCount": 20,
      "error": null,
      "sourcePage": "https://www.instagram.com/popular/travel/"
    },
    {
      "sourceKeyword": "ceramic mugs",
      "status": "empty",
      "itemCount": 0,
      "error": "No clean per-card records found",
      "sourcePage": "https://www.instagram.com/popular/ceramic mugs/"
    }
  ],
  "summary": {
    "saved": 20,
    "failed": 0,
    "skipped": 0,
    "remaining": 0,
    "completed": 2,
    "pending": 0,
    "pendingKeywords": []
  }
}
```

#### Output field guide

Use these groups when mapping the dataset into a warehouse, CRM, or monitoring dashboard:

- **Run context** — `sourceKeyword`, `queryStatus`, `rank`, `sourcePage`, and `scrapedAt` identify which search produced the row and when it was collected.
- **Result identity** — `resultType`, `url`, `shortcode`, `topicSlug`, and `topicUrl` help deduplicate records across repeated scheduled runs.
- **Topic metadata** — `topicTitle`, `topicDescription`, `relatedTopics`, and exposed reel counts describe the public topic page when Instagram includes those blocks.
- **Creator/profile hints** — `username` and `profileUrl` are saved when the public page exposes a profile link near a reel, post, or topic result.
- **Text analysis fields** — `captionText`, `hashtags`, `mentions`, and accessibility text are suitable for lightweight keyword matching, brand-safety review, and enrichment.
- **Media fields** — `thumbnailUrls` and `mediaUrls` are public URLs observed on the page; download them promptly if your workflow needs long-term media evidence.
- **Engagement fields** — `viewCount`, `playCount`, `likeCount`, and `commentCount` are optional public counters. Missing values mean Instagram did not expose the counter, not that the count is zero.

For recurring jobs, deduplicate first by `url`, then by `shortcode` when present. Keep `sourceKeyword` even after deduplication so you can explain why a record entered the dataset. If you merge multiple runs, prefer the most recent `scrapedAt` for volatile engagement counters and keep older snapshots when you need trend history.

### Who is it for

Instagram Search Scraper is useful for teams that need repeatable exports from public Instagram topic discovery pages:

- Social listening teams tracking topic clusters and emerging public reels
- Creator intelligence teams collecting public profile and post links for enrichment
- Brand monitoring teams watching public Instagram topic pages around products or campaigns
- Agencies building weekly dashboards from Instagram search records
- Researchers who need timestamped, repeatable public search snapshots

### API usage

Use this as an Instagram search API from the Apify API, schedules, integrations, or MCP clients. Send the same JSON input you use in Console and export the dataset as JSON, CSV, Excel, XML, or RSS.

#### Node.js

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/instagram-search-scraper').call({
  keywords: ['travel', 'ceramic mugs'],
  maxItems: 20,
  maxItemsPerKeyword: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/instagram-search-scraper').call(run_input={
    'keywords': ['travel', 'ceramic mugs'],
    'maxItems': 20,
    'maxItemsPerKeyword': 10,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~instagram-search-scraper/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"keywords":["travel","ceramic mugs"],"maxItems":20,"maxItemsPerKeyword":10}'
```

After the run finishes, download results from the default dataset endpoint in JSON, CSV, Excel, XML, or RSS.

### MCP and AI-agent setup

You can call this Actor from AI agents through the official focused Apify MCP endpoint:

```text
https://mcp.apify.com?tools=fetch_cat/instagram-search-scraper
```

#### Claude CLI / Claude Code

Add the focused Apify MCP server from a terminal and pass your Apify token as an Authorization header:

```bash
claude mcp add apify-instagram-search -- npx mcp-remote "https://mcp.apify.com?tools=fetch_cat/instagram-search-scraper" --header "Authorization: Bearer <YOUR_API_TOKEN>"
```

Pass the `Authorization: Bearer <YOUR_API_TOKEN>` header to `mcp-remote`; setting `APIFY_TOKEN` alone does not send that header to the MCP endpoint.

#### Claude Desktop configuration

Add an MCP server entry that points to the focused Apify MCP URL and passes your Apify API token as an Authorization header:

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

Example prompts:

- "Run Instagram Search Scraper for `travel` and `ceramic mugs`, limit to 20 results total, then summarize the top result types."
- "Check the `QUERY_STATUS` record for my latest Instagram Search Scraper run and tell me which keywords returned no public data."
- "Export the dataset as JSON and group results by source keyword."

### Pricing and limits

The Actor uses pay-per-event pricing: a small start event plus a per-item event for each dataset row produced. Set `maxItems` and `maxItemsPerKeyword` to control cost. See the live Apify [Pricing tab](https://apify.com/fetch_cat/instagram-search-scraper/pricing) for current rates.

Very large or heavily throttled keyword batches may need more retries or smaller batches. For predictable costs, start with 10-20 items per keyword, review the dataset, then increase the limits once you confirm the topic returns useful public results.

### Related Actors

#### More Instagram scrapers

- [Instagram Profile & Posts Scraper](https://apify.com/fetch_cat/instagram-profile-posts-scraper)
- [Instagram Stories & Highlights Scraper](https://apify.com/fetch_cat/instagram-stories-highlights-scraper)
- [Instagram Post Details Scraper](https://apify.com/fetch_cat/instagram-post-details-scraper)
- [Instagram Reel Scraper](https://apify.com/fetch_cat/instagram-reel-scraper)

For adjacent public Instagram workflows, review [Instagram Profile Posts Scraper](https://apify.com/fetch_cat/instagram-profile-posts-scraper) for profile post exports, [Instagram Reel Scraper](https://apify.com/fetch_cat/instagram-reel-scraper) for reel-first monitoring, or [Instagram Post Details Scraper](https://apify.com/fetch_cat/instagram-post-details-scraper) when you already have post or reel URLs and need deeper public post details.

### Workflow tips

- Use one keyword per buyer intent, campaign, topic cluster, or competitor category.
- Keep `maxItemsPerKeyword` small for scheduled monitoring so each run finishes quickly.
- Use `QUERY_STATUS` to alert on keywords that were throttled or returned no public records.
- Export CSV for spreadsheets and JSON for enrichment pipelines.
- Store run IDs in your dashboard so Support can help investigate unexpected changes.

### Data quality checks

Each saved row includes `sourceKeyword`, `queryStatus`, `rank`, `resultType`, `url`, and `scrapedAt` so downstream systems can filter partial data safely. Optional fields such as captions, hashtags, mentions, thumbnails, media URLs, and engagement counts are populated only when Instagram exposes them on the public page.

Recommended validation after each scheduled run:

1. Confirm saved rows have `queryStatus: "succeeded"`; complete per-keyword `succeeded`, `empty`, `failed`, or `skipped` diagnostics live in the `QUERY_STATUS` key-value-store record.
2. Check how many dataset rows each keyword produced.
3. Deduplicate by `url` or `shortcode` before merging with historical exports.
4. Treat missing optional engagement metrics as unavailable public data, not zero.
5. Review source URLs before using the data in customer-facing reports.

### Notes and limitations

Instagram can throttle or change public pages. The Actor preserves partial output when one keyword fails and records per-keyword errors in the `QUERY_STATUS` key-value-store record instead of hiding missing data. Fields are only populated when available on public logged-out pages.

### FAQ

#### What data can I export?

You can export public topic, reel, post, profile, hashtag, media-link, engagement-count, and per-query status fields when they are exposed on logged-out Instagram popular-topic pages.

#### Can I run Instagram Popular Search Scraper through an API, schedule, or MCP client?

Yes. Use Apify API, schedules, integrations, or MCP clients with the same JSON input shown above.

#### How much does it cost to use Instagram Popular Search Scraper?

The Actor uses pay-per-event pricing: one start event plus one item event for each saved dataset row. Use `maxItems` and `maxItemsPerKeyword` to cap spend before running broad keyword batches.

#### Does it scrape private or logged-in Instagram data?

No. This Actor only uses public logged-out pages and does not collect private, authenticated, or account-only fields.

### Support

If a run fails or a keyword returns fewer rows than expected, open an Apify issue and include:

- The run ID or run URL
- The exact input JSON
- Expected output versus actual output
- One reproducible public Instagram topic URL, if available
- Any relevant `QUERY_STATUS` details from the key-value-store record

The `QUERY_STATUS` record usually shows whether Instagram throttled the request or returned no public data.

# Actor input Schema

## `keywords` (type: `array`):

Instagram popular topic keywords to fetch, e.g. travel, ceramic mugs, fitness reels.

## `maxItems` (type: `integer`):

Maximum total dataset records to save across all keywords.

## `maxItemsPerKeyword` (type: `integer`):

Maximum records to save for each keyword before moving to the next one.

## `maxRetries` (type: `integer`):

Retry count with fresh proxy sessions/backoff for transient 429, 403, or 5xx responses.

## `locale` (type: `string`):

Locale header used for public Instagram pages.

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

Use Apify Proxy for fresh-session rotation. The default SHADER group is the cheapest verified route; switch to Residential only if your keywords are blocked.

## Actor input object example

```json
{
  "keywords": [
    "travel"
  ],
  "maxItems": 20,
  "maxItemsPerKeyword": 20,
  "maxRetries": 3,
  "locale": "en-US,en;q=0.9",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "SHADER"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `queryStatus` (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 = {
    "keywords": [
        "travel"
    ]
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dnbwAdc6RGXZZ2pfb/builds/iZih4FxRqGPrlXDWv/openapi.json
