# Instagram Post Scraper: Posts, Comments, Reels (`deepmine/instagram-post-scraper`) Actor

Instagram post scraper: paste usernames, profile URLs or post URLs and get one row per post with caption, hashtags, likes, comments count and latest comments, date, images, video URL, reel plays, tagged users, coauthors, music and location. Goes past 12 posts. No login, no cookies.

- **URL**: https://apify.com/deepmine/instagram-post-scraper.md
- **Developed by:** [DeepMine](https://apify.com/deepmine) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 posts

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Post Scraper: Posts, Comments, Reels

Instagram post scraper for any public profile or post: paste usernames, profile URLs or post URLs and get one row per post with its caption, hashtags, likes, comments count and latest comments, date, pictures, video, reel plays, tagged users, coauthors, music and location. It pages past the 12 posts a profile shows first, and it never logs in.

| 🏷️ Username | 📝 Caption | ❤️ Likes | 💬 Comments | ▶️ Plays | 📅 Posted |
|---|---|---|---|---|---|
| astro_jessica | Room with a view. Check out my new digs as I camp… | 221,491 | 2,299 | 5,608,770 | 2026-10-03 |
| nasa | Swipe for countless stars Sagittarius B2 is the m… | 1,121,996 | 4,365 | – | 2026-10-02 |
| natgeo | Your phone isn’t rotting your brain—but cell deat… | 72,503 | 218 | – | 2025-06-22 |

<sub>Collected 2026-10-12.</sub>

**$0.69 per 1,000 posts** on the Starter plan ($0.79 Free, $0.59 Scale, $0.49 Business). The prefilled run (41 posts) costs about $0.028 ($0.032 on Free). No start fee, no extra charge for comments, alt text, reel plays, video views or music: Detailed data is the default and is included.

### What it does

- **Instagram posts by username or profile URL**: the newest posts of each profile, pinned ones first as on Instagram, page after page (12 posts a page) up to your `resultsLimit`, or back to a date with `onlyPostsNewerThan`.
- **Any post URL**: `/p/`, `/reel/` and `/tv/` links, one row each, mixed freely with usernames in the same list.
- **Detailed data by default**: each post's latest comments as Instagram shows them on the post's page (usually 10-15, newest first), the post's alt text, reels' play counts, and every video's views (carousel videos too).
- **Same input as apify/instagram-post-scraper**: `username`, `resultsLimit`, `onlyPostsNewerThan`, `skipPinnedPosts`, `dataDetailLevel` and `includeMusicData` are read as they are, so a saved input or API call runs here unchanged.
- **Transcripts (optional, paid)**: turn on 🗣️ **Add transcripts** to get what's said in each video as text (`transcript`, `transcriptLanguage`): Instagram's own speech transcript, read without a login, for videos of any length. $0.0039 per video with a transcript; photos and silent videos aren't charged for it.
- **Every post once**: a post two of your inputs reach (a collab on two profiles, a URL you also listed) is delivered and charged once per run.

### How to use it

1. Paste usernames, profile URLs or post URLs into 📸 **Instagram profiles or posts**.
2. Set 💯 **Posts per profile** (20 in the prefill, 100 by default). Post URLs always give one row.
3. Optional: 📅 **Posts newer than** (`2026-09-01`, `7 days`, `3 months`), 📌 **Skip pinned posts**, 🔍 **Detail level** (Basic is faster: no comments, alt text, plays or views).
4. Press Start. Rows land as each page is read; download them as CSV, Excel or JSON, or call the Actor from the API.

Example input:

```json
{
  "username": [
    "natgeo",
    "https://www.instagram.com/nasa/",
    "https://www.instagram.com/p/DLNsnpUTdVS/"
  ],
  "resultsLimit": 20,
  "dataDetailLevel": "detailedData"
}
```

### Output

Each row is one post. The Console shows four views: 📸 Posts (picture, author, caption, likes, comments, plays, date, first comment), 📈 Stats (every count per post), 🎬 Media (video, audio, size, duration, artist and song, alt text) and 👥 People (tagged usernames, coauthors, mentions, hashtags, sponsors, location). Long texts show as 50-character snippets there; the rows keep the full text and apify's nested fields (`musicInfo`, `taggedUsers`, `sponsors`, `latestComments`) next to their flat columns. The run summary (OUTPUT) lists every input with its status, posts delivered and pages read.

#### Output fields

- `inputUrl`: The profile or post URL from your list this post came from (a username becomes https://www.instagram.com/<username>).
- `id`: Instagram's id for the post (its media id).
- `type`: Image, Video or Sidecar (a carousel).
- `shortCode`: The post's code in its URL (instagram.com/p/<code>/).
- `caption`: The post's caption text.
- `hashtags`: Hashtags in the caption, without #.
- `mentions`: @usernames in the caption, without @.
- `url`: The post's URL.
- `commentsCount`: Comments on the post.
- `firstComment`: The text of the first of latestComments (Detailed data).
- `latestComments`: Detailed data: the comments Instagram shows on the post's page to visitors who aren't logged in (usually 10-15, newest first), each with id, text, ownerUsername, ownerProfilePicUrl, timestamp, repliesCount, likesCount and owner (id, username, profile_pic_url, is_verified, plus full_name, is_private, is_mentionable, profile_pic_id, latest_reel_media and fbid_v2, null unless Instagram shows them logged out). Each also has media: a GIF comment's GIF URL (null for text).
- `dimensionsHeight`: The picture's or video's height in pixels.
- `dimensionsWidth`: The picture's or video's width in pixels.
- `originalHeight`: The height of the media as uploaded.
- `originalWidth`: The width of the media as uploaded.
- `displayUrl`: The post's picture (a video's cover), largest size.
- `images`: A carousel's pictures, in order.
- `alt`: Detailed data: the post's alt text (Instagram's own description of the picture, or the one its author wrote).
- `likesCount`: Likes on the post (null when its author hides the count).
- `videoViewCount`: Detailed data: a video's views, Instagram's view counter (lower than plays; the same number as apify's videoViewCount), from the video's embed page. A carousel's videos have theirs in childPosts. Null for pictures and in Basic data.
- `timestamp`: When the post went up (UTC, ISO 8601).
- `childPosts`: A carousel's items, each with its own id, type, picture, video URL, size, alt text, tagged users and tag positions (taggedUserPositions).
- `ownerFullName`: The author's display name.
- `ownerUsername`: The author's username.
- `ownerId`: The author's Instagram user id.
- `productType`: feed (a picture), carousel_container (a carousel), clips (a reel) or igtv.
- `isCommentsDisabled`: Comments are turned off; false when Instagram showed the post's comments (Detailed data), else null.
- `paidPartnership`: Marked as a paid partnership.
- `sponsors`: The brands of a paid partnership, each with id and username.
- `videoUrl`: The video file's URL (it expires after a few days).
- `taggedUsers`: Accounts tagged in the picture, each with full_name, id, is_verified, profile_pic_url and username.
- `coauthorProducers`: Collab coauthors, each with id, is_verified, profile_pic_url and username.
- `audioUrl`: A video's separate audio track (its DASH audio stream).
- `videoDuration`: A video's length in seconds.
- `musicInfo`: The post's sound: artist_name, song_name, uses_original_audio, should_mute_audio, should_mute_audio_reason, audio_id.
- `videoPlayCount`: Detailed data: a reel's plays, from its author's reels tab (for a profile, read back as far as the posts go, and for its pinned reels back to their date; for a reel URL, paged until the reel; at most 15 pages for a pinned reel or a URL). Null for videos that aren't reels.
- `isPinned`: Pinned to the top of the author's grid.
- `captionSnippet`: The caption's first 50 characters (… when cut), for the table views.
- `transcript`: What's said in the video, Instagram's own speech transcript (its auto-captions) as plain text, no timings; null for photos and videos without speech (Add transcripts, a paid add-on; the key comes only with it on).
- `transcriptLanguage`: The transcript's language (ISO 639-1: en, es, de, ...), null when it's too short to tell (Add transcripts).
- `firstCommentSnippet`: firstComment's first 50 characters (… when cut).
- `taggedUsernames`: The tagged accounts' usernames (taggedUsers as a flat list).
- `sponsorUsernames`: The paid partnership's brands' usernames (sponsors as a flat list).
- `musicArtist`: The sound's artist (musicInfo's artist_name; the author for original audio).
- `musicSong`: The sound's title (musicInfo's song_name; "Original audio" for the author's own).
- `coauthors`: The coauthors' usernames.
- `invitedCoauthors`: The usernames of invitedCoauthorProducers, as a flat list.
- `invitedCoauthorProducers`: Accounts invited to the collab that haven't accepted (yet), each with id, is_verified, profile_pic_url and username.
- `childPostsCount`: How many items a carousel has.
- `locationName`: The tagged location's name.
- `locationId`: The tagged location's Instagram id.
- `location`: The tagged place, every field Instagram sends: id, name, slug, lat, lng, address, city, zipCode, shortName, facebookPlacesId (null where Instagram leaves one out; a profile's grid sends id, name, lat and lng).
- `taggedUserPositions`: Every user tag with where it sits on the picture: username, id, x and y (0-1 from the top left). A user tagged twice comes twice; carousel items (childPosts) have their own.
- `ownerIsVerified`: The author has the verified badge.
- `ownerProfilePicUrl`: The author's profile picture.
- `likesHidden`: The author hides the like count.
- `sourceType`: profile (from a profile's grid) or post (a post URL you gave).
- `scrapedAt`: When the run read the post (UTC).

#### Example row

A real row (2026-10-12, its transcript read 2026-10-18 with Add transcripts on; long URLs and texts shortened, two comments shown with their authors anonymized):

```json
{
  "inputUrl": "https://www.instagram.com/nasa/",
  "id": "3999826868370149150",
  "type": "Video",
  "shortCode": "DeCPVhERA8e",
  "caption": "Room with a view. Check out my new digs as I camp out in Dragon until our departure. With Crew-13’s arrival we have a very full house on the @iss. Luke is living in my previous crew quarters, and I’ve pitched a tent in Dragon.",
  "hashtags": null,
  "mentions": [
    "iss"
  ],
  "url": "https://www.instagram.com/p/DeCPVhERA8e/",
  "commentsCount": 2299,
  "firstComment": "Some v sad people here",
  "latestComments": [
    {
      "id": "18146445475622410",
      "text": "Some v sad people here",
      "ownerUsername": "commenter_1",
      "ownerProfilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/commenter.jpg",
      "timestamp": "2026-10-12T18:11:33.000Z",
      "repliesCount": null,
      "replies": null,
      "likesCount": 0,
      "owner": {
        "id": "10000000",
        "username": "commenter_1",
        "profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/commenter.jpg",
        "is_verified": false,
        "full_name": null,
        "is_private": null,
        "is_mentionable": null,
        "profile_pic_id": null,
        "latest_reel_media": null,
        "fbid_v2": null
      },
      "media": null
    },
    {
      "id": "18107205227222240",
      "text": "Not one single star in the background 👽👽👽👽👽👽👽",
      "ownerUsername": "commenter_2",
      "ownerProfilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/commenter.jpg",
      "timestamp": "2026-10-12T17:52:10.000Z",
      "repliesCount": null,
      "replies": null,
      "likesCount": 0,
      "owner": {
        "id": "10000001",
        "username": "commenter_2",
        "profile_pic_url": "https://scontent.cdninstagram.com/v/t51.2885-19/commenter.jpg",
        "is_verified": true,
        "full_name": null,
        "is_private": null,
        "is_mentionable": null,
        "profile_pic_id": null,
        "latest_reel_media": null,
        "fbid_v2": null
      },
      "media": null
    }
  ],
  "dimensionsHeight": 1920,
  "dimensionsWidth": 1080,
  "originalHeight": 1920,
  "originalWidth": 1080,
  "displayUrl": "https://scontent-arn2-1.cdninstagram.com/v/t51.82787-15/834767174_18464058547143382_652...",
  "images": null,
  "alt": "Video by Jessica Meir on October 03, 2026. May be an image of space shuttle and text.",
  "likesCount": 221491,
  "videoViewCount": null,
  "timestamp": "2026-10-03T14:10:18.000Z",
  "childPosts": null,
  "ownerFullName": "Jessica Meir",
  "ownerUsername": "astro_jessica",
  "ownerId": "4092263381",
  "productType": "clips",
  "isCommentsDisabled": false,
  "paidPartnership": false,
  "sponsors": null,
  "videoUrl": "https://scontent-arn2-1.cdninstagram.com/o1/v/t2/f2/m86/AQMJPDq5Rdnl9IFA0tDHmYYMV82cFQW...",
  "taggedUsers": [
    {
      "full_name": "NASA",
      "id": "528817151",
      "is_verified": true,
      "profile_pic_url": "https://scontent-arn2-1.cdninstagram.com/v/t51.2885-19/29090066_159271188110124_1152068...",
      "username": "nasa"
    },
    {
      "full_name": "International Space Station",
      "id": "953293389",
      "is_verified": true,
      "profile_pic_url": "https://scontent-arn2-1.cdninstagram.com/v/t51.82787-19/524387219_18515253022013390_873...",
      "username": "iss"
    }
  ],
  "coauthorProducers": [
    {
      "id": "528817151",
      "is_verified": true,
      "profile_pic_url": "https://scontent-arn2-1.cdninstagram.com/v/t51.2885-19/29090066_159271188110124_1152068...",
      "username": "nasa"
    },
    {
      "id": "953293389",
      "is_verified": true,
      "profile_pic_url": "https://scontent-arn2-1.cdninstagram.com/v/t51.82787-19/524387219_18515253022013390_873...",
      "username": "iss"
    }
  ],
  "audioUrl": "https://scontent-arn2-1.cdninstagram.com/o1/v/t2/f2/m78/AQMPUZpFhHngoYyHdMIErB1b8MKCrpH...",
  "videoDuration": 27.560894,
  "musicInfo": {
    "artist_name": "astro_jessica",
    "song_name": "Original audio",
    "uses_original_audio": true,
    "should_mute_audio": false,
    "should_mute_audio_reason": "",
    "audio_id": "28373637802328796"
  },
  "videoPlayCount": 5608770,
  "isPinned": true,
  "captionSnippet": "Room with a view. Check out my new digs as I camp…",
  "transcript": "Good morning from my Dragon Lair. Now that Crew -13 has arrived, I've given up my crew quarters and I'm camping out in my dragon vehicle. Here's my view right next to my sleeping bag outside my window here, the Earth and the Crew13 Dragon. A gorgeous view. Reminds me of my best piece of advice to them. Remember to look out the window and realize where you are and I think that kind of advice goes for everybody down on Earth as well. Have a good day.",
  "transcriptLanguage": "en",
  "firstCommentSnippet": "Some v sad people here",
  "taggedUsernames": [
    "nasa",
    "iss"
  ],
  "sponsorUsernames": null,
  "musicArtist": "astro_jessica",
  "musicSong": "Original audio",
  "coauthors": [
    "nasa",
    "iss"
  ],
  "invitedCoauthors": null,
  "invitedCoauthorProducers": null,
  "childPostsCount": null,
  "locationName": null,
  "locationId": null,
  "location": null,
  "taggedUserPositions": [
    {
      "username": "nasa",
      "id": "528817151",
      "x": 0.0,
      "y": 0.0
    },
    {
      "username": "iss",
      "id": "953293389",
      "x": 0.0,
      "y": 0.0
    }
  ],
  "ownerIsVerified": true,
  "ownerProfilePicUrl": "https://scontent-arn2-1.cdninstagram.com/v/t51.82787-19/844321389_18465685600143382_808...",
  "likesHidden": false,
  "sourceType": "profile",
  "scrapedAt": "2026-10-12T18:28:25Z"
}
```

### Good to know

- The Actor never logs in and uses no cookies: it reads what Instagram shows any visitor. Private profiles give no posts (they're listed in OUTPUT and cost nothing), and so do unknown usernames.
- Shares, saves and reposts aren't shown to visitors who aren't logged in, so they aren't in the rows. `videoViewCount` has a video's views and `videoPlayCount` a reel's plays: two different Instagram counters (views are usually 20-40% of plays).
- A reel's plays come from its author's reels tab: for a profile, read as far back as the posts go, and for its pinned reels back to their date; for a reel URL, paged until the reel (at most 15 pages for a pinned reel or a URL). Videos that aren't reels have none.
- Comments are the ones Instagram shows on the post's page without a login (usually 10-15). For every comment of a post, use a comments scraper.
- Video, audio and picture URLs are Instagram's CDN links: they expire after a few days, so download what you need soon after the run.
- **Transcripts** (Add transcripts, off by default): $0.0039 per video with a transcript, on every plan, on top of the post. Photos, carousels and videos without speech (music only, silent) or with fewer than 3 words aren't charged for it.
- You pay per post delivered, nothing for failed, private or unknown inputs. A spending limit stops the run cleanly at the post it pays for.

### Feedback

Missing a field or a kind of input? Open an issue on the Actor's Issues tab and it gets looked at. If the Actor saved you time, a short review on its Store page helps other people find it.

# Actor input Schema

## `username` (type: `array`):

One per line: a username (natgeo), profile URL (https://www.instagram.com/natgeo/) or post / reel URL (https://www.instagram.com/p/DLNsnpUTdVS/). You pay per post delivered; unknown and private profiles are free.

## `resultsLimit` (type: `integer`):

Newest posts per profile (pinned ones come first, as on Instagram). Pages past 12 on their own. You pay per post, so this caps each profile's cost. Not used for post URLs.

## `onlyPostsNewerThan` (type: `string`):

Optional. Only posts after this date (2026-01-31) or this long ago (7 days, 3 months), in UTC. Reading stops at the first older post.

## `skipPinnedPosts` (type: `boolean`):

Leave out the posts a profile pinned to the top of its grid.

## `dataDetailLevel` (type: `string`):

Detailed adds each post's latest comments, alt text, reel play counts and video views. Included in the price; Basic is faster.

## `includeTranscript` (type: `boolean`):

Adds what's said in each video as text (transcript, transcriptLanguage): Instagram's own speech transcript, no timings. $0.0039 per video with a transcript; photos and silent videos aren't charged for it.

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

Stop after this many posts in the whole run. You pay per post, so this caps the run's cost.

## `includeMusicData` (type: `boolean`):

apify/instagram-post-scraper's add-on: here every post's music is in its row whenever Instagram shows it, at no extra cost.

## `mode` (type: `string`):

posts = one row per post (this listing's job).

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

Leave as is: Apify Proxy (datacenter) reads everything this Actor needs.

## Actor input object example

```json
{
  "username": [
    "natgeo",
    "https://www.instagram.com/nasa/",
    "https://www.instagram.com/p/DLNsnpUTdVS/"
  ],
  "resultsLimit": 20,
  "skipPinnedPosts": false,
  "dataDetailLevel": "detailedData",
  "includeTranscript": false,
  "maxResults": 100000,
  "includeMusicData": false,
  "mode": "posts",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "username": [
        "natgeo",
        "https://www.instagram.com/nasa/",
        "https://www.instagram.com/p/DLNsnpUTdVS/"
    ],
    "resultsLimit": 20,
    "dataDetailLevel": "detailedData",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("deepmine/instagram-post-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 = {
    "username": [
        "natgeo",
        "https://www.instagram.com/nasa/",
        "https://www.instagram.com/p/DLNsnpUTdVS/",
    ],
    "resultsLimit": 20,
    "dataDetailLevel": "detailedData",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("deepmine/instagram-post-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 '{
  "username": [
    "natgeo",
    "https://www.instagram.com/nasa/",
    "https://www.instagram.com/p/DLNsnpUTdVS/"
  ],
  "resultsLimit": 20,
  "dataDetailLevel": "detailedData",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call deepmine/instagram-post-scraper --silent --output-dataset

```

## MCP server setup

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