# Instagram Profile Post Scraper (`scraper-engine/instagram-profile-post-scraper`) Actor

The Instagram Profile Post Scraper collects posts from any public Instagram profile with speed and precision. It extracts captions, images, videos, timestamps, hashtags, and engagement metrics. Use it for research, analytics, content monitoring, or tracking competitor activity.

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

## Pricing

$19.99/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period.You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#rental-actors

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Instagram Post Scraper — Captions, Likes, Comments and Media Data

Instagram Post Scraper extracts public posts — images, videos, carousels and reels — from any Instagram profile, returning captions, hashtags, mentions, like and comment counts, media links, and a sample of comments as structured JSON. Paste one or more usernames, profile URLs, or post shortcodes, set how many posts to pull, and every post streams into the dataset the moment it's collected — no login, cookies, or Instagram API credentials required. Start a run below to see it in action.

### What is Instagram Profile Post Scraper?

Instagram Profile Post Scraper is an Apify Actor that reads the public posts on one or more Instagram profiles and returns each post — image, video, carousel, or reel — as a structured JSON record with captions, engagement counts, media links, and a comment sample. It works entirely from Instagram's public pages: no Instagram account, login, or session cookie is read from, or required in, the input schema. It's built for social media managers, competitor and influencer researchers, and developers or AI engineers who need clean, post-level data for dashboards, reports, or LLM pipelines.

### What Instagram post data is publicly available to scrape?

Anyone who opens a public Instagram profile in a browser without logging in can already see its posts, captions, hashtags, media, and like/comment counts — Instagram Profile Post Scraper reads the same publicly rendered data.

| Data Category | Publicly Available | Restricted behind login |
| --- | --- | --- |
| Post captions & hashtags | ✅ | — |
| Media (images, video, carousel slides) | ✅ | — |
| Like & comment counts | ✅ | — |
| A sample of comments | ✅ | Full comment thread — login |
| Pinned-post status | ✅ | — |
| Account username, verification & privacy flag | ✅ | Full bio, follower/following lists — login |
| Stories, Reels insights, saved/archived posts | ❌ | Login (usually the account owner only) |
| Private-account posts | ❌ | Login + accepted follow request |

Instagram Profile Post Scraper only returns publicly visible data — what any visitor sees. Nothing behind a login wall.

### What data can I extract with Instagram Post Scraper?

Each run returns one JSON record per post, covering identity and content fields, engagement and format metrics, and timestamps, comments, and nested media.

| Field Name | Description |
| --- | --- |
| `id`, `pk`, `shortcode` | Post identifiers; `shortcode` is the code used in Instagram's own post URLs |
| `url`, `post_url` | Full link back to the post on instagram.com |
| `type`, `product_type` | `Image` / `Video` / `Carousel`, plus Instagram's own product type (e.g. `clips`) |
| `caption`, `accessibility_caption` | Post text and Instagram's auto-generated image description |
| `hashtags`, `mentions` | Parsed from the caption |
| `display_url`, `image_links`, `video_links`, `images`, `video_versions`, `dimensions` | Media URLs, size variants, and pixel dimensions |
| `owner`, `user`, `account_username`, `account_verified`, `account_profile_picture` | The posting account's username, verification and privacy flags, and profile picture |
| `likes_count` / `like_count`, `comments_count` / `comment_count` | Engagement counts |
| `views_count` / `view_count`, `video_duration` | Video/reel playback metrics |
| `is_video`, `is_carousel`, `is_pinned`, `carousel_media_count`, `carousel_media` | Format flags and carousel slide data |
| `taken_at_timestamp`, `date`, `posted`, `crawled_at`, `scraped_at` | When the post went live and when this row was collected (real UTC) |
| `comments`, `latest_comments` | Up to 10 comments per post, each with text, author, and like count |
| `usertags`, `coauthor_producers`, `clips_metadata` | Tagged accounts, collaborators, and reel/clip audio metadata when present |

#### Post identity & content fields

