# Instagram Scraper (`vortex_data/instagram-scraper`) Actor

Fast no-login Instagram scraper. Extract profiles, posts, reels, comments, hashtags, locations, tagged feeds and audio reels. Paste URLs or search by keyword — clean structured JSON. Works on any post age via 5-tier HTML fallback. Date filter, dedup, parallel race, residential proxy.

- **URL**: https://apify.com/vortex\_data/instagram-scraper.md
- **Developed by:** [VortexData](https://apify.com/vortex_data) (community)
- **Categories:** Social media, Automation, Developer tools
- **Stats:** 23 total users, 15 monthly users, 99.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.50 / 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

<h1>📸 Instagram Scraper</h1>

<p><strong>Turn Instagram links into a clean spreadsheet.</strong> Start with direct Instagram URLs. Public profile URLs, single post/reel URLs, comments on public post/reel URLs, and audio URLs work without login in normal Apify runs. Keyword Search, hashtag URLs, location URLs, <code>/username/reels/</code>, and tagged feeds require your own Instagram cookies because Instagram hides those endpoints from logged-out sessions.</p>

<p><em>Perfect for marketers, agencies, researchers, and anyone who needs Instagram data without writing code.</em></p>

<h2>🎯 What you can do</h2>

<table>
<tr>
<th width="30%">If you want to…</th>
<th>…paste this link</th>
</tr>
<tr>
<td>📊 <strong>Track a brand or creator</strong></td>
<td><code>instagram.com/<i>username</i>/</code> → choose Posts</td>
</tr>
<tr>
<td>🎬 <strong>Get just their Reels</strong></td>
<td><code>instagram.com/<i>username</i>/</code> → choose Reels; use <code>/reels/</code> only with cookies</td>
</tr>
<tr>
<td>📌 <strong>See where they're tagged</strong></td>
<td><code>instagram.com/<i>username</i>/tagged/</code> + your cookies</td>
</tr>
<tr>
<td>🔍 <strong>Analyse one specific post</strong></td>
<td><code>instagram.com/p/<i>shortcode</i>/</code> → choose Details</td>
</tr>
<tr>
<td>💬 <strong>Collect all comments</strong></td>
<td>Post URL → choose Comments</td>
</tr>
<tr>
<td>#️⃣ <strong>Monitor a trend / hashtag</strong></td>
<td><code>instagram.com/explore/tags/<i>tag</i>/</code> + your cookies</td>
</tr>
<tr>
<td>📍 <strong>Posts from a place</strong></td>
<td><code>instagram.com/explore/locations/<i>id</i>/</code> + your cookies</td>
</tr>
<tr>
<td>🎵 <strong>Find Reels using a song</strong></td>
<td><code>instagram.com/reels/audio/<i>id</i>/</code></td>
</tr>
<tr>
<td>🔎 <strong>Discover by keyword</strong></td>
<td>Type a keyword in <strong>Search</strong> and paste your own cookies</td>
</tr>
</table>

<h3>Choose the right input: no cookies vs cookies required</h3>

<table>
<tr>
<th>Feature</th>
<th>Cookies needed?</th>
<th>Use this input</th>
</tr>
<tr>
<td>Public profile posts / details, plus Reels via profile URL</td>
<td>No, usually</td>
<td>Paste <code>instagram.com/<i>username</i>/</code> and choose Posts, Reels, or Details</td>
</tr>
<tr>
<td>Single public post / reel details</td>
<td>No, usually</td>
<td>Paste <code>instagram.com/p/<i>shortcode</i>/</code> or <code>instagram.com/reel/<i>shortcode</i>/</code></td>
</tr>
<tr>
<td>Comments on a public post / reel</td>
<td>No, usually, but comment preview availability varies</td>
<td>Paste a post/reel URL and choose Comments</td>
</tr>
<tr>
<td>Audio URLs</td>
<td>No, usually</td>
<td>Paste <code>instagram.com/reels/audio/<i>id</i>/</code></td>
</tr>
<tr>
<td>Hashtag / location URLs</td>
<td><strong>Yes on Apify</strong></td>
<td>Paste the exact hashtag/location URL and your own cookies</td>
</tr>
<tr>
<td><code>/username/reels/</code> tab and tagged feeds</td>
<td><strong>Yes on Apify</strong></td>
<td>Paste the URL and your own cookies. For no-cookie Reels, try the profile URL and choose Reels.</td>
</tr>
<tr>
<td>Keyword Search</td>
<td><strong>Yes</strong></td>
<td>Fill Search and paste your own Instagram cookies</td>
</tr>
<tr>
<td>Private, age-limited, login-walled, or shadow-limited pages</td>
<td><strong>Yes</strong></td>
<td>Paste direct URLs and your own cookies</td>
</tr>
</table>

<p>If you paste a cookies-required URL without cookies, the actor now skips it before scraping and tells you exactly which input needs cookies. That is intentional: it avoids silent 0-result runs caused by Instagram's logged-out restrictions.</p>

<h3>Choose the right "What to extract" option</h3>

<table>
<tr>
<th>Input URL</th>
<th>Works with</th>
</tr>
<tr>
<td><code>instagram.com/<i>username</i>/</code></td>
<td>Posts, Reels, Details</td>
</tr>
<tr>
<td><code>instagram.com/<i>username</i>/reels/</code></td>
<td>Posts or Reels (returns reels), Details — requires cookies on Apify</td>
</tr>
<tr>
<td><code>instagram.com/<i>username</i>/tagged/</code></td>
<td>Posts, Reels — requires cookies on Apify</td>
</tr>
<tr>
<td><code>instagram.com/p/<i>shortcode</i>/</code>, <code>instagram.com/reel/<i>shortcode</i>/</code></td>
<td>Posts, Reels, Details, Comments</td>
</tr>
<tr>
<td><code>instagram.com/explore/tags/<i>tag</i>/</code></td>
<td>Posts, Reels, Details — requires cookies on Apify</td>
</tr>
<tr>
<td><code>instagram.com/explore/locations/<i>id</i>/</code></td>
<td>Posts, Reels, Details — requires cookies on Apify</td>
</tr>
<tr>
<td><code>instagram.com/reels/audio/<i>id</i>/</code></td>
<td>Posts or Reels (returns reels), Details</td>
</tr>
</table>

<p><strong>Comments only works with a single post or reel URL.</strong> If you choose Comments for a profile, hashtag, location, tagged feed, audio URL, or Search result, the actor will now stop early with a clear message instead of making a confusing zero-result run.</p>

---

<h2>🚀 Get started in 30 seconds</h2>

<ol>
<li>Click <strong>Start</strong> with the default input — you'll get 50 recent posts from <a href="https://www.instagram.com/humansofny/">@humansofny</a>.</li>
<li>Open the <strong>Dataset</strong> tab.</li>
<li>Click <strong>Export</strong> → choose <strong>Excel</strong>, <strong>CSV</strong>, or <strong>JSON</strong>.</li>
</ol>

<p>That's it. Open the file in your spreadsheet app and you have likes, comments, captions, dates, owners, image URLs, and more — ready to filter, sort, or chart.</p>

---

<h2>Use Instagram cookies when needed</h2>

<p>No-cookie mode is for public profile URLs, single post/reel URLs, comments on public post/reel URLs, and audio URLs. Cookies are required for <strong>Keyword Search</strong>, hashtag URLs, location URLs, <code>/username/reels/</code>, and tagged feeds on Apify. The actor uses its managed proxy automatically; there is nothing to configure. Open <strong>Instagram login cookies</strong> and paste your own browser Cookie header into <strong>Instagram cookies</strong>.</p>

<p><strong>Cookies are sensitive.</strong> They work like a temporary password for your Instagram browser session. Use only cookies from your own account, and do not share them with other people.</p>

<h3>How to copy cookies from Chrome or Edge</h3>

<ol>
<li>Open <a href="https://www.instagram.com/">instagram.com</a> in your browser and log in.</li>
<li>Open the exact Instagram profile, post, reel, hashtag, location, or tagged page you want to scrape.</li>
<li>Press <strong>F12</strong>, or right-click the page and choose <strong>Inspect</strong>.</li>
<li>Open the <strong>Network</strong> tab and enable <strong>Preserve log</strong> if you see it.</li>
<li>Refresh the Instagram page with <strong>Ctrl+R</strong>.</li>
<li>Click the main document request: <code>www.instagram.com</code>, or the request named like the username / page path. Do not click image, CSS, JavaScript, GraphQL, or analytics requests.</li>
<li>Open <strong>Headers</strong> → <strong>Request Headers</strong>.</li>
<li>Find <strong>Cookie</strong> and copy the whole value. Copy only the value after <code>Cookie:</code>, not the word <code>Cookie:</code>.</li>
<li>Paste it into <strong>Instagram cookies</strong> in the actor input.</li>
</ol>

<p>The simplest format is a normal Cookie header:</p>

<pre><code>sessionid=...; csrftoken=...; ds_user_id=...; mid=...</code></pre>

<p>If you cannot find <strong>Cookie</strong>, keep DevTools open on the <strong>Network</strong> tab and refresh again. Click the request whose Type is <strong>document</strong> / <strong>doc</strong>, then check <strong>Request Headers</strong>. Do not copy <code>Set-Cookie</code> from Response Headers.</p>

<h3>Alternative: Cookie-Editor export</h3>

<ol>
<li>Install a browser cookie export extension such as Cookie-Editor.</li>
<li>Open <code>instagram.com</code> while logged in.</li>
<li>Export cookies as JSON.</li>
<li>Paste the full JSON into <strong>Instagram cookies</strong>.</li>
</ol>

<p>The actor accepts Cookie header text, Cookie-Editor JSON, JSON objects, and Netscape cookie files. It hides cookie values in logs and only logs the cookie names it installed. For best results include <code>sessionid</code>, <code>csrftoken</code>, <code>ds_user_id</code>, and <code>mid</code>.</p>

---

<h2>💡 Real-world examples</h2>

<details>
<summary><strong>📈 Track 3 competitors' content for the last week</strong></summary>

<pre><code>{
    "directUrls": [
        "https://www.instagram.com/nike/",
        "https://www.instagram.com/adidas/",
        "https://www.instagram.com/puma/"
    ],
    "resultsType": "posts",
    "resultsLimit": 100,
    "onlyPostsNewerThan": "7 days"
}</code></pre>
You get every post each brand made in the last 7 days — likes, comments, captions, hashtags, and image URLs side by side.
</details>

<details>
<summary><strong>💬 Read every comment on a viral reel</strong></summary>

<pre><code>{
    "directUrls": ["https://www.instagram.com/reel/CXXXXXXX/"],
    "resultsType": "comments",
    "resultsLimit": 500
}</code></pre>
Perfect for sentiment analysis, customer feedback, or finding influencer mentions.
</details>

<details>
<summary><strong>🔥 Find trending posts under a hashtag (requires cookies)</strong></summary>

<pre><code>{
    "directUrls": ["https://www.instagram.com/explore/tags/summertravel/"],
    "resultsType": "posts",
    "resultsLimit": 200,
    "sessionCookies": "sessionid=...; csrftoken=...; ds_user_id=...; mid=..."
}</code></pre>
Hashtag URLs require your own Instagram cookies on Apify. Useful for content research, finding influencers, or spotting trends early.
</details>

<details>
<summary><strong>🌍 Discover top hashtags around a topic (requires cookies)</strong></summary>

<pre><code>{
    "search": "sustainable fashion",
    "searchType": "hashtag",
    "searchLimit": 5,
    "resultsType": "posts",
    "resultsLimit": 50,
    "sessionCookies": "sessionid=...; csrftoken=...; ds_user_id=...; mid=..."
}</code></pre>
Keyword Search requires your own Instagram cookies. The actor finds 5 matching hashtags, then scrapes 50 posts from each — 250 posts of fresh content for your niche.
</details>

<details>
<summary><strong>💼 Build a lead list from a location (requires cookies)</strong></summary>

<pre><code>{
    "directUrls": ["https://www.instagram.com/explore/locations/213131048/berlin-germany/"],
    "resultsType": "posts",
    "resultsLimit": 300,
    "sessionCookies": "sessionid=...; csrftoken=...; ds_user_id=...; mid=..."
}</code></pre>
Location URLs require your own Instagram cookies on Apify. Find local businesses and creators by scraping posts from a specific neighbourhood or city.
</details>

---

<h2>📊 What you get</h2>

<p>Every scraped record is one row in your spreadsheet. Below are the columns you can expect for each content type — open the section that matches what you're scraping.</p>

<details>
<summary><strong>🖼️ Posts & Reels</strong> — up to 37 columns</summary>

<p>Caption, hashtags, mentions, likes count, comments count, first comment, latest comments preview, timestamp, image URL, all image sizes (carousels included), video URL, video view count, video duration, accessibility caption, owner username, owner full name, owner profile picture, owner verification badge, location, tagged users, product type (post/reel/carousel), advertisement flag, comments-disabled flag, audio info, post URL, and more.</p>
</details>

<details>
<summary><strong>👤 Profile details</strong> — 45 columns</summary>

<p>Username, full name, biography, biography hashtags & mentions, bio links, external URL, followers count, follows count, posts count, verified badge, private flag, business account flag, professional account flag, category, business email, business phone, pronouns, profile picture (regular & HD), IGTV count, highlight reel count, has Reels, has Guides, joined recently flag, Facebook page, plus the <strong>12 most recent posts inline</strong>, latest IGTV videos, and related profiles.</p>
</details>

<details>
<summary><strong>💬 Comments</strong></summary>

<p>Comment id, post id, comment text, timestamp, likes count, replies count, author username, author id, author verification badge, author profile picture.</p>
</details>

<details>
<summary><strong>#️⃣ Hashtag details</strong></summary>

<p>Hashtag id, name, total posts count, subtitle, description, cover image, plus top posts and recent posts.</p>
</details>

<details>
<summary><strong>📍 Location details</strong></summary>

<p>Location id, name, slug, latitude, longitude, full address, phone, website, description, profile picture, plus top posts and recent posts at this location.</p>
</details>

<details>
<summary><strong>🎵 Audio track details</strong></summary>

<p>Audio id, title, artist, audio cluster id, explicit flag, original sound flag, duration, cover art.</p>
</details>

---

<h2>⚡ How fast is it</h2>

<table>
<tr>
<th>Job</th>
<th>Typical time</th>
</tr>
<tr><td>Profile with 50 recent posts</td><td>5–10 seconds</td></tr>
<tr><td>Profile with 1,000 posts (with date filter)</td><td>30–60 seconds</td></tr>
<tr><td>One recent post details</td><td>3–5 seconds</td></tr>
<tr><td>One older post (4+ years)</td><td>10–15 seconds</td></tr>
<tr><td>Hashtag with 100 posts</td><td>8–15 seconds</td></tr>
<tr><td>500 comments on one post</td><td>15–30 seconds</td></tr>
</table>

<p>Multiple URLs are scraped <strong>in parallel</strong> — adding more inputs barely slows things down.</p>

---

<h2>❓ Common questions</h2>

<details>
<summary><strong>Do I need an Instagram account to use this?</strong></summary>
<p>No. The actor uses only public Instagram data — the same data anyone can see in an incognito browser tab.</p>
</details>

<details>
<summary><strong>Do I need to configure proxy?</strong></summary>
<p>No. The actor uses its managed proxy automatically. The input does not expose proxy settings because users should only choose URLs, output type, limits, filters, and optional Instagram cookies.</p>
</details>

<details>
<summary><strong>What if some fields come back empty?</strong></summary>
<p>For some posts, Instagram doesn't expose every field publicly (especially for very old posts or private accounts). The actor uses a 5-tier fallback to fill in as much as possible. Captions, likes, comments, dates, and authors come back virtually always.</p>
</details>

<details>
<summary><strong>How is pricing calculated?</strong></summary>
<p>You pay for Apify platform usage (memory + compute time + proxy data). Typical runs are inexpensive — a profile with 50 posts is usually a few cents. Use the <strong>Overall cap</strong> input to put a hard limit on cost.</p>
</details>

<details>
<summary><strong>Can I run this on a schedule?</strong></summary>
<p>Yes. In the Apify Console, open the <strong>Schedules</strong> tab and add a cron expression. Useful for daily competitor tracking, weekly trend reports, or hourly hashtag monitoring.</p>
</details>

<details>
<summary><strong>Can I get the data through an API?</strong></summary>
<p>Yes. Apify provides a REST API and SDKs for Python, JavaScript, and others. See the <strong>API</strong> tab on the Actor page for ready-to-paste code snippets.</p>
</details>

<details>
<summary><strong>Is it legal to scrape Instagram?</strong></summary>
<p>Only public Instagram data is collected — the same data that's visible to any visitor. You're responsible for using the output in line with your local laws (especially GDPR if records contain personal data). For an in-depth take, see <a href="https://blog.apify.com/is-web-scraping-legal/">Apify's blog on web scraping legality</a>.</p>
</details>

---

<h2>🛠️ Troubleshooting</h2>

<table>
<tr>
<th>You see…</th>
<th>What to do</th>
</tr>
<tr>
<td><code>❌ No Instagram URLs to scrape</code></td>
<td>Paste at least one URL, or type a keyword in <strong>Search</strong>.</td>
</tr>
<tr>
<td><code>❌ The date filter is invalid</code></td>
<td>Use a calendar date like <code>2026-01-15</code> or a relative one like <code>7 days</code>, <code>2 months</code>, <code>1 year</code>.</td>
</tr>
<tr>
<td><code>🔒 Profile is private</code></td>
<td>Only public profile metadata is available. Posts can't be scraped from private accounts.</td>
</tr>
<tr>
<td><code>❌ Profile doesn't exist</code></td>
<td>Double-check the username spelling — Instagram is strict with case.</td>
</tr>
<tr>
<td><code>🛑 IP throttled by Instagram</code></td>
<td>Retry with a smaller limit or add your own Instagram cookies if the page is login-sensitive. The actor manages proxy internally.</td>
</tr>
<tr>
<td><code>⚠️ Done — saved 0 records</code></td>
<td>Open the run's <strong>Storage</strong> → <strong>Key-value store</strong> and copy <code>SUPPORT_DIAGNOSTICS</code>. Send that JSON with the run log in the <strong>Issues</strong> tab. It contains the URL type, selected options, proxy/cookie flags, and failure reason, but never raw cookies.</td>
</tr>
<tr>
<td><code>⚠️ Some fields empty</code></td>
<td>Normal for very old posts — Instagram doesn't ship full data publicly for posts older than a few years. Captions, likes, comments and dates still come through.</td>
</tr>
</table>

---

<h2>🤝 Need help or have feedback?</h2>

<p>If something doesn't work the way you expect, or you have an idea for a new feature, open an issue on the Actor's <strong>Issues</strong> tab. We read every report.</p>

<p align="center"><em>Built with care for marketers, researchers, and curious people.</em><br><em>Happy scraping! 📸</em></p>

# Actor input Schema

## `directUrls` (type: `array`):

Paste exact Instagram URLs here. This is the best place to start.

**No cookies needed in normal Apify runs**
- 👤 Public profile: `instagram.com/{username}/` — choose Posts, Reels, or Details
- 🖼️ Public post: `instagram.com/p/{shortcode}/` — choose Posts, Details, or Comments
- 🎞️ Public reel: `instagram.com/reel/{shortcode}/` — choose Reels, Details, or Comments
- 🎵 Audio page: `instagram.com/reels/audio/{audio_id}/` — choose Posts/Reels or Details

**Cookies required on Apify**
- 🔎 Keyword Search — use the Search field below and paste cookies
- #️⃣ Hashtag URL: `instagram.com/explore/tags/{tag}/`
- 📍 Location URL: `instagram.com/explore/locations/{id}/`
- 🎬 Reels tab URL: `instagram.com/{username}/reels/`
- 🏷️ Tagged URL: `instagram.com/{username}/tagged/`
- 🔒 Private, age-limited, login-walled, or hidden pages

If you paste a cookies-required URL without cookies, the actor will skip it before scraping and show a clear message instead of returning a confusing 0-result run.
## `resultsType` (type: `string`):

Choose the dataset you want.

**No-cookie combinations**
- Profile URL + Posts: recent public posts
- Profile URL + Reels: public reels when Instagram exposes them in the profile feed
- Profile URL + Details: profile information
- Post/Reel URL + Details: one post or reel
- Post/Reel URL + Comments: comments available from the public page preview
- Audio URL + Posts/Reels or Details: reels using that audio or audio details

**Cookies-required combinations**
- Hashtag URL + Posts/Reels/Details
- Location URL + Posts/Reels/Details
- `/username/reels/` + Posts/Reels/Details
- `/username/tagged/` + Posts/Reels
- Any Keyword Search result

**Important:** Comments works only with a direct post/reel URL: `/p/...`, `/reel/...`, or `/tv/...`.
## `resultsLimit` (type: `integer`):

Maximum records to extract from each URL. For example, with `100` and 2 profile URLs you'll get up to 200 posts.
## `maxTotalResults` (type: `integer`):

Optional hard cap on the **total** records emitted by this run, no matter how many URLs you provide. Use this to keep cost predictable — e.g. set `1000` to never spend more than 1000 records' worth of credit. Leave empty for no overall cap.
## `onlyPostsNewerThan` (type: `string`):

Optional date filter — skip posts older than this. The actor stops paging as soon as it crosses the cutoff, which makes the run faster.

**Accepted formats**
- `2026-01-15` (calendar date, UTC)
- `2026-01-15T10:00:00Z` (full ISO time)
- `1 day`, `2 weeks`, `3 months`, `1 year` (relative)
## `addParentData` (type: `boolean`):

If you scrape multiple sources at once, turn this on to add a `dataSource` field to every record (`profile`, `hashtag`, `location`, `post`, or `comments`) plus the parent username / tag / location id. Useful when merging results in a spreadsheet.
## `dedupResults` (type: `boolean`):

When the same post appears in multiple sources (e.g. a hashtag feed and the author's profile), keep only the first one. Recommended.
## `sessionCookies` (type: `string`):

Leave empty when scraping only:
- public profile URLs;
- public post/reel URLs;
- comments on a public post/reel URL;
- audio URLs.

Paste your own Instagram cookies when using:
- Keyword Search;
- hashtag URLs;
- location URLs;
- `/username/reels/` URLs;
- `/username/tagged/` URLs;
- private, age-limited, login-walled, or hidden pages.

**How to copy cookies from Chrome / Edge**
1. Open `instagram.com` and log in to your own account.
2. Open the Instagram page you want to scrape, or open Instagram search if you want Keyword Search.
3. Press `F12`, or right-click the page and choose **Inspect**.
4. Open the **Network** tab and enable **Preserve log** if it is available.
5. Refresh the Instagram page with `Ctrl+R`.
6. Click the main document request: `www.instagram.com` or the request named like the username / page path. Do not click image, CSS, JavaScript, GraphQL, or analytics requests.
7. Open **Headers** -> **Request Headers**.
8. Find **Cookie** and copy the full value. Copy only the value after `Cookie:`, not the word `Cookie:`.
9. Paste that value here.

Correct format:
`sessionid=...; csrftoken=...; ds_user_id=...; mid=...`

If you cannot find **Cookie**, keep DevTools open on Network, refresh again, click the request with Type `document` / `doc`, and check **Request Headers**. Do not copy `Set-Cookie` from Response Headers.

You can also paste JSON from Cookie-Editor or a Netscape cookie export. Cookies are sensitive and work like a password: use only your own Instagram account cookies and do not share them.
## `search` (type: `string`):

Leave this empty for no-cookie runs.

Use Search only when you also paste your own Instagram cookies above. Instagram blocks logged-out keyword search.

Examples: `travel`, `nasa`, `musk`.
## `searchType` (type: `string`):

Only used when Search query is filled and Instagram cookies are provided. Ignored for direct URLs.
## `searchLimit` (type: `integer`):

How many profiles, hashtags, or places to take from Search. Direct URLs do not use this setting.
## `concurrency` (type: `integer`):

How many URLs to scrape at the same time. Higher = faster, but more likely to hit rate limits.
## `requestRetryBudget` (type: `integer`):

If a single request fails (network blip, 500, 429), how many times to retry it before giving up. Each retry uses a fresh IP.
## `urlRetryBudget` (type: `integer`):

How many failed pages we'll tolerate inside one URL (e.g. while paginating through 1,000 posts) before skipping that URL.
## `globalRateLimitBudget` (type: `integer`):

Total 429 (rate-limit) responses allowed across the whole run before the actor aborts. Stops runaway costs if Instagram is blocking us hard.

## Actor input object example

```json
{
  "directUrls": [
    "https://www.instagram.com/humansofny/",
    "https://www.instagram.com/p/C3TTthZLoQK/"
  ],
  "resultsType": "posts",
  "resultsLimit": 10,
  "addParentData": false,
  "dedupResults": true,
  "searchType": "hashtag",
  "searchLimit": 10,
  "concurrency": 4,
  "requestRetryBudget": 3,
  "urlRetryBudget": 5,
  "globalRateLimitBudget": 50
}
````

# Actor output Schema

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

Open the dataset to browse, filter, or export the results (CSV, Excel, JSON, HTML).

# 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 = {
    "directUrls": [
        "https://www.instagram.com/humansofny/",
        "https://www.instagram.com/p/C3TTthZLoQK/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vortex_data/instagram-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 = { "directUrls": [
        "https://www.instagram.com/humansofny/",
        "https://www.instagram.com/p/C3TTthZLoQK/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vortex_data/instagram-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 '{
  "directUrls": [
    "https://www.instagram.com/humansofny/",
    "https://www.instagram.com/p/C3TTthZLoQK/"
  ]
}' |
apify call vortex_data/instagram-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Instagram Scraper",
        "description": "Fast no-login Instagram scraper. Extract profiles, posts, reels, comments, hashtags, locations, tagged feeds and audio reels. Paste URLs or search by keyword — clean structured JSON. Works on any post age via 5-tier HTML fallback. Date filter, dedup, parallel race, residential proxy.",
        "version": "1.0",
        "x-build-id": "TaS29VJuwczCXdtOo"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/vortex_data~instagram-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-vortex_data-instagram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/vortex_data~instagram-scraper/runs": {
            "post": {
                "operationId": "runs-sync-vortex_data-instagram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/vortex_data~instagram-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-vortex_data-instagram-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "directUrls": {
                        "title": "1️⃣ Paste Instagram URLs here",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Paste exact Instagram URLs here. This is the best place to start.\n\n**No cookies needed in normal Apify runs**\n- 👤 Public profile: `instagram.com/{username}/` — choose Posts, Reels, or Details\n- 🖼️ Public post: `instagram.com/p/{shortcode}/` — choose Posts, Details, or Comments\n- 🎞️ Public reel: `instagram.com/reel/{shortcode}/` — choose Reels, Details, or Comments\n- 🎵 Audio page: `instagram.com/reels/audio/{audio_id}/` — choose Posts/Reels or Details\n\n**Cookies required on Apify**\n- 🔎 Keyword Search — use the Search field below and paste cookies\n- #️⃣ Hashtag URL: `instagram.com/explore/tags/{tag}/`\n- 📍 Location URL: `instagram.com/explore/locations/{id}/`\n- 🎬 Reels tab URL: `instagram.com/{username}/reels/`\n- 🏷️ Tagged URL: `instagram.com/{username}/tagged/`\n- 🔒 Private, age-limited, login-walled, or hidden pages\n\nIf you paste a cookies-required URL without cookies, the actor will skip it before scraping and show a clear message instead of returning a confusing 0-result run.",
                        "items": {
                            "type": "string",
                            "pattern": "^https?://(www\\.)?instagram\\.com/"
                        }
                    },
                    "resultsType": {
                        "title": "2️⃣ Choose what you want",
                        "enum": [
                            "posts",
                            "reels",
                            "details",
                            "comments"
                        ],
                        "type": "string",
                        "description": "Choose the dataset you want.\n\n**No-cookie combinations**\n- Profile URL + Posts: recent public posts\n- Profile URL + Reels: public reels when Instagram exposes them in the profile feed\n- Profile URL + Details: profile information\n- Post/Reel URL + Details: one post or reel\n- Post/Reel URL + Comments: comments available from the public page preview\n- Audio URL + Posts/Reels or Details: reels using that audio or audio details\n\n**Cookies-required combinations**\n- Hashtag URL + Posts/Reels/Details\n- Location URL + Posts/Reels/Details\n- `/username/reels/` + Posts/Reels/Details\n- `/username/tagged/` + Posts/Reels\n- Any Keyword Search result\n\n**Important:** Comments works only with a direct post/reel URL: `/p/...`, `/reel/...`, or `/tv/...`.",
                        "default": "posts"
                    },
                    "resultsLimit": {
                        "title": "🔢 Results per URL",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum records to extract from each URL. For example, with `100` and 2 profile URLs you'll get up to 200 posts.",
                        "default": 10
                    },
                    "maxTotalResults": {
                        "title": "💸 Max total results (cost safety)",
                        "minimum": 1,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Optional hard cap on the **total** records emitted by this run, no matter how many URLs you provide. Use this to keep cost predictable — e.g. set `1000` to never spend more than 1000 records' worth of credit. Leave empty for no overall cap."
                    },
                    "onlyPostsNewerThan": {
                        "title": "📅 Only newer than",
                        "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])(T[0-2]\\d:[0-5]\\d(:[0-5]\\d)?(\\.\\d+)?Z?)?$|^\\d+\\s*(minute|hour|day|week|month|year)s?$",
                        "type": "string",
                        "description": "Optional date filter — skip posts older than this. The actor stops paging as soon as it crosses the cutoff, which makes the run faster.\n\n**Accepted formats**\n- `2026-01-15` (calendar date, UTC)\n- `2026-01-15T10:00:00Z` (full ISO time)\n- `1 day`, `2 weeks`, `3 months`, `1 year` (relative)"
                    },
                    "addParentData": {
                        "title": "🏷️ Add source info to each result",
                        "type": "boolean",
                        "description": "If you scrape multiple sources at once, turn this on to add a `dataSource` field to every record (`profile`, `hashtag`, `location`, `post`, or `comments`) plus the parent username / tag / location id. Useful when merging results in a spreadsheet.",
                        "default": false
                    },
                    "dedupResults": {
                        "title": "🧹 Remove duplicate posts",
                        "type": "boolean",
                        "description": "When the same post appears in multiple sources (e.g. a hashtag feed and the author's profile), keep only the first one. Recommended.",
                        "default": true
                    },
                    "sessionCookies": {
                        "title": "🔐 Instagram cookies (only for locked features)",
                        "type": "string",
                        "description": "Leave empty when scraping only:\n- public profile URLs;\n- public post/reel URLs;\n- comments on a public post/reel URL;\n- audio URLs.\n\nPaste your own Instagram cookies when using:\n- Keyword Search;\n- hashtag URLs;\n- location URLs;\n- `/username/reels/` URLs;\n- `/username/tagged/` URLs;\n- private, age-limited, login-walled, or hidden pages.\n\n**How to copy cookies from Chrome / Edge**\n1. Open `instagram.com` and log in to your own account.\n2. Open the Instagram page you want to scrape, or open Instagram search if you want Keyword Search.\n3. Press `F12`, or right-click the page and choose **Inspect**.\n4. Open the **Network** tab and enable **Preserve log** if it is available.\n5. Refresh the Instagram page with `Ctrl+R`.\n6. Click the main document request: `www.instagram.com` or the request named like the username / page path. Do not click image, CSS, JavaScript, GraphQL, or analytics requests.\n7. Open **Headers** -> **Request Headers**.\n8. Find **Cookie** and copy the full value. Copy only the value after `Cookie:`, not the word `Cookie:`.\n9. Paste that value here.\n\nCorrect format:\n`sessionid=...; csrftoken=...; ds_user_id=...; mid=...`\n\nIf you cannot find **Cookie**, keep DevTools open on Network, refresh again, click the request with Type `document` / `doc`, and check **Request Headers**. Do not copy `Set-Cookie` from Response Headers.\n\nYou can also paste JSON from Cookie-Editor or a Netscape cookie export. Cookies are sensitive and work like a password: use only your own Instagram account cookies and do not share them."
                    },
                    "search": {
                        "title": "🔎 Keyword Search (cookies required)",
                        "type": "string",
                        "description": "Leave this empty for no-cookie runs.\n\nUse Search only when you also paste your own Instagram cookies above. Instagram blocks logged-out keyword search.\n\nExamples: `travel`, `nasa`, `musk`."
                    },
                    "searchType": {
                        "title": "🎯 Search target",
                        "enum": [
                            "hashtag",
                            "profile",
                            "place"
                        ],
                        "type": "string",
                        "description": "Only used when Search query is filled and Instagram cookies are provided. Ignored for direct URLs.",
                        "default": "hashtag"
                    },
                    "searchLimit": {
                        "title": "🔢 Search matches to scrape",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "How many profiles, hashtags, or places to take from Search. Direct URLs do not use this setting.",
                        "default": 10
                    },
                    "concurrency": {
                        "title": "⚡ Speed: parallel URLs",
                        "minimum": 1,
                        "maximum": 32,
                        "type": "integer",
                        "description": "How many URLs to scrape at the same time. Higher = faster, but more likely to hit rate limits.",
                        "default": 4
                    },
                    "requestRetryBudget": {
                        "title": "🔁 Retries per request",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "If a single request fails (network blip, 500, 429), how many times to retry it before giving up. Each retry uses a fresh IP.",
                        "default": 3
                    },
                    "urlRetryBudget": {
                        "title": "🔁 Retries per URL",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "integer",
                        "description": "How many failed pages we'll tolerate inside one URL (e.g. while paginating through 1,000 posts) before skipping that URL.",
                        "default": 5
                    },
                    "globalRateLimitBudget": {
                        "title": "🛑 Stop after too many rate limits",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Total 429 (rate-limit) responses allowed across the whole run before the actor aborts. Stops runaway costs if Instagram is blocking us hard.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
