Instagram Profile Posts & Reels Scraper · Apify
Instagram Profile Posts & Reels Scraper avatar

Instagram Profile Posts & Reels Scraper

Pricing

from $0.60 / 1,000 content results

Go to Apify Store
Instagram Profile Posts & Reels Scraper

Instagram Profile Posts & Reels Scraper

Collect posts and Reels from one or more Instagram profiles, with up to 1,000 items per profile. Use postedAfter to fetch only newly published content and stop paginating early, so scheduled runs pay the lower filter rate for old items instead of the full result rate.

Pricing

from $0.60 / 1,000 content results

Rating

0.0

(0)

Developer

LanceAPI

LanceAPI

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

8 days ago

Last modified

Categories

Features

Limited permissions

Share

Instagram Posts & Reels Scraper

Fetch posts and Reels from Instagram profiles. Use postedAfter to retrieve only newly published content, so your Dataset and your result fees stay focused on what is new.

This Actor collects public posts and Reels from one or more Instagram profiles and writes one clean, structured row per item. Paste usernames, profile URLs or numeric user IDs, choose what you want, and — when you only care about what is new — set a cutoff date so pagination stops as soon as the feed moves past it. It is built for content collection and new-content monitoring, not for profile analytics.

  • Posts and Reels in one pass — photos, carousels, feed videos and Reels come back from the profile feed, or ask for posts only / Reels only.
  • postedAfter incremental monitoring — only content published strictly after your cutoff is returned, and pagination stops early once the feed is older than that moment, so a scheduled run does not re-collect and re-pay full result fees for content you already have.
  • Zero new posts is a normal, successful result — not an error, and not a reason to retry the same profile against every data source.
  • Up to 1,000 items per profile, 200 profiles per run — with input normalization and de-duplication built in.
  • Pay per delivered item, with optional date filtering for one fixed fee per run — result fees follow unique posts and Reels delivered to your Dataset. Enable postedAfter for a single advanced-feature fee across the whole batch, regardless of how many items are filtered.

✨ Key features

1. One profile, many content rows

Every unique post or Reel is delivered as its own Dataset row, linked back to the profile it came from through sourceUsername, sourceProfileUrl and sourceProfileId. Photos, carousels, feed videos and Reels are all first-class rows, with type telling them apart (photo, carousel, video, reel).

Because each item is its own row, filtering, joining against your own tables, and exporting stay simple — you never have to unpack a nested list to get at a single post.

2. postedAfter: real incremental scraping, not a local filter

Set postedAfter to a calendar date, an ISO-8601 moment, or a relative value such as 7 days, and only content published strictly after it is returned. The filter is applied inside the pagination pipeline, page by page:

  • each page is normalized and filtered as it arrives;
  • once the feed has moved past your cutoff, pagination stops instead of continuing to pull older pages you would throw away;
  • pinned posts are excluded from the stop decision, so a pinned old item at the top of a feed can never hide newer content;
  • an item with no usable timestamp is not delivered and not guessed — it cannot be proven to be newer than your cutoff.

For scheduled monitoring, older items stay out of your Dataset and do not create result fees. Date filtering is an optional advanced feature charged once per run after at least one profile is successfully checked, across the whole batch. A run that finds nothing new still succeeds: no content rows or result fees, with only the one-time date-filter fee and the Actor start fee.

3. Content-type control that matches how you will use the data

  • All content returns the profile's mixed feed: photos, carousels, feed videos and Reels in one pass.
  • Posts only returns the same feed with explicit Reels removed.
  • Reels only uses the dedicated Reels feed rather than filtering the first page of a mixed one, so Reel-only runs are not limited by what happens to sit on top of the general feed.

4. Batch-friendly with de-duplication at two levels

Process up to 200 profiles in one run. Inputs are normalized before any work starts, so nasa, @nasa, https://www.instagram.com/nasa/ and a numeric user ID for the same account are recognized as the same profile and processed once — no repeated work, no duplicate rows, no duplicate charges. At the result level, the same media ID is delivered only once even across pagination and recovery.

If one profile in a batch fails, the rest of the batch continues. Failures are reported per profile in the run summary, so one bad input does not waste a 200-profile run.

5. Limits that control both Dataset size and cost

resultsLimit caps how many unique items are delivered per profile (1–1000, default 100). It is the main lever over both your Dataset size and your result fees: set it to what you actually need rather than leaving it high. How far back a profile can be read also depends on what the data source returns — this Actor does not claim to deliver an account's entire history.

