Instagram Profile Scraper - $0.55 per 1,000 Profiles avatar

Instagram Profile Scraper - $0.55 per 1,000 Profiles

Deprecated

Pricing

from $0.55 / 1,000 profile scrapeds

Go to Apify Store
Instagram Profile Scraper - $0.55 per 1,000 Profiles

Instagram Profile Scraper - $0.55 per 1,000 Profiles

Deprecated

The cheapest Instagram profile scraper on the market: $0.55 per 1,000 profiles. Handles in, one row per profile out - full bio, follower/following/post counts, verified and private flags, business category, bio links, HD avatar, related profiles and optional latest posts. No login.

Pricing

from $0.55 / 1,000 profile scrapeds

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Instagram Profile Scraper

Give it Instagram handles, get one row per public profile back: full biography, follower / following / post counts, verified and private flags, professional-account and business-category fields, every bio link, the HD avatar, the account's related-profile suggestions, and — if you tick the box — its 12 most recent posts.

No Instagram account. No cookies to paste. No session token. No proxy of your own. Type handles, get rows.

Price

$0.55 per 1,000 profiles, plus $0.0000125 to start a run.

That makes it the cheapest Instagram profile scraper on the market. The rate is also flat: the same $0.55 on the free plan as on any paid plan, with no volume tiers, no minimum spend and no plan gates, so the number below is what you pay from your very first run.

ProfilesCost here
100$0.055
1,000$0.55
10,000$5.50
100,000$55.00

Plus the $0.0000125 run-start fee, once per run, whatever the size of the run.

What is actually billed

  • profile-scraped — $0.00055. Charged once, immediately after a real profile row is written to the dataset. One charge per profile, never per post: turning on "include the latest posts" adds up to 12 posts to the row and costs nothing extra.
  • apify-actor-start — $0.0000125 per GB of run memory. The Actor's default memory is 1 GB, so that is $0.0000125 per run.
  • Free: everything else. The sample row a run with no input returns is not charged. Diagnostic rows (profile not found, blocked, bad input) are not charged. A run that finds nothing costs the start fee alone.

There are no add-on events

profile-scraped is the only result event this Actor has. Switching on includeLatestPosts adds up to 12 posts to the row and costs nothing extra; neither do relatedProfiles, the HD avatar, the full externalUrls array or the e-mail/phone extraction — they are all part of the same profile row. Nothing is metered per page, per request or per proxy gigabyte, so the table above plus the fractional start fee is the entire bill. A run you cancel mid-way is billed only for the rows it had already written.

Input

FieldWhat it does
usernamesInstagram handles. nasa, @nasa and https://www.instagram.com/nasa/ are all accepted.
profileUrlsSame thing, if you would rather paste URLs. Merged with usernames, de-duplicated.
includeLatestPostsOff by default. On, each row gets latestPosts — up to 12 recent posts with caption, hashtags, mentions, media URLs and timestamp.
resultsLimitStop after this many profiles. Leave empty to do every handle you supplied. Ceiling 1,000.
maxConcurrencyHow many profiles to fetch at once. Default 8, ceiling 16.
proxyConfigurationLeave empty. See "How it works" for why.
{
"usernames": ["nasa", "natgeo", "@nike"],
"profileUrls": ["https://www.instagram.com/spotify/"],
"includeLatestPosts": true,
"resultsLimit": 10
}

usernames is a prefill, not a default — running with genuinely empty input returns one labelled sample row, uncharged, so you can see the row shape before spending anything.

Output

A real row, trimmed for length (this is nasa, run 2026-08-15):

