SFOLN

Catalogue / Social media data

Instagram Posts Scraper (No Login)

sfoln/instagram-user-posts · Social media, Lead generation, Automation On request

Scrape the latest posts and reels of public Instagram profiles, no login needed: caption, date, likes, comments, views, media URLs, hashtags, mentions and location, one row per post. $0.60 per 1,000 posts + $0.003 per page of about 12.

About

What it does

Instagram Posts Scraper (No Login) gets the latest posts of public Instagram profiles with one normalized record per post: shortcode, URL, type (image / video / carousel / reel), caption, post date, likes, comments, video views, thumbnail, all media URLs, hashtags, mentions, tagged users, pinned flag and location. You can optionally also read the Reels tab. It's built for influencer vetting, brand and competitor monitoring, content analytics and AI agents.

Price

Price per delivered record

EventPricePer 1,000Charged for
Instagram post
instagram-post
$0.0006$0.60 / 1,000Charged once per Instagram post or reel delivered as a dataset record. User summary records are never charged.
Instagram posts page
instagram-posts-query
$0.003$3 / 1,000Charged once per page of a user's posts or reels (about 12 per page) that delivered at least one post, or that the provider billed although it had no new posts (e.g. a private account's empty feed). Covers the per-request upstream fee.

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~instagram-user-posts/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"handles":["nasa"],"maxPostsPerUser":6}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/instagram-user-posts"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~instagram-user-posts/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Get the 12 latest Instagram posts of @nasa and rank them by likes and comments.

Input

Input fields

Paste Instagram handles or profile URLs. Each profile produces one dataset record per post (newest first) plus one summary record per profile.

FieldTypeDefaultMeaning
handles *arrayrequiredInstagram profiles
Handles (with or without @) or profile URLs such as https://www.instagram.com/nasa/. Post and reel URLs are not accepted. Duplicates are removed. Accounts on the Apify free plan can process up to 10 profiles per run.
maxPostsPerUserinteger12Max posts per profile
How many of the newest posts to return per profile (1–120). Posts are fetched in pages of about 12; each delivered post is one charged event, plus one page event per page. Range 1–120.
includeReelsbooleanfalseAlso fetch the Reels tab
Also read the profile's Reels tab (up to the same limit) and add reels that are not already in the posts feed. Reels from this tab come without captions. Billed like posts.
maxUsersinteger100Max profiles
Safety cap on the number of profiles processed in this run. Range 1–1000.
concurrencyinteger4Concurrency
How many profiles are fetched in parallel (1–8). Range 1–8.
itemTimeoutSecsinteger600Time limit per input (seconds)
Pagination for one profile stops cleanly shortly before this limit (60–3600). Raise it for very large per-input limits. Range 60–3600.
includeRawbooleanfalseInclude raw upstream response
Attach the unmodified provider post object to each post record (much larger output).
Example input
{
  "handles": [
    "nasa"
  ],
  "maxPostsPerUser": 6
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The handle or profile URL as provided.
recordTypestringRecord type
post (one per delivered post, charged) | user (one summary per profile, never charged) e.g. "post"
handlestring | nullHandle
feedstringFeed
posts (main grid) | reels (Reels tab, only with includeReels)
positionintegerPosition
postIdstring | nullPost ID
shortcodestring | nullShortcode
urlstring | nullURL
typestring | nullType
image | video | carousel | reel
captionstring | nullCaption
takenAtstring | nullPosted at
ISO 8601 UTC
likesnumber | nullLikes
null when the owner hides like counts
commentsnumber | nullComments
viewsnumber | nullViews
Video/reel plays (Instagram only); null for images
durationSecsnumber | nullDuration (s)
thumbnailUrlstring | nullThumbnail URL
mediaUrlsarrayMedia URLs
Image/video URLs (one per carousel item); CDN links expire.
mediaCountintegerMedia count
hashtagsarrayHashtags
mentionsarrayMentions
@handles mentioned in the caption
taggedUsersarrayTagged users
isPinnedboolean | nullPinned
isPaidPartnershipboolean | nullPaid partnership
locationNamestring | nullLocation
ownerHandlestring | nullOwner handle
ownerIdstring | nullOwner ID
profileUrlstringProfile URL
user records only.
postsDeliveredintegerPosts delivered
user records only.
reelsDeliveredintegerExtra reels delivered
user records only.
pagesFetchedintegerPages fetched
user records only.
pagesChargedintegerPages charged
user records only.
reachedEndbooleanReached end
user records only.
stopReasonstringStop reason
user records only.
statusstringStatus
ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan e.g. "ok"
chargedbooleanCharged
Post records: charged instagram-post. user summary records are never charged themselves: the instagram-posts-query page fees charged for the input (including empty pages the provider billed) are counted in pagesCharged.
chargedEventstringCharged event
errorobjectError
warningsarrayWarnings
sourcestringSource
fetchedAtstringFetched at
Example record
{
  "input": "carsoncantcode",
  "recordType": "post",
  "handle": "carsoncantcode",
  "feed": "posts",
  "position": 1,
  "postId": "3644028144127958689_59042353222",
  "shortcode": "DKSMEpKRd6h",
  "url": "https://www.instagram.com/p/DKSMEpKRd6h/",
  "type": "reel",
  "caption": "5 best college baseball regional plays for day 1 #baseball",
  "takenAt": "2025-05-30T16:20:51.000Z",
  "likes": 29,
  "comments": 7,
  "views": 2647,
  "durationSecs": 72.1,
  "thumbnailUrl": "https://scontent.cdninstagram.com/…jpg",
  "mediaUrls": [
    "https://scontent.cdninstagram.com/…mp4"
  ],
  "mediaCount": 1,
  "hashtags": [
    "baseball"
  ],
  "mentions": [],
  "taggedUsers": [],
  "isPinned": false,
  "isPaidPartnership": false,
  "locationName": null,
  "ownerHandle": "carsoncantcode",
  "ownerId": "59042353222",
  "status": "ok",
  "charged": true,
  "chargedEvent": "instagram-post",
  "source": "scrapecreators",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}

Machine-readable

This page for agents