Every row carries the Instagram media id and shortcode plus the canonical url, so you can de-duplicate against previous runs, join to your own tables, and trace any row back to the profile and input value that produced it. scrapedAt records when the row was collected.

🚀 Quick start

  1. Open the Actor's Input tab.
  2. Add one or more public Instagram profiles — usernames, @usernames, profile URLs, or numeric user IDs.
  3. Keep the defaults for a first run: contentType: all, resultsLimit: 100.
  4. Click Start. When the run finishes, open Output → Content.

For monitoring, set Only content published after to the last moment you already have (for example 2026-10-11T18:30:00Z). The run then returns only newer items and stops paginating once the feed is past that moment.

Minimal input:

{
"profiles": ["nasa", "@natgeo", "https://www.instagram.com/lego/"],
"contentType": "all",
"resultsLimit": 100
}

Incremental input — only what is new since yesterday evening:

{
"profiles": ["nasa"],
"contentType": "all",
"resultsLimit": 100,
"postedAfter": "2026-10-11T18:30:00Z"
}

Short output example

Each unique post or Reel is written as its own Dataset row. The example below is an illustrative example showing structure and field names — values are redacted, not from a live run.

{
"sourceUsername": "nasa",
"sourceProfileUrl": "https://www.instagram.com/nasa/",
"sourceProfileId": "528817151",
"type": "reel",
"url": "https://www.instagram.com/reel/XXXXXXXXXXX/",
"timestamp": "2026-10-12T15:04:00.000Z",
"caption": "Example caption text #hashtag",
"likesCount": 123456,
"commentsCount": 2345,
"viewsCount": 987654,
"videoUrl": "https://…example-video-url…",
"thumbnailUrl": "https://…example-thumbnail-url…",
"id": "3000000000000000000",
"shortcode": "XXXXXXXXXXX",
"contentType": "all",
"input": "nasa",
"scrapedAt": "2026-10-13T06:00:00.000Z"
}

Input

