# Instagram Post Scraper (No Login) (`superxcoder/instagram-post-scraper-lite`) Actor

Get the latest 12 posts of public Instagram profiles, or any post or reel by link, without logging in: caption, likes, comment count, date, images, video, hashtags, mentions, tagged users, co-authors and location. No duplicates, a row for every input. $1.20 per 1,000 posts, all data included.

- **URL**: https://apify.com/superxcoder/instagram-post-scraper-lite.md
- **Developed by:** [Deependra Singh](https://apify.com/superxcoder) (community)
- **Categories:** Social media
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.20 / 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.

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 (No Login)

Pull public Instagram posts into a spreadsheet, JSON feed or your own app. Give it usernames, profile links or post links and get back captions, likes, comment counts, images, videos, hashtags, mentions, tagged accounts, co-authors, locations and more. Profiles return their **latest 12 posts**; post and reel links return that exact post, however old.

**$1.20 per 1,000 posts, all data included.** No add-ons, no start fee, and you only pay for posts that pass your filters.

### Why this one

- **One simple price.** $0.0012 per post with every field included: comments, alt text, music and partnership info at no extra cost.
- **Built to be stable.** Stress-tested on 80 profiles in a single run: 888 posts, every input answered, zero duplicates, zero missing core fields.
- **Pay only for what you keep.** Filter by date range, post type (image, reel, carousel), minimum likes and minimum comments. Skipped posts cost nothing.
- **Never charged twice.** A post that appears under two profiles (collabs) or as both a profile post and a link is returned and billed once per run.
- **Nothing fails silently.** Every input gets at least one row: posts, or a free row explaining why there are none (private, not found, filters matched nothing, cost limit reached).
- **Same input, same output.** Profile posts are sorted newest-first before limits and filters, so repeat runs are consistent.
- **Predictable spend.** Cap posts per profile *and* posts per run. The run also stops cleanly at your "Maximum cost per run".
- **Drop-in compatible.** Input names (`username`, `resultsLimit`, `onlyPostsNewerThan`, `skipPinnedPosts`, `dataDetailLevel`) and output field names follow the format most Instagram post scrapers use, so you can switch without rewriting integrations. A `resultsLimit` above 12 is accepted and returns the 12 visible posts.
- **Slim output.** Keep only the fields you need with `outputFields`.
- **No login, no cookies.** Only public data; your accounts are never at risk.

### What you get

| Every post                                 | Detailed level (same price)           |
| ------------------------------------------ | ------------------------------------- |
| URL, shortcode, ID, type, product type     | Alt text (accessibility caption)      |
| Caption, hashtags, mentions                | Latest comments with author and likes |
| Likes, comment count                       | Music: artist, song, original audio   |
| Publish time (UTC)                         | Video length (seconds)                |
| Main image, all carousel images, video URL |                                       |
| Carousel slides (`childPosts`)             |                                       |
| Owner username, ID and full name           |                                       |
| Tagged users, collab co-authors            |                                       |
| Location name and ID, pinned flag          |                                       |

Fields Instagram does not show to logged-out visitors stay `null`: paid-partnership flag and sponsors, affiliate flag, comments-disabled flag, and video view or play counts. They are kept in the output so existing integrations do not break.

Inputs that return no posts get one free row with `error` and `errorDescription`: `unavailable` (the username or post does not exist, or Instagram blocked every try), `restricted` (private or hidden from logged-out visitors), `no_posts`, `invalid_input`, `duplicate` (same profile or post as an earlier input), `no_results` (your filters matched nothing), `not_found` or `failed`. You always know what happened to each input.

### How to use

1. Add usernames, profile URLs or post links to **Profiles or post links**.
2. Set **Posts per profile** (default and maximum 12; higher values are accepted and still return 12).
3. Optional: set a date range, post types, minimum likes/comments, or a total cap.
4. Click **Start** and download the results as JSON, CSV, Excel or HTML, or fetch them over the API.

#### Example input

```json
{
    "username": ["natgeo", "https://www.instagram.com/nasa/", "https://www.instagram.com/p/SHORTCODE/"],
    "resultsLimit": 12,
    "onlyPostsNewerThan": "30 days",
    "postTypes": ["Video"],
    "minLikes": 1000,
    "maxPostsTotal": 500,
    "dataDetailLevel": "basicData"
}
```

#### Example output (shortened)

```json
{
    "inputUrl": "natgeo",
    "id": "3700000000000000000",
    "type": "Video",
    "shortCode": "SHORTCODE",
    "url": "https://www.instagram.com/p/SHORTCODE/",
    "caption": "Example caption #wildlife @photographer",
    "hashtags": ["wildlife"],
    "mentions": ["photographer"],
    "likesCount": 48210,
    "commentsCount": 312,
    "timestamp": "2026-09-30T14:02:11.000Z",
    "displayUrl": "https://scontent.cdninstagram.com/...",
    "videoUrl": "https://scontent.cdninstagram.com/...mp4",
    "ownerUsername": "natgeo",
    "ownerFullName": "National Geographic",
    "isPinned": false,
    "productType": "clips"
}
```

### Pricing

| Event | Price per post | Per 1,000 posts |
| ----- | -------------- | --------------- |
| Post  | $0.0012        | $1.20           |

All fields are included at both detail levels. There is no start fee. Rows for invalid, missing or restricted inputs are free. Apify's free plan credits cover thousands of posts every month.

### Tips

- **Filters save money.** Posts outside your date range, types or engagement thresholds are never charged.
- **Pinned posts** sit at the top of Instagram's grid even when they're old, and they count towards the 12 visible posts. Instagram does not label them for logged-out visitors, so the Actor infers `isPinned` from grid position: a post in the top three slots that is older than a post listed after it. Results are still sorted newest-first, so a pinned post from last year appears at the bottom with `isPinned: true`. Old pinned posts outside your date range are skipped; "Skip pinned posts" drops them all.
- **Proxy is handled for you.** Runs start on datacenter IPs; any page Instagram blocks is retried on residential automatically, so you don't need to configure anything.
- **Video and image URLs expire** about 4 to 5 days after the run (Instagram signs them; the CDN then answers 403). Download the media soon after the run if you need it.
- **Post type filters save fetches.** The profile grid states each post's type, so posts outside "Post types" are never fetched.
- **`unavailable` rows** mean Instagram returned an empty page on all 6 tries, including residential IPs. Logged-out Instagram serves the same empty page for a username that does not exist and for a blocked IP, so check the spelling first; if the profile opens in a browser, run again later.
- **Hidden like counts** come back as `null` or `0`.

### Limits

- **Profiles: latest 12 posts.** Instagram shows logged-out visitors only the 12 newest posts of a profile, and this Actor never logs in. For older posts, pass their post links directly.
- Collab posts appear under the profile they were shared to, but `ownerUsername` is the account that published them.
- Video play and view counts are not shown to logged-out visitors, so they are usually empty.
- Only public profiles and posts. No stories, private accounts, or follower lists.
- Detailed data includes the comments Instagram shows on the post page (usually up to 10 to 15), not the full thread.
- Instagram changes its web endpoints from time to time. If something breaks, open an issue and it's usually fixed within a day.

### Is scraping Instagram legal?

This Actor collects only data that account owners chose to make public, without logging in. Results can still contain personal data (usernames, comments) protected by GDPR, CCPA and similar laws. Only collect and use it if you have a legitimate purpose, and check with a lawyer if you're unsure. You're responsible for complying with Instagram's terms and applicable law.

### Use it from AI agents (MCP)

The Actor is available through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), so Claude, ChatGPT, Cursor, Windsurf, VS Code and any other MCP client can call it as a tool. Add this to your client's MCP configuration; the browser opens once for sign-in:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com?tools=superxcoder/instagram-post-scraper-lite"
        }
    }
}
```

Then ask: *"Get the latest posts of @nasa and @natgeo and list the three with the most likes."* With the Apify CLI, `apify mcp install cursor` (or `claude`, `vscode`, `windsurf`) writes the config for you. The Actor is **agent-payable**: autonomous agents can pay per post with USDC or prepaid tokens through Apify's agentic payments, with no human account set-up.

### API and integrations

Run it from any language with the Apify API or the official clients. The run below waits for the results and prints them:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('superxcoder/instagram-post-scraper-lite').call({
    username: ['nasa', 'natgeo'],
    onlyPostsNewerThan: '7 days',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, 'posts');
```