{
"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/",
"externalUrlShimmed": "https://l.instagram.com/?u=https%3A%2F%2Fwww.nasa.gov%2F&e=AUA5zD4…",
"externalUrls": [
{ "title": "NASA.gov Homepage", "url": "https://www.nasa.gov", "lynxUrl": "https://l.instagram.com/?u=…", "linkType": "external" },
{ "title": "NASA Internships", "url": "http://intern.nasa.gov", "lynxUrl": "https://l.instagram.com/?u=…", "linkType": "external" }
],
"followersCount": 104395191,
"followsCount": 92,
"postsCount": 4882,
"hasChannel": false,
"highlightReelCount": 5,
"igtvVideoCount": 171,
"isBusinessAccount": true,
"isProfessionalAccount": true,
"joinedRecently": false,
"businessCategoryName": "Government Agencies",
"categoryName": null,
"businessEmail": null,
"businessPhoneNumber": null,
"businessContactMethod": "CALL",
"businessAddress": null,
"private": false,
"verified": true,
"profilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/29090066_159271188110124_…",
"profilePicUrlHD": "https://scontent.cdninstagram.com/v/t51.2885-19/29090066_159271188110124_…",
"fbid": "17841401474538262",
"relatedProfiles": [
{ "id": "1067259270", "username": "nasagoddard", "fullName": "NASA Goddard", "isVerified": true, "isPrivate": false, "profilePicUrl": "https://…" }
],
"latestPosts": [
{
"id": "3963668990156895830",
"type": "Video",
"shortCode": "DcBx_I1iHZW",
"url": "https://www.instagram.com/p/DcBx_I1iHZW/",
"caption": "Check out the eclipse from 50,000 feet in the air!…",
"hashtags": ["NASA", "Eclipse2026", "Aircraft"],
"mentions": [],
"likesCount": 187209,
"commentsCount": 1234,
"videoViewCount": 4026346,
"displayUrl": "https://scontent.cdninstagram.com/v/t51.82787-15/774149093_…",
"images": ["https://scontent.cdninstagram.com/v/t51.82787-15/774149093_…"],
"alt": "Video by NASA on August 14, 2026…",
"isVideo": true,
"timestamp": "2026-08-14T18:02:41.000Z",
"ownerUsername": "nasa",
"ownerId": "528817151"
}
],
"emailsFound": [],
"phonesFound": [],
"bioHashtags": [],
"bioMentions": [],
"pronouns": [],
"dataSource": "web_profile_info",
"scrapedAt": "2026-08-15T02:31:07.882Z"
}

The field names follow the conventions used across Instagram profile Actors — username, fullName, followersCount, followsCount, postsCount, verified, private, isBusinessAccount, businessCategoryName, externalUrl, externalUrls, profilePicUrl, profilePicUrlHD, relatedProfiles, latestPosts, highlightReelCount, igtvVideoCount, fbid, inputUrl — so an existing pipeline can be pointed at this Actor without editing the code that reads the rows. Everything extra (emailsFound, phonesFound, bioHashtags, bioMentions, businessEmail, businessPhoneNumber, businessAddress, isProfessionalAccount, dataSource) is appended after those.

Field coverage

Measured on a real 40-account run on the platform, 2026-08-15. 40 of 40 handles returned a row.

FieldPresent
username, id, url, followersCount, verified, private100%
profilePicUrl, profilePicUrlHD, fbid, highlightReelCount100%
latestPosts (with includeLatestPosts on)100%
fullName98%
followsCount95%
isBusinessAccount, igtvVideoCount93%
externalUrl, externalUrls90%
biography88% (the rest genuinely have an empty bio)
postsCount83%
relatedProfiles70% (Instagram returns none for some accounts)
businessCategoryName20%
businessEmail, businessPhoneNumber0% — see below

Missing values are null. Nothing is ever guessed or interpolated.

Limits

Read this part before you build on it.

  • businessEmail and businessPhoneNumber were null on every one of the 22 accounts tested, large brands and small shops alike. Instagram no longer returns public contact details on the logged-out endpoints. The fields are still in the row, so the row shape stays stable for existing pipelines, but do not plan a lead-gen pipeline around them. What does work: any e-mail or phone number an account writes into its bio text is extracted into emailsFound and phonesFound.
  • postsCount is null on about 17% of accounts. Instagram's primary profile endpoint currently returns HTTP 400 for a large minority of professional accounts (see "How it works"), and the fallback path can only recover the exact post total when the profile page states it exactly. When the page rounds it — "9.5M Posts" — the field is left null rather than reporting a rounded number as if it were a count. Follower and following counts are exact on every path.
  • Public profiles only. A private account returns its bio, counts and avatar — that is all Instagram shows a logged-out visitor — with private: true. Its posts are not accessible and no attempt is made to get them.
  • latestPosts is up to 12 posts, never more. This Actor reads profiles. It does not paginate a feed, and it does not scrape comments, followers, stories, tagged posts or hashtags.
  • Counts move. A followers number is a reading at scrapedAt, not a stable identifier. Two runs a minute apart on a large account will differ by thousands.
  • A handle that does not exist returns an uncharged NOT_FOUND diagnostic row, not a crash and not a charge.
  • 1,000 profiles per run (resultsLimit ceiling), and the run timeout is 5 minutes. 40 profiles took 77 seconds at the default concurrency of 8, so a run covers a few hundred handles comfortably; for very large lists, split them across runs or raise maxConcurrency.