FieldTypeRequiredDefaultLimits / notes
profilesarray of stringsYesprefill: ["instagram"]1–200 values. Accepts usernames (nasa), @usernames, profile URLs (https://www.instagram.com/nasa/) and numeric Instagram user IDs. Normalized and de-duplicated before processing: the same profile is processed once, whatever form it arrived in.
contentTypestringNoallall (mixed feed: photos, carousels, feed videos, Reels), posts (same feed with explicit Reels removed), reels (dedicated Reels feed).
resultsLimitintegerNo1001–1000 unique items per profile. The main control over Dataset size and result fees.
postedAfterstringNoemptyCutoff for incremental runs. In the form, Absolute provides a YYYY-MM-DD calendar picker and Relative accepts a number of days, weeks, months, or years (e.g. 1 days, 2 months, 3 years). JSON also accepts ISO-8601 date-times such as 2026-10-11T18:30:00Z or 2026-10-11T08:00:00+08:00. Dates start at midnight UTC; relative values are resolved once at run start in UTC. Only items published strictly after that cutoff are returned. Invalid values fail with INVALID_POSTED_AFTER before processing. Optional paid feature: one date-filter fee per run after at least one profile is successfully checked; see Pricing.

How the fields interact:

  • postedAfter and resultsLimit work together: the cutoff decides which items qualify, the limit decides how many are delivered. When both are set, the run stops at whichever comes first.
  • postedAfter with zero new items is a successful run: the profile is reported as checked, and no content rows are written.
  • contentType: reels measures Reels directly from the Reels feed; it is not "the first page of the general feed, filtered".

Output

One row per unique post or Reel. The Dataset Views change only the column order and presentation, never the underlying rows:

  • All Content — the balanced overview: source, type, link, timestamp, caption, likes, comments, views, video and thumbnail.
  • Posts — photo and carousel oriented columns.
  • Reels — Reel oriented columns: views, duration, video URL, music.
  • Downloads — media URLs and identifiers for downloading or archiving.

Field reference

Core fields:

FieldTypeMeaning
sourceUsernamestring | nullUsername the item was collected from. Null when the profile was supplied as a numeric ID and nothing proved the username.
sourceProfileUrlstring | nullProfile URL the item was collected from.
sourceProfileIdstring | nullNumeric Instagram user ID of the source profile, when known. Stable across username changes.
typestringreel, photo, carousel, video, or unknown when the payload did not establish one. Never folded into another bucket.
urlstring | nullCanonical Instagram URL of the item.
timestampstring | nullPublication time, ISO-8601 UTC. Null when the payload carried no usable timestamp.
captionstring | nullCaption text, when present.
idstring | nullInstagram media ID — stable identifier for de-duplication and joins.
shortcodestring | nullInstagram shortcode; the slug used in the content URL.

Engagement and media fields:

FieldTypeMeaning
likesCountinteger | nullLike count, when reported.
commentsCountinteger | nullComment count, when reported.
viewsCountinteger | nullPlay/view count for video content, when reported. Null for content that reports none.
playsCountinteger | nullPlay count, when separately reported.
sharesCountinteger | nullShare count, when reported.
videoUrlstring | nullDirect video URL, when the payload returned one. Provider media URLs can expire — download promptly if you need the file.
thumbnailUrlstring | nullThumbnail or first-frame image.
imageUrlstring | nullDisplay image for photos and carousels.
durationnumber | nullVideo duration in seconds, when reported.

Context fields:

FieldTypeMeaning
hashtagsstring[]Hashtags parsed from the caption.
mentionsstring[]Usernames mentioned in the caption.
musicobject | nullAttached audio (title, artist) when the payload carried it.
locationobject | nullTagged location (id, name, city, address) when the payload carried one.
contentTypestringThe contentType setting this run used.
inputstringThe exact profile value you supplied that produced this row.
scrapedAtstringWhen the row was collected, ISO-8601 UTC.

Missing values are delivered as null, never as zero or placeholder text: a null likesCount means the source did not report one, which is different from a real count of zero.

Status and errors

Every run writes a RUN_SUMMARY record to the key-value store with per-run totals: profiles requested / processed / succeeded / failed, how many items the date filter removed, how many content rows were delivered (split into posts and Reels), how many pages and upstream calls were used, how many times the date filter stopped pagination early, and which inputs were rejected.

Run-level input errors fail the whole run before any profile is processed:

CodeMeaning
INVALID_REQUESTThe input could not be read.
BATCH_LIMIT_EXCEEDEDMore than 200 profiles in one run.
INVALID_POSTED_AFTERpostedAfter could not be parsed as an absolute date, an ISO-8601 instant, or a relative UTC duration.

Per-profile outcomes are reported in the summary; a failed profile does not stop the rest of the batch:

CodeMeaningRetry?
PROFILE_NOT_FOUNDThe profile could not be found.Check the username; no retry needed.
CONTENT_UNAVAILABLEPublic content is not available right now (for example a private or restricted account).Retry later may help.
UPSTREAM_RATE_LIMITED / UPSTREAM_QUOTA_EXHAUSTED / UPSTREAM_TIMEOUTA temporary data-source issue.Retry later.
MALFORMED_RESPONSE / UPSTREAM_ERRORA temporary data-source issue prevented this profile from being resolved.Retry later.
SERVICE_CONFIGURATION_ERRORA service configuration issue prevented processing. This failed profile creates no result or date-filter fee; the run start fee is separate.Do not retry: the Actor's routing configuration has to be fixed first.
INVALID_PROFILEThe value is not a usable Instagram profile.Fix the input.
FREE_USAGE_LIMIT_EXCEEDEDThe free usage allowance has been reached.See Pricing.
INTERNAL_ERRORThe profile could not be processed right now.Retry later.

Important, non-error outcomes:

  • Zero new items with postedAfter set — a successful check. The profile is counted as checked, no rows are written, and no result fee applies.
  • Reaching the natural end of a feed — a successful result, even when fewer items than resultsLimit are available.
  • Items older than your cutoff — filtered out by design; the summary reports how many were seen and how many were filtered.

💰 Pricing

This Actor uses pay-per-event pricing, so what you pay follows what the run actually delivered.

Result pricing (per 1,000 delivered posts or Reels)

PlanDelivered posts or Reels
Free$1.10
Bronze$1.00
Silver$0.80
Gold$0.60

That is $0.0011 per delivered item on the Free plan, down to $0.0006 on Gold. See the Actor's Pricing tab for the rates that apply to your account.

Optional advanced date filtering — once per run

Set postedAfter to enable date filtering for $0.0015 per run on Free, or $0.001 per run on Bronze, Silver and Gold. The fee is charged at most once across the whole run, after at least one profile is successfully checked. It does not increase with the number of profiles, pages, or filtered items.

The fee also applies when the check finds no new posts, when every post is new, or when a successfully checked feed is empty: you are paying for the enabled feature. Leave postedAfter empty to avoid this fee. If every profile fails to be checked, no date-filter fee applies.

Actor start fee

$0.001 per run, whatever the batch size. This is separate from result and optional feature fees.

How the billing works:

  • One result fee per unique post or Reel delivered. resultsLimit controls the maximum delivered items per profile and the associated result fees.
  • One optional date-filter fee per run. Filtering 10 items or 10,000 items costs the same feature fee within that run. Multiple profiles share this fee.
  • One start fee per run. The start fee can still apply when no results are delivered or all profiles fail.

There are no additional result fees for invalid profiles, duplicate results, retries, skipped content, or pagination. Invalid input and failed profiles do not activate the date-filter fee by themselves. A successful profile elsewhere in the batch can activate the shared fee. A page can contain items beyond your result limit, but those items do not create result fees or increase the date-filter fee.

Cost example (Free-plan rates, Actor event charges): a daily monitoring run across 5 profiles delivers 12 new posts and filters 288 older ones. It costs 12 × $0.0011 + $0.0015 + $0.001 = $0.0157. A successful quiet-day check with no new posts costs $0.0025: one date-filter fee plus one start fee. A run delivering 100 items without postedAfter costs 100 × $0.0011 + $0.001 = $0.111.

Free-plan users

Free-plan users are subject to the current free usage allowance configured for this Actor. Paid users are not subject to that allowance. When a run reaches the allowance, the remaining profiles continue to be processed and the ones that were not served are reported explicitly in RUN_SUMMARY.

API usage

Run the Actor programmatically and retrieve the default Dataset when it finishes. Replace the sample profiles with your own.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lance_api/instagram-profile-posts-reels-scraper').call({
profiles: ['nasa', '@natgeo'],
contentType: 'all',
resultsLimit: 100,
postedAfter: '2026-10-11T18:30:00Z',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient(token=os.environ['APIFY_TOKEN'])
run = client.actor('lance_api/instagram-profile-posts-reels-scraper').call(run_input={
'profiles': ['nasa', '@natgeo'],
'contentType': 'all',
'resultsLimit': 100,
'postedAfter': '2026-10-11T18:30:00Z',
})
for item in client.dataset(run['defaultDatasetId']).iterate_items():
print(item)

cURL

curl -X POST \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"profiles": ["nasa", "@natgeo"],
"contentType": "all",
"resultsLimit": 100,
"postedAfter": "2026-10-11T18:30:00Z"
}' \
"https://api.apify.com/v2/acts/lance_api~instagram-profile-posts-reels-scraper/runs?waitForFinish=120"