`id`, `pk`, `shortcode`, `url`, `post_url`, `type`, `product_type`, `caption`, `accessibility_caption`, `hashtags`, `mentions`, `display_url`, `image_links`, `video_links`, `images`, `video_versions`, `dimensions`, `owner`, `user`, `account_username`, `account_profile_picture`, `from_url` — everything that identifies the post, describes it, and locates its media.

#### Engagement & format metrics

`likes_count` / `like_count`, `comments_count` / `comment_count`, `views_count` / `view_count`, `video_duration`, `is_video`, `is_carousel`, `is_pinned`, `carousel_media_count`, `carousel_media`, `account_verified` — the counts, flags, and booleans used for ranking or filtering posts.

#### Timestamps, comments & nested media

`taken_at_timestamp`, `date`, `posted`, `crawled_at`, `scraped_at`, `comments`, `latest_comments`, `usertags`, `coauthor_producers`, `clips_metadata` — when the post happened, when it was scraped, its comment sample, and nested objects like tagged accounts and reel audio.

#### 🤖 Add-on: Need additional Instagram data?

Need the creator's own bio, follower count, and verification badge alongside every post? Pair this Actor with **Instagram Posts Scraper With Creator Profiles**. Tracking a profile's Stories instead of its feed? **Instagram Story Details Scraper** covers that surface with the same JSON-first approach.

### How does Instagram Post Scraper differ from the official Instagram API?