FAQ

Do I need an Instagram account, cookies or a session id? No. Nothing to log in to and nothing to paste. Every endpoint used here is one a logged-out visitor hits.

Do I need to buy proxies? No. Proxy rotation is built in and its cost is already inside the $0.55.

What does 1,000 profiles cost? $0.55, plus the $0.0000125 start fee.

Is this really the cheapest Instagram profile scraper? Yes — $0.55 per 1,000 profiles, and it is the same $0.55 on every plan rather than a headline rate you only reach at high volume. The full billing mechanics are spelled out under "Price".

Can I switch from another Instagram profile Actor without changing my code? Usually. Input field names follow the common conventions used across similar Actors — usernames is the same field it is everywhere — and the output field names match too, so switching is normally a drop-in change. An "about section" block (date joined, country) that some Actors offer has no equivalent here; in the other direction, this Actor returns fields (emailsFound, phonesFound, bioHashtags, bioMentions, pronouns, dataSource) that most do not.

Does it return e-mail addresses? Only ones written into the bio text, in emailsFound. Instagram's public contact-e-mail field came back empty on every account tested — see "Limits".

How fast is it? 40 profiles in 77 seconds on the platform at the default settings, half of them on the slower fallback path. Accounts on the fast path take 1.5–2 seconds each.

Can I export to CSV or Excel? Yes — Apify exports the dataset as JSON, CSV, Excel or XML, and the same data is available over the REST API.

What happens if I run it with no input? One labelled sample row, uncharged, and the run finishes as SUCCEEDED.

Is this affiliated with Instagram or Meta? No. It reads public profile data. Check Instagram's terms and your own local rules before using the output commercially.

How it works

Instagram's logged-out profile API is metered per IP address, not per account, and it answers a spent address with 401 "Please wait a few minutes before you try again" — an HTTP status, not a captcha. The fix is a large pool you can hop through rather than a fast pool you keep hitting, so this Actor requests a fresh Apify datacenter address for every attempt. Datacenter addresses are not billed per gigabyte, which matters because Instagram answers a profile request with 100–800 KB. Residential proxy is deliberately not used: it is metered by the gigabyte, and at that response size the bandwidth alone would cost more per row than a row is priced at. The cheap egress is the reason this price is possible.

Plain Node fetch is refused from every address — Instagram is judging the TLS handshake, not the IP. Requests go through impit with a genuine Chrome fingerprint instead, which returns HTTP 200 from the same addresses in the same second.

There is one more thing, and it is the reason this Actor returns rows for accounts where a single-endpoint scraper returns nothing. As of 2026-08-14 Instagram's main profile endpoint answers HTTP 400 for a large minority of professional accounts:

{"message":"Asset asset://laser.provider/ig_business_category_subvertical has been deleted.
You cannot use this schema"}

That is a bug in Instagram's own schema, not a block: it is deterministic per account and it reproduces from every address, so retrying and rotating cannot fix it. Measured across 20 well-known handles, 9 of 20 fail this way — natgeo, netflix, adidas, beyoncé, starbucks, airbnb, leomessi, shakira and hubspot among them. Any scraper that calls only that endpoint returns nothing for exactly those accounts.

So this one falls down a ladder instead of failing:

  1. web_profile_info with the ordinary web app id — the complete answer when it works.
  2. The same endpoint with a different app id, which is not subject to the broken schema. Its descriptive fields are good; its follower/following and post counts are not, so they are dropped rather than reported.
  3. The logged-out profile page, whose embedded payload carries the exact follower and following counts and the recent posts, with the post total read from the page's own meta description.
  4. The feed-by-username route, used only to recover recent posts when rung 3 is rate limited.

Rungs 2, 3 and 4 are merged into one row and dataSource records which of them produced it. In the 40-account run above, 21 rows came from rung 1 and 19 needed the ladder — and all 40 returned.