Fetch the default Dataset of the finished run:

$curl "https://api.apify.com/v2/datasets/{datasetId}/items?format=json"

Use cases

  • New-content monitoring. Schedule the Actor daily with postedAfter set to your last checkpoint and receive only what was published since — without re-collecting and re-paying for the same posts on every run.
  • Competitor content tracking. Collect the recent posts and Reels of competitor profiles into your own store and compare posting volume, formats and captions over time.
  • Creator content review at scale. Pull the recent output of a shortlist of creators and review formats, cadence and captions in a spreadsheet before outreach.
  • Reels research. Run with contentType: reels to study a profile's Reel output specifically — views, duration and music — rather than a mixed feed.
  • Content archiving. Use resultsLimit and the Downloads view to capture posts, images and video URLs for an internal archive, downloading media before the URLs expire.
  • Feeding analytics pipelines. Every row carries stable IDs, timestamps and engagement counts, so the Dataset drops straight into a database, dashboard or BI tool.
  • UGC and mention sourcing. Use captions, hashtags, mentions and location fields to find brand-relevant public content for outreach or research.

How it works

  1. You submit profiles in any supported form.
  2. The Actor validates, normalizes and de-duplicates them, so the same profile is processed once.
  3. For each profile it collects the requested content type, normalizing every item into a stable row shape.
  4. When postedAfter is set, items are filtered page by page and pagination stops once the feed has moved past your cutoff.
  5. Unique items are written to the Dataset, and the run summary reports totals, checks, filtered counts and failures.
If you need to…Recommended Actor
Discover more creators and Reels to monitorInstagram Search Scraper
Turn Reels and video posts into text, timestamps and subtitlesInstagram Video Transcript Scraper
Evaluate a creator's followers, engagement rate and posting cadenceInstagram Profile Scraper – Followers & Engagement
Explore an account's followers and following listsInstagram Followers & Following Scraper – Export Lists
Collect comments and replies from posts and ReelsInstagram Comments & Replies Scraper – Posts, Reels
Find who liked a post or ReelInstagram Likers Scraper – Post & Reel Like
Download Reels and videos as filesInstagram Reels Downloader – Video, Audio & Metadata
Find public contact details on a profileInstagram Profile Email Scraper
Monitor what a creator is posting right nowInstagram Stories Scraper
Collect Reels that use a specific trackInstagram Music & Audio Scraper – Reels by Sound
Read Stories saved in HighlightsInstagram Highlights Scraper – Stories & Media