```python
import os
from apify_client import ApifyClient

client = ApifyClient(token=os.environ["APIFY_TOKEN"])
run = client.actor("superxcoder/instagram-post-scraper-lite").call(
    run_input={"username": ["nasa", "natgeo"], "onlyPostsNewerThan": "7 days"}
)
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

**No-code:** connect it to n8n, Make, Zapier, Google Sheets, Slack, Airtable or Notion from the **Integrations** tab, or schedule it in Console. A ready-made **n8n workflow** that scrapes a list of accounts every morning and appends new posts to Google Sheets ships with the Actor's source (`templates/` folder) and is being submitted to the n8n template library: import the JSON, pick your Apify and Google credentials, done. Webhooks can notify your own system when a run finishes.

### Support

Found a bug or need a field added? Open an issue on the **Issues** tab.

# Actor input Schema

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

One per line: a username (natgeo or @natgeo), a profile URL, or a post/reel URL (https://www.instagram.com/p/SHORTCODE/). Profiles return their latest posts (up to 12); post links return that exact post, any age.

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

Stop after this many posts from each profile. Instagram shows logged-out visitors only the latest 12 posts of a profile, so values above 12 still return at most 12 (kept accepted so inputs written for other Instagram scrapers run unchanged). Does not apply to post links.

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

Skip posts published before this date. Use YYYY-MM-DD, a full ISO date, or a relative value like "7 days", "2 months". UTC. The scraper stops reading a profile once it passes this date, so you also pay less.

## `onlyPostsOlderThan` (type: `string`):

Skip posts published after this date. Combine with "Only posts newer than" to get an exact date range. Same formats.

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

Leave out posts the profile has pinned to the top of its grid. Instagram does not mark pinned posts for logged-out visitors, so they are inferred: a post in the top three grid slots that is older than a post listed after it.

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

Same price either way. Detailed adds alt text, the latest comments, music and paid-partnership info; Basic leaves those out for smaller, faster exports.

## `postTypes` (type: `array`):

Keep only these types. Leave empty for all. Reels count as Video, carousels as Sidecar.

## `minLikes` (type: `integer`):

Skip posts with fewer likes. Posts with hidden like counts are treated as 0. Skipped posts are not charged.

## `minComments` (type: `integer`):

Skip posts with fewer comments. Skipped posts are not charged.

## `maxPostsTotal` (type: `integer`):

Hard cap for the whole run across all profiles and links. 0 = no cap. Useful to keep spend predictable.

## `latestCommentsLimit` (type: `integer`):

How many of the comments Instagram returns with a post to keep (Detailed data only). Instagram usually includes a few, not all.

## `outputFields` (type: `array`):

Optional list of field names to keep in each row, e.g. url, caption, likesCount, timestamp. Leave empty for all fields. Smaller rows export faster.

## `maxConcurrency` (type: `integer`):

Parallel requests. 10 is fast and rarely blocked; lower it if you see many retries.

## `maxRequestRetries` (type: `integer`):

Each retry uses a new IP. The first 2 tries use datacenter, later ones residential.

## `residentialFallback` (type: `boolean`):

When Instagram blocks a datacenter IP twice for the same page, retry that page on residential proxy. Keeps most traffic cheap while still getting blocked profiles.

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

Apify datacenter proxy is the default and costs least. Requests Instagram blocks are retried on residential automatically (see below).

## Actor input object example

```json
{
  "username": [
    "natgeo",
    "https://www.instagram.com/nasa/"
  ],
  "resultsLimit": 12,
  "skipPinnedPosts": false,
  "dataDetailLevel": "detailedData",
  "postTypes": [],
  "minLikes": 0,
  "minComments": 0,
  "maxPostsTotal": 0,
  "latestCommentsLimit": 10,
  "outputFields": [],
  "maxConcurrency": 10,
  "maxRequestRetries": 8,
  "residentialFallback": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `posts` (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/"
    ],
    "resultsLimit": 12,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superxcoder/instagram-post-scraper-lite").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/",
    ],
    "resultsLimit": 12,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superxcoder/instagram-post-scraper-lite").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/"
  ],
  "resultsLimit": 12,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superxcoder/instagram-post-scraper-lite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superxcoder/instagram-post-scraper-lite"
        }
    }
}
```

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/dxMx0TNsWBxQVERCz/builds/MrXgQDsu1lnTRZvgm/openapi.json
