Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
Instagram Profile Scraper icon

Instagram Profile Scraper

Scrape Instagram profiles from handles or URLs. Get the bio, exact follower and post counts, verified flag, category and bio links. $0.70 per 1,000.

1.8 from 3 reviews on Apify 3,478 runs on Apify $0.0007 per profile ($0.7 / 1,000)
Run this in the cloudRun on Apify →

Social Media Scrapers

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust usernames, includeAccountAbout, includeLatestPosts (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.0007 per profile = $0.7 per 1,000

You are charged forWhenPrice
Profile scrapedOne public Instagram profile read and written to the dataset.$0.0007
Add-on: country, join date and former usernamesOptional. Reads Instagram's About this account panel for one profile. Only charged when you tick the box.$0.005

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-19, and they are what you are actually charged.

Inputs

FieldWhat it doesType
usernamesOne entry per profile. Any of these forms works: nasa, @nasa, instagram.com/nasa, https://www.instagram.com/nasa/. Up to 1,000 per run. Duplicates are removed before anything is charged.array
includeAccountAboutReads Instagram's About this account panel and adds the account's country of registration, the date it was created, and how many usernames it has used before (the number, not the names - Instagram keeps those behind a tap). Needs a paid Apify plan - on the free plan this stays off and the rest of the run is unaffected. Instagram only shows that panel to a logged-in session, so it costs extra per profile on top of the profile price. Be aware, the country line only shows on larger accounts: smaller ones still return the join date, with country null. Leave this off and you pay the profile price only.boolean
includeLatestPostsAdds the recent posts themselves to each row: link, caption, likes, comments, hashtags, mentions, tagged people, co-authors, location, music, whether the post is pinned, and whether likes or comments are switched off. The field names are the same as in our post scraper. The posts are listed one per line in the Recent posts tab of the output; the Profiles tab keeps one row per account. Off by default. It changes nothing about the engagement figures, which are worked out from those posts either way. This only decides whether the posts ride along in the row.boolean
maxItemsStop after this many profiles from the list above. Leave it empty to read the whole list. Useful while testing, because you pay per profile.integer
concurrencyHow many profiles are read in parallel. The default of 6 is the setting that keeps the data most complete; raise it for speed on large lists, lower it if you are supplying your own proxy servers and they are few.integer
sessionCookiesLeave this empty. Profiles are read logged out and that answers almost every handle. On the rare handle every public surface refuses, the run retries once with a cookie you paste here, using your account and your own rate limit; without one you get an uncharged BLOCKED diagnostic row instead. In Chrome: F12 -> Application -> Cookies -> instagram.com, copy the sessionid value (or paste the whole cookie string).array
proxyUrlsLeave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.array

What you get

A structured dataset — each result includes fields like:

usernamefullNamefollowersCountfollowsCountpostsCountverifiedprivatelimitedDataaccountAbout.countryaccountAbout.dateJoinedaccountAbout.accountAgeYearsaccountAbout.formerUsernameCountengagement.engagementRateengagement.avgLikesengagement.avgCommentsengagement.postsPerWeekengagement.daysSinceLastPostengagement.postsAnalysedsignals.followerTiersignals.followerToFollowingRatiosignals.hasContactInfocategoryNamebusinessEmailbusinessPhoneNumberexternalUrllatestPostsbiographyprofilePicUrlHD

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

1 ready-to-run use cases

Instagram Follower Count Checker - Bulk Usernames

Check Instagram follower counts in bulk. Paste usernames and get followers, following, post count, bio and verified flag. No login.

Related tools in Social Media Scrapers

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

Instagram Reel Scraper iconSocial Media Scrapers

Instagram Reel Scraper

Scrape reels from any public Instagram profile. Play counts, likes, comments, captions, duration, MP4 and cover links, audio. $0.35 per 1,000 reels.

Ready to run — no setup

LinkedIn Post Search Scraper iconSocial Media Scrapers

LinkedIn Post Search Scraper

Scrape public LinkedIn posts by keyword: author, text, exact date, reactions, comments and post URL. No login or cookies. $0.90 per 1,000 posts.

1 use cases

LinkedIn Profile Search Scraper iconSocial Media Scrapers

LinkedIn Profile Search Scraper

Find public LinkedIn profiles by keyword, title, company, school or location: name, headline, role, profile URL. No login. $0.50 per 1,000.

2 use cases

YouTube Shorts Scraper iconSocial Media Scrapers

YouTube Shorts Scraper

Scrape YouTube Shorts by channel or keyword. Titles, ids, URLs, exact views and likes, publish dates, thumbnails. No API key. $0.40/1k.

Ready to run — no setup

TikTok Scraper - Profiles, Videos, Hashtags & Search iconSocial Media Scrapers

TikTok Scraper - Profiles, Videos, Hashtags & Search

Scrape TikTok profiles, videos, hashtags and search. Play, like, comment and share counts. No login needed from you. $0.25 per 1,000.

5 use cases

Instagram Scraper - Profiles, Posts & Reels (No Login) iconSocial Media Scrapers

Instagram Scraper - Profiles, Posts & Reels (No Login)

Scrape Instagram profiles, posts and reels as JSON: followers, caption, likes, comments, media URLs. No login or API key. $0.45 per 1,000 items.

8 use cases

See all Social Media Scrapers →

Instagram Profile Scraper: bios, exact follower counts and contact details from a list of handles

Paste handles or profile links and get one row per account: the bio, the exact follower, following and post counts, the verified and private flags, the business category, and whatever e-mail, phone and links the account publishes. Making an account private hides the posts and nothing else, so private accounts still come back with a full row.

One thing to know before you build on it. The engagement figures are arithmetic over the recent posts Instagram hands a logged-out reader, which is 6 to 12 of them at most. That makes them a picture of current form, not a lifetime average, and on some accounts those posts do not come back at all. Every row carries postsAnalysed so you can see which you got.

InputHandles, @handles or instagram.com/... profile links
OutputOne row per profile
Ceiling1,000 profiles per run
Account neededNone from you
Price$0.70 per 1,000 profiles, flat on every plan

🔍 What Instagram Profile Scraper does

You hand it a list of accounts, it hands back a table. nasa, @nasa, instagram.com/nasa and https://www.instagram.com/nasa/ all mean the same thing, so you can mix whatever forms your list already has. Duplicates are dropped before anything is charged.

Counts come back exact, not rounded the way the page prints them: 104,352,629 followers, not "104M". Each field comes from a surface known to report it correctly, so a field nobody could answer for comes back null instead of wrong.

Every row also carries two worked-out blocks at no extra cost. engagement has average and median likes and comments, an engagement rate against followers, posts per week, when the account last posted, what share of recent posts are video, and its most-engaged recent post. signals has the follower tier, the follower-to-following ratio, whether there is a real contact route, link count and bio length.

📥 What you give it

{
  "usernames": ["nasa", "@gopro", "https://www.instagram.com/natgeo/"],
  "maxItems": 50
}
FieldDefaultWhat it is
usernamesnoneOne entry per profile, in any of the forms above. Up to 1,000 per run.
includeAccountAboutfalseAdds country, join date and how many handles the account has used before. Priced separately, and it needs a paid Apify plan.
includeLatestPostsoffAdds the recent posts themselves to each row, using the same field names as our post scraper. They also get their own tab in the output.
maxItemsnoneStop after this many profiles, counting from the top. Leave it empty to read the whole list.
concurrency6How many profiles are read at once, 1 to 12. Higher finishes a long list sooner.
sessionCookiesnoneOptional. Your own Instagram cookie, used to retry a handle that every public route refused.
proxyUrlsnoneLeave it empty unless you have your own servers you want the traffic to leave through.

Run it with the input empty and you get one labelled sample row, free, so you can look at the shape before spending anything.

📤 What you get back

A real row from a real run. The picture links and the bio are cut short so the block stays readable, and relatedProfiles is trimmed to one of its 49 entries:

{
  "ok": true,
  "charged": true,
  "recordType": "profile",
  "inputUrl": "https://www.instagram.com/nasa/",
  "id": "528817151",
  "username": "nasa",
  "url": "https://www.instagram.com/nasa/",
  "fullName": "NASA",
  "biography": "Making the seemingly impossible, possible. ...",
  "externalUrl": "https://www.nasa.gov/",
  "externalUrls": [
    { "title": "NASA.gov Homepage", "url": "https://www.nasa.gov", "linkType": "external" },
    { "title": "NASA Internships", "url": "http://intern.nasa.gov", "linkType": "external" }
  ],
  "followersCount": 104352629,
  "followsCount": 91,
  "postsCount": 4928,
  "verified": true,
  "private": false,
  "isBusinessAccount": true,
  "isProfessionalAccount": true,
  "categoryName": "Government Agencies",
  "businessCategoryName": "Government Agencies",
  "businessEmail": null,
  "businessPhoneNumber": null,
  "businessAddress": null,
  "profilePicUrl": "https://scontent-lga3-3.cdninstagram.com/v/t51.2885-19/...",
  "profilePicUrlHD": "https://scontent-lga3-3.cdninstagram.com/v/t51.2885-19/...",
  "highlightReelCount": 6,
  "igtvVideoCount": 171,
  "hasChannel": false,
  "joinedRecently": false,
  "pronouns": [],
  "relatedProfiles": [
    { "id": "524549267", "username": "microsoft", "fullName": "Microsoft", "isVerified": true, "isPrivate": false, "profilePicUrl": "https://scontent-lga3-3.cdninstagram.com/..." }
  ],
  "emailsFound": [],
  "phonesFound": [],
  "bioHashtags": [],
  "bioMentions": [],
  "latestPosts": [],
  "fbid": "17841401474538262",
  "dataSource": "profile-api",
  "limitedData": false,
  "scrapedAt": "2026-09-21T01:45:24.304Z",
  "accountAbout": { "available": false, "country": null, "dateJoined": null, "accountAgeDays": null, "accountAgeYears": null, "formerUsernames": [], "formerUsernameCount": null, "verifiedOnAboutPanel": null },
  "engagement": { "postsAnalysed": 0, "avgLikes": null, "medianLikes": null, "avgComments": null, "medianComments": null, "engagementRate": null, "engagementPerPost": null, "videoSharePct": null, "avgCaptionLength": null, "postsPerWeek": null, "lastPostAt": null, "daysSinceLastPost": null, "activeLast30Days": null, "topHashtags": [], "topMentions": [], "topPost": null },
  "signals": { "followerTier": "celebrity", "followerToFollowingRatio": 1146732.19, "followsPerPost": 0.02, "hasContactInfo": false, "contactEmailCount": 0, "contactPhoneCount": 0, "externalLinkCount": 5, "bioLength": 44, "hasBioLink": true }
}
FieldWhat it is
idThe numeric account id. It survives a rename, so track it rather than the handle.
followsCountHow many accounts the profile follows. One public surface publishes it and it throttles, so this is null on a small share of rows rather than a guess.
externalUrlsEvery link in the bio when the account uses the multi-link layout. externalUrl is just the first.
emailsFound, phonesFoundAnything written into the bio text, on top of the published business e-mail and phone.
profilePicUrlHDThe largest picture on offer. Signed and time limited, so download what you want to keep.
dataSourceWhich public surfaces answered for this row. Useful when you want to know why a field is null.
limitedDatatrue when Instagram served this profile only through its public embed card. The row has the name, followers, post count, picture and recent posts, but no bio, following count, category, links or contact fields.
latestPostsOnly with includeLatestPosts on: up to 12 recent posts. Each has url, caption, likesCount, commentsCount, timestamp, hashtags, mentions, taggedUsers, coauthorProfiles, locationName, musicTitle, isPinned, likesAndViewCountsDisabled and isCommentsDisabled. A flag Instagram did not send for that post is null, not false, and posts on limitedData rows carry fewer fields.
engagement.postsAnalysedHow many recent posts the figures are based on. 0 means none came back, as above, and the rest of the block is null rather than zero.

🧾 Reading the output

Three kinds of row land in your dataset, and one flag separates them.

RowHow to spot itBilled
A real profileok: true, charged: true, recordType: "profile"yes
The sample row_sample: true, charged: falseno
A diagnostic_diagnostic: true, charged: false, an errorCodeno

Filter on charged == true and you have your profiles. Treat that flag as the marker that tells a real row apart from a sample or a diagnostic, not as a receipt.

CodeWhat it means
NOT_FOUNDNo public account at that handle any more.
BLOCKEDEvery public route refused that handle this run. Re-running usually picks it up.
TIME_BUDGETThe run ran out of time before reaching that handle.
STOPPED_EARLYInstagram refused a long run of handles in a row, so the run stopped instead of working through the rest. unreadUsernames lists the handles it never reached.
BAD_INPUTNothing in your list could be read as a handle or a profile link.
ABOUT_PLAN_REQUIREDYou ticked the About box on a free Apify plan. Everything else still arrives.
ABOUT_PARTIAL, ABOUT_RATE_LIMITED, ABOUT_UNAVAILABLEThe About lookup stopped part way through the run. The profile rows are unaffected.

A diagnostic row never fails the run and is never billed.

▶️ How to run it

1. Open Instagram Profile Scraper and click Try for free. 2. Paste your handles into Instagram usernames or profile URLs, one per line. 3. Set Maximum profiles while you are testing, since you pay per profile. 4. Click Start. 5. Download the dataset as JSON, CSV or Excel, or pull it from the Apify API.

💰 How much does it cost?

$0.70 per 1,000 profiles. Flat on every Apify plan, no volume tiers.

The About panel is the one extra: tick Country, join date and former usernames and those profiles cost $5.00 per 1,000 on top. Leave the box alone and you pay the profile price only.

Duplicate handles are collapsed before the run starts, so you pay once per account. The sample row, every diagnostic row and a handle that turns out not to exist cost you nothing.

💡 What people use it for

  • Shortlisting creators. Drop in a few hundred handles, sort by follower count or category, and open

Instagram only for the ones worth it.

  • Enriching a lead list. Business accounts publish a category, an e-mail and a phone, and the bio

often carries a second address.

  • Weekly tracking. Re-run the same list and diff followersCount and postsCount to see who is

growing and who has gone quiet.

  • Cleaning a list. verified, private and the NOT_FOUND rows tell you which handles are still

real accounts.

🚧 What it does not do

  • No follower or following lists. The counts only.
  • No posts unless you ask. latestPosts is empty unless you turn it on, and even then it covers

the recent handful rather than a full history.

  • Nothing behind a private account. A private profile returns its bio, counts and flags. The

content stays private, with latestPosts empty and the engagement block null.

  • followsCount is sometimes null. A null beats a wrong number, and re-running usually

fills it.

  • Some rows come back limited. Now and then Instagram serves a profile only through its public

embed card. Those rows carry limitedData: true, are charged like any other row, and a later re-run usually returns the full profile.

  • Country does not show on every account. Instagram puts that line on larger accounts. Smaller

ones still return the join date with country null.

  • Former usernames come back as a count, not as names. Instagram keeps the names behind a tap.
  • Entries that are not handles are dropped quietly, so check your list if a row is missing.
  • 1,000 profiles per run. Split a bigger list across runs.
  • Picture links are signed and expire. Counts are a snapshot, so two runs an hour apart disagree

slightly on a big account and neither is wrong.

🧭 Which Instagram scraper do you need?

If you wantUse
One row per account from a list of handlesThis one
A profile plus the posts on its gridInstagram Scraper
One post or reel you already have the link forInstagram Post Scraper
Posts under a hashtagInstagram Hashtag Scraper
Reels found by keywordInstagram Reels Search

❓ Questions people ask

Do I need an Instagram account? No. Profiles are read logged out and that answers almost every handle. The cookie field is there for the rare one that gets refused.

Can it get e-mails and phone numbers? It returns the business e-mail and phone when the account publishes them, plus anything written into the bio text. Personal accounts usually publish neither.

What happens to a handle that no longer exists? One free NOT_FOUND row, and the run carries on down your list.

Is scraping Instagram legal? This reads public profile pages only, never private accounts or messages. Results can still contain personal data, which GDPR and similar laws cover, so have a reason for collecting it. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Include the handles you used and the run ID, and the log is enough for us to see what happened.