Skip to content

Instagram Post Scraper

Try for free

Scrape public Instagram posts from usernames, profile URLs, or post URLs. Get captions, hashtags, likes, comments count, media URLs, and timestamps for every post.

📸 Instagram Post Scraper

Public Instagram posts, from a username or a URL, in one dataset.

Built for social teams, agencies, and researchers who need a repeatable pull of public posts: captions, media, engagement, and the people attached to the post. Paste a list, set a cap, and run it. A bad URL is one error row. The rest of the list still finishes.

✨ Features

  • 👤 Usernames, profile URLs, and post URLs in the same username list. @natgeo and https://www.instagram.com/p/… both work.
  • 🔢 resultsLimit per profile. A single post URL returns that post and ignores the cap.
  • 📌 skipPinnedPosts drops posts pinned to the top of the profile.
  • 📅 onlyPostsNewerThan stops at a UTC date (YYYY-MM-DD or ISO) or a relative window such as 1 day. Pinned posts stay unless you also skip them.
  • ⚡ basicData for caption, counts, images, owner, and timestamp.
  • 🔬 detailedData (the default) adds alt text, latest comments, music info, paid partnership, and video play count when Instagram sends them.
  • 🖼️ Carousels come back as childPosts plus an images list. Videos include videoUrl and videoDuration when the file is public.
  • 🔒 Public only. Private profiles return private_profile and stop. No login and no session cookie.
  • 🚫 Missing stays missing. A hidden like count is likesCount: -1. A real 0 or false is kept. Anything Instagram did not send is left off the item.

🚀 Why teams use this

Request-based scraping, not a browser. The run spends its time on Instagram’s own post payloads, so a profile list is something you can put on a schedule.

One failed target does not kill the run. A typo, a private account, or a removed post becomes {inputUrl, error, errorDescription}. Every other username still writes its posts.

The output uses the same field names as the public Instagram Post Scraper dataset, so a table, a warehouse load, or a downstream actor can read shortCode, caption, ownerUsername, likesCount, and url without a second mapping step.

Residential proxy is required inside the Scrapely run. Datacenter addresses are rejected by Instagram. The actor does not ask you to paste a session.

💡 Use cases

  • Export a profile's recent posts with captions, likes, and comment counts.
  • Archive a brand's feed or a campaign's posts.
  • Compare post performance across competitors.

🧪 Example input

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

🧾 Sample output

One item from a real run of the example input, shortened. Long text is cut and lists show their first entries.

{
  "id": "3983118388705688735",
  "type": "Video",
  "shortCode": "DdG4RIxIPyf",
  "caption": "Presented by @Rolex. Welcome to Africa 🌍 Africa Earth’s Wild Home takes you deep into the heart of our wildest continent, bringing you closer to its animals,…",
  "hashtags": [
    "Rolex",
    "PerpetualPlanet"
  ],
  "mentions": [
    "Rolex.",
    "wunmimosaku"
  ],
  "url": "https://www.instagram.com/p/DdG4RIxIPyf/",
  "commentsCount": 578,
  "dimensionsHeight": 1920,
  "dimensionsWidth": 1080,
  "originalHeight": 1920,
  "originalWidth": 1080,
  "displayUrl": "https://instagram.fnak3-1.fna.fbcdn.net/…",
  "images": [
    "https://instagram.fnak3-1.fna.fbcdn.net/…"
  ],
  "videoUrl": "https://instagram.fnak3-1.fna.fbcdn.net/…",
  "audioUrl": "https://instagram.fnak3-1.fna.fbcdn.net/…",
  "likesCount": 79633,
  "timestamp": "2026-09-10T13:00:14.000Z",
  "ownerFullName": "National Geographic",
  "ownerUsername": "natgeo",
  "ownerId": "787132",
  "isPinned": true,
  "productType": "clips",
  "videoDuration": 72.614,
  "sponsors": [
    {
      "username": "rolex",
      "full_name": "ROLEX"
    }
  ]
}

📥 Input

FieldRequiredWhat it does
usernameYesUsernames, profile URLs, or post URLs. Duplicates of the same profile or post are scraped once.
resultsLimitNoMaximum posts per profile. Default 20. Minimum 1. Not applied to a single post URL.
skipPinnedPostsNoDefault false.
onlyPostsNewerThanNoUTC YYYY-MM-DD, full ISO, or a relative value such as 2 weeks.
dataDetailLevelNobasicData or detailedData. Default detailedData.

Hashtag, place, and audio URLs, and numeric /p/{id} or /reel/{id} links, are rejected by the input form before a run starts. Use a username, a profile URL, or the shortcode URL.

📤 Output

Each public post is one dataset item. Fields are written only when the payload contains them.

Always attempted from the post itself: id, type (Image, Video, or Sidecar), shortCode, caption, hashtags, mentions, url, commentsCount, dimensionsHeight, dimensionsWidth, originalHeight, originalWidth, displayUrl, images, videoUrl, likesCount, timestamp, childPosts, ownerUsername, ownerId, ownerFullName, isPinned, productType, videoDuration, affiliate, sponsors, taggedUsers, coauthorProducers, locationName, locationId, pk, isCommentsDisabled, inputUrl.

facebookPage and threadsNetProfile are set only when the author object already includes them. Share links are not an input.

Detailed data can also include alt, firstComment, latestComments, musicInfo, paidPartnership, videoPlayCount, videoViewCount, and igPlayCount. audioUrl is included only when Instagram sends a preview file. Logged-out responses often omit it.

A failed target looks like this:

{
  "inputUrl": "https://www.instagram.com/private_example/",
  "error": "private_profile",
  "errorDescription": "This profile is private. Only public profiles are scraped."
}

💰 Pricing

Pay per result, plus platform usage (compute and proxy traffic) at the normal rates.

EventWhen it is chargedPrice
PostEach post saved to the dataset$0.0013 ($1.30 per 1,000 posts)
Post detailsEach post saved with detailed data (dataDetailLevel = detailedData, the default)$0.0006

Example: 1,000 posts with detailed data ≈ $1.90 in event fees plus platform usage; with basic data ≈ $1.30. In our tests a 20-post detailed run used about $0.009 of platform usage. Error rows (private profile, unsupported URL) are never charged. If you set a maximum charge for the run, the scraper stops cleanly when it is reached and keeps every post it already saved.

Related actors

G2
4.7/5
Excellent
Trustpilot

The internet is full of data.
Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

No credit card. No setup calls.