Explore more Instagram data Actors from lance_api on Apify.

FAQ

Which profile formats are accepted? Usernames (nasa), @usernames (@nasa), profile URLs (https://www.instagram.com/nasa/) and numeric Instagram user IDs. All forms of the same profile are recognized and processed once.

Do I need a login or cookie? No. This Actor works with publicly available data only. Never send tokens, cookies or sessions to support.

Is postedAfter inclusive or exclusive? Exclusive. Only items published strictly after the moment are returned. An item published at exactly 2026-10-11T18:30:00Z is excluded when the cutoff is that same moment.

What date formats does postedAfter accept? Use Absolute to select a date with the calendar (YYYY-MM-DD, interpreted as midnight UTC), or Relative to choose days, weeks, months, or years before run start, for example 1 days, 2 months, or 3 years. JSON can also supply ISO-8601 date-times with a timezone (2026-10-11T18:30:00Z, 2026-10-11T08:00:00+08:00). All time values are taken in UTC timezone. The relative cutoff is resolved once per run, so scheduled runs automatically move the window forward. Days/weeks use elapsed UTC days; months/years use calendar subtraction, keeping the UTC time of day and clamping to the last valid day when needed (March 31 minus one month becomes February 28 or 29). 0 days means the run start time. Invalid values fail with INVALID_POSTED_AFTER before any profile is processed.

What happens when there are no new posts? The run succeeds. The profile is reported as checked, no content rows are written, and no result fees apply. With postedAfter enabled, the one-time date-filter fee and the Actor start fee still apply, regardless of how many items were filtered.

Can I get an account's entire post history? No guarantee. The Actor delivers up to resultsLimit unique items per profile, and how far back the feed can actually be read depends on what the data source returns. Do not market or plan against "complete history".

How are pinned posts handled with postedAfter? A pinned item is never allowed to trigger the early stop, so a pinned old post at the top of a feed cannot hide newer content below it.

What happens to items with no timestamp when postedAfter is set? They are not delivered. An item without a usable timestamp cannot be proven to be newer than your cutoff, so it is excluded rather than guessed, and the count is reported in the run summary.

Are duplicate profiles charged twice? No. Repeated references to the same profile — in any supported form — are normalized to one profile, processed once, and charged once.

Are duplicate results possible? The same media ID is delivered once per run, even across pagination and recovery. Two different posts with identical captions remain separate rows.

If one profile fails, does the whole run fail? No. Each profile is processed independently; failures are reported per profile in RUN_SUMMARY and the rest of the batch continues.

Why are some counts null? The source did not report them. Null means "not reported", which is different from zero — this keeps your analysis honest.

How long do media URLs stay valid? Video and image URLs come from the source and can expire. Download media promptly if you need the files; the metadata rows remain valid.

How do I control cost? Lower resultsLimit to what you need. For scheduled runs, enable postedAfter to skip older items for one fixed date-filter fee across your batch; only newly delivered posts incur result fees. Duplicate results, skipped items and failed profiles create no result fee.

Limitations

  • Public data only. Private, restricted or deleted profiles and content cannot be collected.
  • Content availability, counts and media URLs depend on what the source returns at run time and can change without notice.
  • History depth is not guaranteed: the Actor delivers up to resultsLimit unique items per profile, and the readable depth of a feed depends on the source.
  • Counts such as likes, comments, views and shares are reported only when the source reports them; missing values are null.
  • Direct media URLs can expire; download promptly when you need the files.
  • The Actor does not log in, does not bypass access controls, and does not guarantee a fixed number of results per profile.

Public data and responsible use

This Actor collects only publicly available data. You are responsible for complying with applicable laws, Instagram's terms of service, and the privacy and copyright expectations that apply to your use case — including how you store, share and republish collected content, and for avoiding spam or automated abuse of the platform.

Support

Open an issue on the Actor page or email lanceapi2026@hotmail.com.

For a bug report, include:

  • Apify Run ID
  • a non-sensitive Instagram profile you used
  • the input fields you set
  • the relevant status or error code from RUN_SUMMARY, if available
  • what you expected and what actually happened

Do not send:

  • Apify Token or APIFY_TOKEN
  • Cookie
  • Session ID
  • Password
  • API Key
  • Proxy credentials
  • Authorization header