Skip to content

Instagram Profile Scraper

Try for free

Scrape public Instagram profile details from usernames, IDs, or URLs: bio, follower and following counts, posts count, verification, business category, external links, and recent posts.

📸 Instagram Profile Scraper

Public Instagram profiles, ready for a dataset: name, bio, follower counts, links, related accounts, and the latest posts.

Built for growth, research, and competitor teams who need profile records they can join to the rest of their pipeline. Pass usernames, profile ids, or profile URLs. Each successful input becomes one item.

✨ Features

  • 👤 Accepts a username, a numeric profile id, or a profile URL, including /stories/{user}/, /{user}/reels/, and /_u/{user}/.
  • 📊 Returns the public profile record when Instagram sends it: id, username, url, fullName, biography, followersCount, followsCount, postsCount, private, verified, isBusinessAccount, and businessCategoryName.
  • 🔗 Keeps bio links on externalUrl, externalUrlShimmed, and externalUrls (title, url, lynx url, link type) when those values are in the response.
  • 🖼️ Profile pictures on profilePicUrl and profilePicUrlHD when a high-resolution file is actually returned.
  • 🤝 Related accounts on relatedProfiles (id, username, full_name, is_private, is_verified, profile_pic_url).
  • 🗞️ Up to 12 latestPosts, with caption, hashtags, mentions, counts, media URLs, carousel children, tagged users, and video fields when the post payload includes them. likesCount is -1 when likes are hidden or the post has no like count.
  • 📺 igtvVideoCount and up to 12 latestIgtvVideos when the guest profile includes IGTV.
  • 📍 Business address, connected Facebook page name, Threads username, highlight count, and a current public-story flag when the page or guest profile contains them.
  • 🧹 Missing values stay off the item. A real false or 0 stays.
  • ⚠️ A bad username, id, or URL is skipped, listed with its reason in the status message and the OUTPUT record, and does not stop the other inputs. It is never saved as a row or charged.

includeAboutSection adds an about object only when the profile payload already contains a country, join date, verification date, or former-username count. This actor does not look those up on a separate call.

🚀 Why teams use this

Request-based scraping. No browser startup. The run stays on the public page and the same JSON those pages already load, so a batch of profiles finishes as HTTP calls instead of a rendered session per account.

Production shape. One item per input, field names aligned with the public Instagram Profile Scraper dataset, and empty keys left off so exports stay small.

A failed URL does not kill the run. The rest of the list is still scraped and saved. Failed inputs are listed in the status message and in OUTPUT as failedInputs: [{input, reason}]. The run is marked failed only when no profile could be saved.

💡 Use cases

  • Enrich a creator list with follower counts, bios, and contact links.
  • Vet influencers before outreach: size, verification, and posting activity.
  • Track how competitor accounts grow.

🧪 Example input

{
  "usernames": [
    "humansofny"
  ]
}

🧾 Sample output

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