Meta's Instagram Graph API only returns content the authorizing account itself created — a permission "only allows access to data created by the app user who granted the permission," so it cannot be pointed at a competitor's or influencer's public profile without that profile's owner granting your app access (per Meta's Instagram Graph API documentation, checked 2026-07-30). Instagram Post Scraper instead reads any public profile's posts directly, no token or account ownership required.

| Feature | Instagram Graph API | Instagram Post Scraper |
| --- | --- | --- |
| Access to other public accounts' posts | Not supported without that account's own access token | ✅ any public profile |
| Account type required | Business or creator Instagram account | None |
| App review | Advanced Access requires Meta App Review and business verification to read accounts you don't own | Not applicable |
| Setup time | App creation, permission scopes, review, account conversion | Paste a username and start the run |
| Rate limiting | Governed by Meta's content-impression-based platform limits | Governed by `requestDelay` / `maxRetries` and your chosen Apify Proxy, set per run |
| Output shape | Raw Graph API JSON, versioned per API release | Fixed, unified JSON schema across every post |

Use the Graph API when you manage the Instagram account yourself and need first-party analytics or publishing inside your own app. Use Instagram Post Scraper when you need post-level data from public profiles you don't own or control — competitors, influencers, or brand accounts — without going through Meta's app review process.

### How to use Instagram Post Scraper

You run this Actor from the Apify platform — there's no separate signup or API key to obtain first.

1. Open **Instagram Profile Post Scraper** on the Apify Store (or your Apify Console if you already have it saved).
2. Add the required input — one or more entries in `startUrls`: full profile URLs, plain usernames, or post shortcodes.
3. Set `maxPosts` (`0` for unlimited), `pinnedMode`, and `recent` if you only want posts newer than a given date.
4. Optionally open **⚙️ Advanced Settings** to tune `requestDelay` / `maxRetries`, and **🛡️ Proxy Configuration** — residential proxies are recommended.
5. Click **Start** — posts stream into the default dataset as they're collected.
6. Export the dataset as JSON, CSV, Excel, or XML from the Console, or pull it via the Apify API/SDK.

#### How to scale to bulk post extraction

`startUrls` accepts an unlimited number of entries in a single array, so queuing 50 profiles is one run, not fifty separate ones. Profiles are processed one after another within that run, with a `requestDelay` pause between each; there's no separate "bulk" toggle — the array itself is the bulk input, and posts from every profile land in the same dataset as they're collected.

### What can you do with Instagram post data?

- 📊 **Social media managers** benchmarking engagement use `likes_count`, `comments_count`, and `view_count` across a profile's posts to see which format or topic performs best.
- 🕵️ **Competitor & influencer researchers** use `caption`, `hashtags`, and `posted` to track a rival's or creator's posting cadence and messaging over time.
- 🛡️ **Brand safety teams** use `mentions` and `usertags` to spot unauthorized brand tags or collaborations surfacing in a creator's feed.
- 🔬 **Researchers and data scientists** use `caption` and `latest_comments[].text` to build topic or sentiment models across an account's post history.
- 🤖 **AI engineers** feed `caption`, `hashtags`, and `comments` into a RAG pipeline or LLM summarizer to power a social-listening or content-briefing agent. Because output is typed JSON reachable through the Apify API, any agent framework that can call an HTTP endpoint can drive this Actor and consume its results directly.

### How does Instagram Post Scraper handle rate limits and blocking?

Every request is routed through Apify Proxy using the `proxyConfiguration` you set (residential proxies are recommended for Instagram); each attempt pulls a fresh rotating proxy URL and a randomized desktop User-Agent. Failed requests are retried automatically: the fallback pagination path retries each request up to `maxRetries` times and gives up on a profile after 3 consecutive failed pages, while ⚠️ the initial, faster profile-page fetch always retries a fixed 3 times regardless of `maxRetries`. `requestDelay` paces the wait between paginated requests and between profiles, and that delay is scaled up automatically on later pages to ease off large profiles. The Actor does not solve CAPTCHAs — if Instagram serves a challenge or login page instead of data, that request is treated as a failure and retried or skipped.

### ⬇️ Input

Instagram Profile Post Scraper takes the following parameters, defined in `.actor/actor.json`'s input schema:

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `startUrls` | Yes | array | List one or more Instagram profile URLs (e.g. `https://www.instagram.com/username`), plain usernames (e.g. `username`), or post shortcodes (e.g. `ABC123DEF`). The actor normalizes everything into usernames. | `["https://www.instagram.com/nasa/", "mkbhd"]` |
| `maxPosts` | No | integer (min `0`, max `10000`, default `10`) | How many posts to scrape per profile. Set to `0` for unlimited posts (use with care for very large profiles). | `25` |
| `pinnedMode` | No | string (enum: `include`, `skip`, `only`; default `include`) | `include`: mix pinned + regular posts. `skip`: ignore pinned posts. `only`: return only pinned posts when available. | `"include"` |
| `recent` | No | string (nullable) | Filter posts by date. Use an absolute date (`YYYY-MM-DD`) or a relative value like `"3 days"`, `"2 weeks"`, or `"1 month"`. Leave empty to scrape all available posts. | `"2 weeks"` |
| `requestDelay` | No | integer (min `1`, max `30`, default `2`) | Base delay in seconds between paginated requests and between profiles. `requestDelay=2` → the actor waits roughly 2–4s between page fetches (randomized, increasing on later pages). | `2` |
| `maxRetries` | No | integer (min `1`, max `10`, default `3`) | How many times to retry a failed page/request before giving up on it. | `3` |
| `proxyConfiguration` | No | object | Configure which proxies to use for scraping. Residential proxies are strongly recommended (and usually required) for reliable Instagram scraping. | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

#### Example input

```json
{
  "startUrls": [
    "https://www.instagram.com/nasa/",
    "mkbhd",
    "DRnOEjME21V"
  ],
  "maxPosts": 25,
  "pinnedMode": "include",
  "recent": "2 weeks",
  "requestDelay": 2,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### ⬆️ Output

Every post is pushed to the run's default dataset as one typed, normalized JSON record, with the same field names and shapes on every row. Export it as JSON, CSV, Excel, or XML from the Apify Console, or read it programmatically via the Apify API/SDK. Each row written is charged under the `row_result` pay-per-event pricing shown on the Actor's pricing tab — the Actor does not push separate uncharged error or accounting rows, so every dataset row you see is a scraped post.

#### Example output

```json
{
  "id": "3776048697886076245_2535829435",
  "pk": "3776048697886076245",
  "shortcode": "DRnOEjME21V",
  "url": "https://www.instagram.com/p/DRnOEjME21V/",
  "post_url": "https://www.instagram.com/p/DRnOEjME21V/",
  "type": "Video",
  "product_type": "clips",
  "is_video": true,
  "is_carousel": false,
  "is_pinned": false,
  "has_audio": true,
  "posted": "29 Nov 2025, 07:02:23 am",
  "taken_at_timestamp": 1764360143,
  "date": "2025-11-29T07:02:23Z",
  "crawled_at": "2026-07-30T09:15:00Z",
  "caption": "Behind the scenes from today's shoot — link in bio for the full video.",
  "accessibility_caption": "Photo by Example Account on November 29, 2025.",
  "hashtags": ["bts", "launch"],
  "mentions": ["examplebrand"],
  "usertags": null,
  "likes_count": 996806,
  "like_count": 996806,
  "comments_count": 5024,
  "comment_count": 5024,
  "views_count": 4210332,
  "view_count": 4210332,
  "video_duration": 34.5,
  "video_links": ["https://scontent.cdninstagram.com/video.mp4"],
  "video_versions": [{"width": 1080, "height": 1920, "url": "https://scontent.cdninstagram.com/video.mp4", "type": 101}],
  "display_url": "https://scontent.cdninstagram.com/thumb.jpg",
  "thumbnail": "https://scontent.cdninstagram.com/thumb.jpg",
  "image": "https://scontent.cdninstagram.com/thumb.jpg",
  "image_links": ["https://scontent.cdninstagram.com/thumb.jpg"],
  "images": [{"url": "https://scontent.cdninstagram.com/thumb.jpg", "width": 1080, "height": 1920}],
  "dimensions": {"height": 1920, "width": 1080},
  "carousel_media_count": null,
  "carousel_media": null,
  "coauthor_producers": [],
  "owner": {
    "id": "2535829435",
    "pk": "2535829435",
    "username": "example_account",
    "profile_pic_url": "https://scontent.cdninstagram.com/profile.jpg",
    "is_verified": true,
    "is_private": false
  },
  "user": {
    "pk": "2535829435",
    "id": "2535829435",
    "username": "example_account",
    "full_name": "Example Account",
    "profile_pic_url": "https://scontent.cdninstagram.com/profile.jpg",
    "hd_profile_pic_url_info": {"url": ""},
    "is_verified": true,
    "is_private": false
  },
  "account_username": "example_account",
  "account_verified": true,
  "account_profile_picture": "https://scontent.cdninstagram.com/profile.jpg",
  "from_url": "https://www.instagram.com/example_account/",
  "clips_metadata": {"audio_type": "original_sounds", "music_info": null},
  "scraped_at": "2026-07-30T09:15:01Z",
  "comments": [
    {
      "id": "17912345678901234",
      "text": "This is amazing!",
      "created_at": 1764361000,
      "created_at_utc": 1764361000,
      "user": {"pk": "998877", "username": "a_follower", "full_name": "", "profile_pic_url": "", "is_verified": false, "is_private": false},
      "comment_like_count": 12,
      "has_liked_comment": false
    }
  ],
  "latest_comments": [
    {
      "id": "17912345678901234",
      "text": "This is amazing!",
      "created_at": 1764361000,
      "created_at_utc": 1764361000,
      "user": {"pk": "998877", "username": "a_follower", "full_name": "", "profile_pic_url": "", "is_verified": false, "is_private": false},
      "comment_like_count": 12,
      "has_liked_comment": false
    }
  ]
}
```

Fields Instagram doesn't expose for a given post — for example `carousel_media_count` on a single-image post, or `user.full_name` when only the lightweight page path was used — return as `null`/`[]`/`{}` rather than a guessed value.

### How does it work?

Instagram Post Scraper first requests each profile's public page over HTTP through Apify Proxy, using randomized browser-like headers, and reads the JSON Instagram embeds directly in that page's HTML for the profile's most recent posts. If that page doesn't expose any posts — for example because Instagram's markup changed for that profile — the Actor switches to Instagram's own private feed API: it first reads a CSRF token and app ID off the same public page, then pages through results the way a browser would while scrolling. No login, session, or saved cookie is ever used; every request looks like an anonymous visit to a public page. Whichever path succeeds, results are normalized into the same JSON schema before being written to the dataset, so field names and types stay stable even when Instagram changes its front end or private API shape.

### Integrations

Instagram Post Scraper runs on the Apify platform, so it works with anything that can call the Apify API or trigger an Apify run.

#### Calling Instagram Post Scraper programmatically

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_API_TOKEN>")
run = client.actor("instagram-profile-post-scraper").call(run_input={
    "startUrls": ["https://www.instagram.com/nasa/"],
    "maxPosts": 25,
    "pinnedMode": "include",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["shortcode"], item["likes_count"])
```

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.

#### No-code tools (n8n, Make, LangChain)

In **n8n**, use the HTTP Request node (or the community Apify node) pointed at this Actor's run-and-get-dataset-items endpoint to pull posts straight into a workflow. In **Make**, the Apify app's "Run Actor and Get Dataset Items" module does the same without writing code. In **LangChain** or a similar agent framework, wrap the Apify API call in a custom Tool so an agent can request fresh Instagram post data on demand.

### Is it legal to scrape Instagram posts?

Scraping publicly available Instagram posts is generally lawful, since Instagram Post Scraper only reads what any logged-out visitor can already see — no login wall is bypassed. That said, captions, comments, and usernames are personal data, so storing or reusing them can bring GDPR or CCPA into play depending on where your users are and what you do with the data — you need a lawful basis for collecting and retaining it, and you still need to respect Instagram's own Terms of Use for your use case. Consult legal counsel if your use case involves bulk storage of personal data.

### Frequently asked questions

#### What Instagram post fields does Instagram Post Scraper return?

The top fields are `caption`, `likes_count`, `comments_count`, `display_url`, and `posted` — see the [data fields section](#what-data-can-i-extract-with-instagram-post-scraper) above for every key returned on each row.

#### Does Instagram Post Scraper require an Instagram account or login?

No. It reads Instagram's own public profile and post pages; no username, password, session cookie, or Instagram API credential is accepted as input.

#### How many posts can I extract in one run?

Up to `maxPosts` per profile (`0` removes the cap, `10000` is the schema's own maximum), across as many profiles as you list in `startUrls` in a single run. ⚠️ In practice, if Instagram's own profile page already returns posts on the first request, the Actor uses exactly what that page contains and does not paginate further even if `maxPosts` asks for more — it only switches to the paginated fallback (capped at 100 pages) when that first request returns zero posts.

#### What happens if a profile is private or doesn't exist?

Instagram Post Scraper logs an error for that profile — "No posts found for @username. Account may be private or unreachable." — and moves on to the next entry in `startUrls`. No rows are written, and nothing is charged, for a profile that returns zero posts.

#### Can I scrape multiple Instagram profiles at once?

Yes — list any number of profile URLs, usernames, or shortcodes in `startUrls` and they're processed one after another within the same run, each streaming its own posts into the shared dataset.

#### Does Instagram Post Scraper work with Claude, ChatGPT, and other AI agent tools?

Yes, as an HTTP endpoint. It isn't registered as an MCP server, but any agent framework that can call the Apify API — including custom tools built for Claude, ChatGPT, or LangChain — can start a run and read back the resulting JSON.

#### Does Instagram Post Scraper return data in a format LLMs can use directly?

Yes. Every post is typed, normalized JSON with the same field names and shapes across runs — no HTML to parse and no CSS selectors to maintain — so it can be passed straight to an LLM prompt, indexed into a vector store, or handed to an agent tool.

#### What happens when Instagram changes its layout or anti-bot system?

The Actor is maintained against Instagram's current page structure and private API shape, and the output schema is designed to stay the same regardless of front-end changes. No specific turnaround time is published for updates.

#### Can I use Instagram Post Scraper without managing proxies or browser infrastructure?

Yes — proxy rotation (via Apify Proxy / `proxyConfiguration`), retries, and header rotation are all handled by the Actor. You only choose the proxy group (residential is recommended); there's no separate browser or infrastructure to run yourself.

#### Which Instagram post fields work best for AI training data and RAG indexing?

For RAG, index `caption` and `latest_comments[].text` — the highest-information free text on each post. For training data or structured features, `likes_count`, `comments_count`, `view_count`, `is_video`, and `is_carousel` are the most consistently populated numeric/boolean fields across every row, and all fields return as typed primitives or nested objects, never embedded HTML.

#### What makes Instagram Post Scraper's output reliable without an Instagram login?

Every field is filled from what Instagram itself serves the request, including a real UTC `scraped_at`/`crawled_at` timestamp on each row. Fields Instagram doesn't expose for a given post on a given code path — for example a creator's verification badge when only the lightweight profile-page fetch was used — are left `null`/empty instead of guessed, so a null value always means "not exposed here," never a fabricated placeholder.

### Related scrapers

| Scraper | What it extracts |
| --- | --- |
| Instagram Posts Scraper With Creator Profiles | Instagram posts plus the creator's own profile fields (bio, followers, verification) in one run |
| Instagram Story Details Scraper | Public Instagram Stories per profile |
| TikTok User Profile Scraper With Engagement Analytics | TikTok profile and engagement data |
| LinkedIn Company Profile Scraper | LinkedIn company page data |
| Snapchat User Stories Scraper | Public Snapchat Stories per user |

### Your feedback

Found a bug or a field that's not populating? Let us know via the Issues tab on this Actor's Apify Store page, or through Apify's support chat in the Console — reports like this get folded directly into the next update.

# Actor input Schema

## `startUrls` (type: `array`):

List one or more Instagram profile URLs (e.g. https://www.instagram.com/username), plain usernames (e.g. username), or post shortcodes (e.g. ABC123DEF). The actor will normalize everything into usernames for you.

## `maxPosts` (type: `integer`):

How many posts to scrape per profile. Set to 0 for unlimited posts (use with care for very large profiles).

## `pinnedMode` (type: `string`):

Choose how to handle pinned posts:

- include: mix pinned + regular posts (default)
- skip: ignore pinned posts
- only: return only pinned posts when available

## `recent` (type: `string`):

Filter posts by date to keep results fresh. Use an absolute date (YYYY-MM-DD) or a relative value like '3 days', '2 weeks', or '1 month'. Leave empty to scrape all available posts.

## `requestDelay` (type: `integer`):

Base delay in seconds between paginated requests and between profiles. Example: requestDelay=2 → the actor waits roughly 2-4s between page fetches (randomized, increasing on later pages). Lower is faster but riskier for rate limits; higher is safer for large profiles. Default is 2.

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

How many times to retry a failed page/request before giving up on it (e.g. maxRetries=3 → up to 3 attempts per request). Default is 3.

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

Configure which proxies to use for scraping. Residential proxies are strongly recommended (and usually required) for reliable Instagram scraping.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.instagram.com/cristiano/"
  ],
  "maxPosts": 10,
  "pinnedMode": "include",
  "requestDelay": 2,
  "maxRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "startUrls": [
        "https://www.instagram.com/cristiano/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper-engine/instagram-profile-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 = {
    "startUrls": ["https://www.instagram.com/cristiano/"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scraper-engine/instagram-profile-post-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 '{
  "startUrls": [
    "https://www.instagram.com/cristiano/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scraper-engine/instagram-profile-post-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/5qNgraWnm5ozWKViZ/builds/F3lEZc8SudrqB6iEY/openapi.json