{
  "inputUrl": "humansofny",
  "id": "242598499",
  "username": "humansofny",
  "url": "https://www.instagram.com/humansofny",
  "fullName": "Humans of New York",
  "biography": "New York City, one story at a time.\nCreated by Brandon Stanton\nInquiries/Collabs: honybrandon@gmail.com\nGet a copy of Dear New York below:",
  "externalUrl": "https://bit.ly/dearnewyorkbook",
  "externalUrlShimmed": "https://l.instagram.com/?u=https%3A%2F%2Fbit.ly%2Fdearnewyorkbook&e=AUD4Civ5zNXuVP5_JhwLakPiaX0iFUh0kbqM1ug5ieM-dIVzJzHXUZMcZ5E048rcGdYSRNv__emYxoyrhg5J9Wm3v…",
  "externalUrls": [
    {
      "title": "Dear New York Book",
      "lynx_url": "https://l.instagram.com/?u=https%3A%2F%2Fbit.ly%2Fdearnewyorkbook&e=AUA4W3F1OSFU015FS7nNX8UdfbXIHMzQkfBaRkPz-yV5O52EgUzjoJNJmsUAyD4YgMr8LfL7H8TUW3ecFJS3uEZUd…",
      "url": "https://bit.ly/dearnewyorkbook",
      "link_type": "external"
    }
  ],
  "followersCount": 12647340,
  "followsCount": 755,
  "hasChannel": false,
  "highlightReelCount": 1,
  "isBusinessAccount": false,
  "joinedRecently": false,
  "private": false,
  "verified": true,
  "profilePicUrl": "https://scontent-lim1-1.cdninstagram.com/…",
  "profilePicUrlHD": "https://scontent-lim1-1.cdninstagram.com/…",
  "postsCount": 5876,
  "latestPosts": [
    {
      "id": "3741054891297971261",
      "type": "Video",
      "shortCode": "DPq5ZpJDZw9",
      "caption": "Dear New York closes on October 19th. It’s been the honor and joy of my life to see this take flight. It’s been a magical six days of community and connectio…",
      "url": "https://www.instagram.com/p/DPq5ZpJDZw9/",
      "commentsCount": 976,
      "dimensionsHeight": 1920,
      "dimensionsWidth": 1080,
      "displayUrl": "https://scontent-lim1-1.cdninstagram.com/…",
      "likesCount": 107882,
      "timestamp": "2025-10-11T13:27:07.000Z",
      "ownerUsername": "humansofny",
      "ownerId": "242598499",
      "productType": "clips",
      "videoUrl": "https://scontent-lim1-1.cdninstagram.com/…",
      "videoDuration": 45.416668
    },
    {
      "id": "3742534382104984578",
      "type": "Sidecar",
      "shortCode": "DPwJzEVDbwC",
      "caption": "A few years ago I received a DM from @zohrankmamdani. Only recently did I discover its existence. It was a very unusual DM—especially coming from a local ass…",
      "mentions": [
        "zohrankmamdani."
      ],
      "url": "https://www.instagram.com/p/DPwJzEVDbwC/",
      "commentsCount": 3980,
      "dimensionsHeight": 960,
      "dimensionsWidth": 1440,
      "displayUrl": "https://scontent-lim1-1.cdninstagram.com/…",
      "images": [
        "https://scontent-lim1-1.cdninstagram.com/…",
        "https://scontent-lim1-1.cdninstagram.com/…"
      ],
      "likesCount": 257585,
      "timestamp": "2025-10-13T14:14:46.000Z",
      "childPosts": [
        {
          "id": "…",
          "type": "…",
          "dimensionsHeight": "…"
        },
        {
          "id": "…",
          "type": "…",
          "dimensionsHeight": "…"
        }
      ],
      "ownerUsername": "humansofny",
      "ownerId": "242598499",
      "productType": "carousel_container",
      "taggedUsers": [
        {
          "full_name": "…",
          "id": "…",
          "is_verified": "…"
        }
      ]
    }
  ],
  "fbid": "17841401154973790",
  "threadsNetProfile": {
    "username": "humansofny"
  }
}

📥 Input

FieldTypeWhat to pass
usernamesstring array, requiredOne or more Instagram usernames, numeric profile ids, or profile URLs.
includeAboutSectionboolean, default falseWhen true, copy an about block if the profile response already has it.
{
  "usernames": ["humansofny"]
}

📤 Output

One dataset item per input. A profile URL has no trailing slash. inputUrl is the value you passed in.

Present when Instagram sent them:

id, username, url, fullName, biography, externalUrl, externalUrlShimmed, externalUrls, followersCount, followsCount, hasChannel, highlightReelCount, isBusinessAccount, joinedRecently, businessCategoryName, private, verified, profilePicUrl, profilePicUrlHD, facebookPage, igtvVideoCount, relatedProfiles, latestIgtvVideos, postsCount, latestPosts, hasPublicStory, isRestrictedProfile, restrictionReason, businessAddress, fbid, threadsNetProfile, inputUrl.

about is added only with includeAboutSection and only from fields already on the payload.

A profile that could not be read is not saved. It is listed in the OUTPUT record of the run's key-value store:

{
  "saved": 1,
  "failedInputs": [
    {"input": "zzqq9850notarealuser", "reason": "not_found: Instagram returned 404 (not_found)."}
  ]
}

A value that is not a username, a numeric profile id, or a profile URL is invalid_input: ValueError. The reason is a status and code, or an exception type name.

💰 Pricing

You pay $0.001 per saved profile ($1 per 1,000 profiles), plus the platform usage of the run (compute and residential proxy traffic). Profiles that fail are never saved and never charged. includeAboutSection has no extra charge.

Worked example: 1,000 profiles ≈ $1.00 in profile fees plus platform usage. In our tests at the default 512 MB, a 10-profile run used about $0.009 to $0.011 of platform usage, so 1,000 profiles come to roughly $2 in total. A single-profile run costs about $0.004 of usage because start-up dominates, so batch usernames into one run.

Set a maximum charge for the run and the scraper stops cleanly when it is reached, keeping every profile 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.