Instagram Profile Scraper: Instagram Followers Count, Bio avatar

Instagram Profile Scraper: Instagram Followers Count, Bio

Pricing

from $1.35 / 1,000 profiles

Go to Apify Store
Instagram Profile Scraper: Instagram Followers Count, Bio

Instagram Profile Scraper: Instagram Followers Count, Bio

Scrape Instagram profile data with no login: by username, link or id, or an Instagram user search by keyword. Exact followers count, following, posts, bio with links, e-mails and phones, category, business flag, 12 latest posts, engagement rate, related accounts. Business profiles come back whole.

Pricing

from $1.35 / 1,000 profiles

Rating

0.0

(0)

Developer

Hyperbach

Hyperbach

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

4

Monthly active users

a day ago

Last modified

Share

Instagram profiles as data, logged out: usernames, profile links, profile ids or post links in — or keywords that find accounts — and one row per profile out. Each row has the exact follower, following and posts counts (never a rounded '12.6M'), the whole bio with its links and the e-mails and phones written in it, the verified, private, business and professional flags, the category, the HD profile picture, the 12 latest posts with their likes, comments, views and the pinned flag, the IGTV videos, Instagram's related accounts, the highlights and, on request, the latest reels with their plays — plus engagement averages over the posts. Business profiles that the usual profile endpoint refuses (about 4 in 10 big brands, more than 4 in 5 ordinary businesses) are read whole by a fallback route instead of coming back as empty rows. A private, age-restricted, missing or unavailable profile is a free row that says which. No login, no Instagram account, no cookie, proxies handled for you.

Why this Instagram profile scraper

  • Business profiles come back whole. For many business accounts Instagram's profile endpoint answers an error instead of the profile (20 of the 49 big brands of our test list, natgeo among them; 89 of 104 ordinary businesses). Profile scrapers that read only that endpoint return those accounts as thin rows with no posts, no related accounts and no posts count. This Actor reads them by a fallback of five logged-out calls: the counts, the bio and links, the category and account type, the 12 latest posts with their likes and comments, the related accounts and the exact posts count. Each row says which route read it (record_source).
  • Exact counts, read in the run. Followers, following and posts are the exact figures at the read, never a rounded '12.6M' and never a cached copy. The posts count of a fallback profile comes from Instagram's own embed of the profile, which equals the profile record's count; its lagging follower figure is never used.
  • Honest rows for every input. A private account gives a free row with its public fields (name, bio, counts, picture); an age-restricted brand (such as a spirits or beer brand) gives a free row with its follower count, page category and badge from Meta's Ad Library; a missing handle is not_found only when two connections agree; a value that names nothing is invalid. Only public profiles read whole are charged, and a profile given twice (a username and its id, a post link of the same author) is one row and one charge.
  • No ten retries on a restricted handle. An unavailable or restricted profile is told by Instagram's own answer in two or three calls, not retried until a timeout.
  • Related accounts that are not empty. When a profile's record lists no related accounts, Instagram's suggestions for the profile are asked instead (they filled the list for 2 of 4 creators whose record had none). With relatedDepth the related accounts become rows of their own, one to three levels deep.
  • Keywords that find accounts. A keyword asks the Threads account search and Meta's Ad Library page search, the two logged-out searches that name Instagram accounts, and reads each account found as a full profile row.
  • Plain HTTP, no browser, no login. Instagram's own logged-out answers through rotating connections: no cookie, no account of yours, nothing to configure. A profile the record serves is one call; five profiles are read at a time. On our test 200 profiles (88 of them by the fallback route) came out in 98 seconds, about 127 a minute, the first row 4 seconds after the start (4 to 19 seconds on our other runs: a slow connection is replaced after 5 seconds).

Who it's for

  • Marketers and influencer teams — creators' and brands' exact followers, engagement over their latest posts, category and business flag, related accounts to find more like them.
  • Lead generation and sales — business profiles found by keyword with their category, website, bio links and the e-mails and phones written in the bio, filtered by followers or category.
  • Researchers and analysts — a list of accounts read the same way every time, with the route that read each one and a run summary; follower growth between runs with a monitor memory.
  • Developers and data teams — typed rows keyed by the profile id, one row per input whatever happened to it, free rows that say why, and the leader's column names mapped one to one.

Quick start

A few profiles

{
"usernames": [
"humansofny",
"natgeo"
]
}

Profile links, ids and post links mixed

{
"usernames": [
"https://www.instagram.com/nasa/",
"787132",
"https://www.instagram.com/p/DPq5ZpJDZw9/"
]
}

Find accounts by keyword, with their reels' plays

{
"searchQueries": [
"coffee roasters"
],
"maxResultsPerQuery": 10,
"includeReelPlays": true
}

A profile and its related accounts as rows, verified only

{
"usernames": [
"natgeo"
],
"relatedDepth": 1,
"relatedOnlyVerified": true,
"maxItems": 20
}

Follower changes since the last run (for a schedule)

{
"usernames": [
"humansofny",
"natgeo"
],
"monitorStore": "my-watchlist"
}

Output

One row per profile (a public profile charged; a private, restricted, missing or filtered one a free row that says why):

fieldmeaning
statusok (a public profile read whole: charged) or a free row's reason: private (a private account: its public fields only — name, bio, counts, picture — no posts), restricted (Instagram withholds the profile from logged-out visitors, e.g. an age-gated brand: the follower count, page category and badge come from Meta's Ad Library), unavailable (no public profile shown to visitors and no source names it; two exits agree), not_found (no account with this username, id or post: two exits agree), invalid (the value names no profile), filtered (left out by a filter), duplicate (the same profile as another input of the run: read once), no_results (a keyword that found no account), failed (no exit served it: try again), not_read (maxItems, the charge limit or the time limit came first).
status_reasonWhy a free row is free, in words; null on an ok row.
inputThe value you gave that led to this row (a username, a link, an id, a post link or the keyword); on a related account's row, the profile it is related to.
input_typeusername, id, post, search (an account a keyword found), related (an account the related crawl found) or invalid.
found_byinput, search:threads, search:adlib, search:threads+adlib (which account search named it) or related.
search_queryThe keyword that found this account (searchQueries); null otherwise.
search_rankThe account's place in the keyword's joined results (Threads first, then the Ad Library's pages), 1-based.
related_ofThe profile whose related list led to this row (relatedDepth 1 to 3).
related_depthHow many related steps from a profile you gave (1 to 3); null on your own inputs.
idInstagram's numeric user id (pk): one row and one charge per profile a run.
usernameThe username, lower case.
full_nameThe name on the profile.
urlhttps://www.instagram.com/<username>/.
biographyThe whole bio text, line breaks and emoji kept.
bio_hashtagsEvery #hashtag of the bio, without the #, once each.
bio_mentionsEvery @username the bio mentions, without the @, once each.
bio_emailsE-mail addresses written in the bio text, lower case.
bio_phonesPhone numbers written in the bio, as written: a number starting with +, or one next to a phone word or sign (📞, tel, call, WhatsApp). A number with no country code is left as written. The contact button's own e-mail and phone are not shown to logged-out visitors.
bio_linksEvery link of the bio: {title, url, link_type} (the URL is the target, not Instagram's tracking redirect).
external_urlThe profile's website link (the first external bio link).
followersThe exact follower count at the read (never a rounded '12.6M'); on a restricted row, the count Meta's Ad Library gives for the account.
followingThe exact number of accounts the profile follows.
posts_countThe exact number of posts on the profile.
posts_count_sourcerecord (the profile record) or embed (Instagram's profile embed: the exact count for a profile the record route does not serve).
is_verifiedTrue when the profile carries the verified badge.
is_privateTrue for a private account (its row is free and carries no posts).
is_businessTrue for a business account.
is_professionalTrue for a business or creator (professional) account.
account_typepersonal, creator or business.
categoryThe profile's category as Instagram shows it (Cafe, Government Agencies); null when the owner set none (never the text 'None').
business_contact_methodThe contact button's kind when the profile shows one (CALL, TEXT, EMAIL); its e-mail and phone values are shown to logged-in users only.
profile_pic_urlThe profile picture, Instagram's own CDN URL (signed: it expires after a few days).
profile_pic_url_hdThe largest profile picture Instagram serves, its own CDN URL.
highlights_countThe number of story highlights; on a profile the record route does not serve, the exact count up to 10 and null past 10 (highlights_count_min then says 10).
highlights_count_min10 when the profile has more than 10 highlights and only the first 10 are listed; else null.
highlightsThe first highlights the profile lists, {id, title} (up to 10): on every profile the fallback route reads, and on the others with includeHighlights.
igtv_countThe number of IGTV (long) videos; null on a profile served by the fallback route (not served there).
has_channelTrue when the profile runs a broadcast channel.
has_reelsTrue when the profile has reels.
has_threads_badgeTrue when the profile shows its Threads badge.
pronounsThe pronouns the profile shows.
fbidThe profile's Facebook-side id (fbid).
is_joined_recentlyTrue when Instagram marks the account as new.
is_memorializedTrue for a memorialized account, where Instagram says so: on every profile the fallback route reads, and on the others with includeHighlights (the record route does not carry it: null there).
latest_story_atWhen the profile's newest active story was posted (stories live 24 hours); null when it has none. On every profile the fallback route reads, and on the others with includeHighlights.
linked_facebook_pageThe Facebook page the profile links, {name, id}; null when it links none. On every profile the fallback route reads, and on the others with includeHighlights.
is_age_restrictedTrue when Instagram marks the profile as age-restricted (regulated content).
transparency_labelInstagram's label for state-controlled media and the like; null on most profiles.
meta_verifiedTrue when the badge comes from a Meta Verified subscription.
latest_postsThe profile's 12 latest posts, newest first with the pinned ones on top as on the profile: {id, shortcode, url, type (photo, carousel, reel, video), product_type, caption, hashtags, mentions, taken_at, likes (also on a post whose owner hid the count, where Instagram serves it: likes_hidden says so; null on the fallback route's hidden posts), likes_hidden, comments, video_views, plays, is_pinned, alt, display_url, video_url, carousel_items, width, height, owner_username, owner_id, coauthors (null where Instagram names them by id only, on the fallback route), comments_disabled, location, tagged_count, is_paid_partnership}. Empty for a private account.
posts_noteWhat the latest posts lack and why, when they come from the fallback route (no video views, alt text or location on that list).
latest_igtvThe latest IGTV videos with their title and duration, in the post shape; null on a profile served by the fallback route.
latest_reelsWith includeReelPlays: the 12 latest reels, {shortcode, id, url, taken_at, plays, likes, comments, duration}.
avg_reel_playsThe average plays of latest_reels.
reels_statusserved, no_reels, refused (the reels page was not served: try again) or not_asked (includeReelPlays off).
related_profilesInstagram's related accounts for the profile (up to 50): {username, id, full_name, is_verified, is_private, profile_pic_url}.
related_countHow many related accounts the row carries.
related_statusserved (the profile record's list), served_by_suggestions (Instagram's suggestions for the profile, asked when the record lists none or the record is not served), none_at_source (Instagram lists none) or refused (not served on this run).
engagementOver the latest posts, pinned posts left out (a hidden-likes post counts where its count is served): {posts_read, avg_likes, avg_comments, median_likes, avg_video_views, engagement_rate ((avg likes + avg comments) ÷ followers), posts_per_week, last_post_at, followers_to_following}.
record_sourcerecord (Instagram's profile record: the whole row in one call), bundle (the fallback for a profile whose record Instagram does not serve: five logged-out calls) or adlib (a restricted profile's Ad Library figures).
facebook_page_categoryOn a restricted row: the category of the Facebook page that names the account in Meta's Ad Library.
change_typeWith monitorStore: new (first read by this memory), changed or unchanged since its last delivery.
changed_fieldsWith monitorStore: which watched fields moved (followers, following, posts_count, username, full_name, biography, external_url, category, is_verified, is_private, account_type, latest_codes).
previous_read_atWith monitorStore: when this memory last delivered the profile.
followers_changeWith monitorStore: followers now minus at the last delivery.
following_changeWith monitorStore: following now minus at the last delivery.
posts_changeWith monitorStore: posts count now minus at the last delivery.
new_postsWith monitorStore: the shortcodes of the latest posts the last delivery did not list.
scraped_atWhen the row was read, UTC.

Example record:

{
"status": "ok",
"status_reason": null,
"input": "humansofny",
"input_type": "username",
"found_by": "input",
"search_query": null,
"search_rank": null,
"related_of": null,
"related_depth": null,
"id": "242598499",
"username": "humansofny",
"full_name": "Humans of New York",
"url": "https://www.instagram.com/humansofny/",
"biography": "New York City, one story at a time.\nCreated by Brandon Stanton\nInquiries/Collabs: honybrandon@gmail.com\nLittle Humans Board Book Below:",
"bio_hashtags": [],
"bio_mentions": [],
"bio_emails": [
"honybrandon@gmail.com"
],
"bio_phones": [],
"bio_links": [
{
"title": "Little Humans Board Book",
"url": "https://us.macmillan.com/books/9780374395476/littlehumans/",
"link_type": "external"
}
],
"external_url": "https://us.macmillan.com/books/9780374395476/littlehumans/",
"followers": 12639616,
"following": 761,
"posts_count": 5877,
"posts_count_source": "record",
"is_verified": true,
"is_private": false,
"is_business": false,
"is_professional": true,
"account_type": "creator",
"category": null,
"business_contact_method": null,
"profile_pic_url": "https://scontent-ord5-2.cdninstagram.com/v/t51.2885-19/488057622_654626203990134_4938995104135839433_n.jpg?[signed]",
"profile_pic_url_hd": "https://scontent-ord5-2.cdninstagram.com/v/t51.2885-19/488057622_654626203990134_4938995104135839433_n.jpg?[signed]",
"highlights_count": 1,
"highlights_count_min": null,
"highlights": [
{
"id": "17888766853687923",
"title": "Humans"
}
],
"igtv_count": 0,
"has_channel": false,
"has_reels": true,
"has_threads_badge": true,
"pronouns": [],
"fbid": "17841401154973790",
"is_joined_recently": false,
"is_memorialized": false,
"latest_story_at": null,
"linked_facebook_page": null,
"is_age_restricted": false,
"transparency_label": null,
"meta_verified": false,
"latest_posts": [
{
"id": "3741054891297971261",
"shortcode": "DPq5ZpJDZw9",
"url": "https://www.instagram.com/reel/DPq5ZpJDZw9/",
"type": "reel",
"product_type": "clips",
"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 connection, and we have some extra special moments coming in the final week. Thanks to all of you who have made the pilgrimage to Grand Central these last few days. And I hope to see many more of you as the clock ticks down to the closing ceremony next Sunday. Note: The Vanderbilt Hall exhibit is closed today for a prescheduled event, but will reopen tomorrow and remain open until the conclusion of the installation.",
"hashtags": [],
"mentions": [],
"taken_at": "2025-10-11T13:27:07Z",
"likes": 107895,
"likes_hidden": false,
"comments": 980,
"video_views": 1035933,
"plays": null,
"is_pinned": true,
"alt": null,
"display_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.71878-15/562558918_1458293865288733_531942526782989329_n.jpg?[signed]",
"video_url": "https://scontent-ord5-1.cdninstagram.com/o1/v/t2/f2/m86/AQOZS_IaHCgcUdg7VqoJnQrUb7g2tVaafy9FYlu-IYpFSbBzMOdFdlOw-iC9C7Vvp6Fiv1-Kgr0Y6fQ1w5oir21dPf9IVagmILJ0t-g.mp4?[signed]",
"carousel_items": null,
"width": 640,
"height": 1136,
"owner_username": "humansofny",
"owner_id": "242598499",
"coauthors": [],
"comments_disabled": false,
"location": null,
"tagged_count": 0,
"is_paid_partnership": null
},
{
"id": "3986064511875180730",
"shortcode": "DdRWI3yHGi6",
"url": "https://www.instagram.com/p/DdRWI3yHGi6/",
"type": "carousel",
"product_type": null,
"caption": "This is one of the stories from Dear New York; a collection of hundreds of portraits and written stories from the streets of NYC. The most beautiful and complete of the Humans of New York books; it’s currently only $15.99 on Amazon— which is a full 65 percent off. Link in bio.",
"hashtags": [],
"mentions": [],
"taken_at": "2026-09-14T14:25:40Z",
"likes": 38345,
"likes_hidden": false,
"comments": 534,
"video_views": null,
"plays": null,
"is_pinned": false,
"alt": null,
"display_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.82787-15/810051818_18649177978038500_7894747996650689132_n.jpg?[signed]",
"video_url": null,
"carousel_items": [
{
"type": "photo",
"display_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.82787-15/810051818_18649177978038500_7894747996650689132_n.jpg?[signed]",
"video_url": null
},
{
"type": "photo",
"display_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.82787-15/810623400_18649177996038500_4881994946749497834_n.jpg?[signed]",
"video_url": null
}
],
"width": 1080,
"height": 1440,
"owner_username": "humansofny",
"owner_id": "242598499",
"coauthors": [],
"comments_disabled": false,
"location": null,
"tagged_count": 0,
"is_paid_partnership": null
}
],
"posts_note": null,
"latest_igtv": [],
"latest_reels": [
{
"shortcode": "DewvR7fMhr_",
"id": "4012915208278383359",
"taken_at": "2026-10-21T15:37:37Z",
"plays": 1406324,
"likes": 81535,
"comments": 797,
"duration": 145.819,
"url": "https://www.instagram.com/reel/DewvR7fMhr_/"
},
{
"shortcode": "Ddt2AXassp7",
"id": "3994085964203084411",
"taken_at": "2026-09-25T16:04:47Z",
"plays": 1263542,
"likes": 25473,
"comments": 608,
"duration": 91.252,
"url": "https://www.instagram.com/reel/Ddt2AXassp7/"
}
],
"avg_reel_plays": 2419441.7,
"reels_status": "served",
"related_profiles": [
{
"username": "refinery29",
"id": "2983181",
"full_name": "Refinery29",
"is_verified": true,
"is_private": false,
"profile_pic_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.2885-19/476903204_2113454765748440_157479314747860263_n.jpg?[signed]"
},
{
"username": "subwaytakes",
"id": "58262011178",
"full_name": "SubwayTakes with Kareem Rahma",
"is_verified": true,
"is_private": false,
"profile_pic_url": "https://scontent-ord5-2.cdninstagram.com/v/t51.2885-19/401856520_356940863507252_7800533169247318656_n.jpg?[signed]"
},
{
"username": "trevornoah",
"id": "31115504",
"full_name": "Trevor Noah",
"is_verified": true,
"is_private": false,
"profile_pic_url": "https://scontent-ord5-1.cdninstagram.com/v/t51.82787-19/714630916_18589258414011505_5138183321255507866_n.jpg?[signed]"
}
],
"related_count": 13,
"related_status": "served",
"engagement": {
"posts_read": 9,
"avg_likes": 92941.2,
"avg_comments": 928.8,
"median_likes": 71164,
"avg_video_views": 953599.3,
"engagement_rate": 0.007427,
"posts_per_week": 0.65,
"last_post_at": "2026-10-21T15:37:37Z",
"followers_to_following": 16609.22
},
"record_source": "record",
"facebook_page_category": null,
"change_type": null,
"changed_fields": null,
"previous_read_at": null,
"followers_change": null,
"following_change": null,
"posts_change": null,
"new_posts": null,
"scraped_at": "2026-10-27T20:53:46Z"
}

Pricing

Pay for the public profiles a run delivers, plus one run start; no platform usage is billed to you. The profile price falls with your Apify plan.

eventunitFreeStarterScaleBusiness
Profile (profile)per 1,000$2.70$2.295$1.89$1.35
Run start (start)per run$0.0039$0.0039$0.0039$0.0039

A profile is $2.70 per 1,000 on the Free plan ($0.0027 a row) and $2.295 on Starter, whatever found it (a username, a link, an id, a keyword or a related account) and whatever it carries: the 12 latest posts, the related accounts, the engagement block, and the reels' plays and the highlights when you ask for them are inside the row's price. Each run that delivers a profile also pays the run start, $0.0039 once; a run that delivers none pays nothing at all. So one profile costs $0.0066 on the Free plan and $0.006195 on Starter; 50 profiles $0.1389 and $0.11865; 1,000 profiles $2.7039 and $2.2989; every input of a run shares one start. Free: a private account's row (its public fields), an age-restricted, missing or unavailable profile, a value that names nothing, a profile given twice (one row, one charge), a profile a filter leaves out, a keyword with no account, and a profile left unread at a cap or the time limit. A run that stops early (a timeout, an abort) is charged for the profiles it delivered. maxItems counts the charged profiles. Before the first request the log names the price of a profile at your plan, the run start and the most the run can cost: each value you give is one profile at most, each keyword maxResultsPerQuery (up to 25), and with relatedDepth each profile adds at most maxRelatedPerProfile related accounts (50 when it is 0, the most Instagram lists) a level. That bound grows fast with the depth, while real lists are shorter: on our ordinary profiles a related list held 0 to 39 accounts (30 of 58 none), and a coffee roaster's whole crawl at depth 1 gave 37 profiles. Set maxItems or a charge limit for a lower maximum. Enterprise plans have their own rates — the Actor's Pricing tab shows the price for your plan.

Usage patterns

  • What to give — usernames: usernames (natgeo, @natgeo), profile links in any form (instagram.com/natgeo/, parameters such as ?igsh= dropped, m. and instagr.am links, a reels or tagged tab, a story link), numeric profile ids (787132), or post and reel links (the author's profile is read). searchQueries: keywords that find accounts. A value repeated is read once; a value that names nothing (a hashtag or location page, another site, a value with a space) is a free invalid row that says why.
  • Related accounts — Every row lists the profile's related accounts (up to 50). relatedDepth 1 reads each of them as its own row too (2 and 3 go further), breadth first, each account once; maxRelatedPerProfile and relatedOnlyVerified narrow the crawl, maxItems bounds the run.
  • Filters — minFollowers, maxFollowers, verifiedOnly, businessOnly, skipPrivate, hasBioContact (an e-mail or phone in the bio), bioKeywords and categories keep only the profiles you want. A profile left out is free: a filtered row for a value you gave, skipped for an account a keyword or the crawl found.
  • Extra data — includeReelPlays adds the 12 latest reels with their plays (one more call a profile); includeHighlights adds the highlights' titles, the active story's time, the linked Facebook page and the memorialized flag on the profiles the record route serves (one more call a profile; the fallback route has them anyway).
  • Scheduled runs: what changed — Save a task with a monitorStore name and schedule it: each row then says new, changed or unchanged since the last run of that memory, which fields moved, the follower, following and posts changes and the new post codes. The memory keeps 20,000 profiles.

Input configuration

fieldtypedefaultwhat it does
usernamesarray[]Instagram profiles, one per line, in any form: a username (natgeo, @natgeo), a profile link (https://www.instagram.com/natgeo/, with ?igsh= or any other parameter, m.instagram.com, instagr.am, a reels or tagged tab, an app /_u/ link, a story link), a numeric profile id (787132), or a post or reel link (its author's profile is read). A handle is read whole: trading.com stays trading.com. The same profile given twice is one row and one charge. A private, restricted, missing or unavailable profile, or a value that names nothing, is a free row that says why.
searchQueriesarray[]Words that find Instagram accounts (coffee roasters, yoga studio berlin): each keyword is asked of the Threads account search and Meta's Ad Library page search (a Threads account is its Instagram account; a page names its Instagram account), joined by username in rank order, and each account found is read as a profile. A keyword with no account is a free row.
maxResultsPerQueryinteger10How many accounts each keyword reads, in rank order (both searches together list up to about 25).
relatedDepthinteger00 = each profile's related accounts stay a list inside its row. 1 = each related account of every profile you gave is read as its own row too; 2 and 3 go one and two levels further (breadth first, each account once). Bound it with maxRelatedPerProfile and maxItems.
maxRelatedPerProfileinteger0How many of a profile's related accounts the crawl reads (Instagram lists up to 50); 0 = all of them.
relatedOnlyVerifiedbooleanfalseWith relatedDepth above 0, read only the related accounts that carry the verified badge.
includeReelPlaysbooleanfalseAdd the profile's 12 latest reels with their play counts (latest_reels, avg_reel_plays) and the plays on the latest posts that are reels. One more call per profile.
includeHighlightsbooleanfalseAdd the titles of the profile's story highlights (up to 10, highlights), the active story's time (latest_story_at), the linked Facebook page (linked_facebook_page) and the memorialized flag. A profile served by the fallback route has them anyway; on the others it is one more call per profile.
minFollowersinteger0Keep a profile only with at least this many followers. A profile left out by a filter is a free row (filtered) for a value you gave, and is skipped for an account a keyword or the crawl found. 0 = no minimum.
maxFollowersinteger0Keep a profile only with at most this many followers. 0 = no maximum.
verifiedOnlybooleanfalseKeep only the profiles with the verified badge.
businessOnlybooleanfalseKeep only business accounts (account_type business); creator and personal accounts are left out.
skipPrivatebooleanfalseA private account is always free; with this on it becomes a filtered row instead of a private row with its public fields.
hasBioContactbooleanfalseKeep only the profiles whose bio text carries an e-mail address or a phone number.
bioKeywordsarray[]Keep only the profiles whose bio contains at least one of these words (case does not matter).
categoriesarray[]Keep only the profiles whose Instagram category contains one of these words (cafe, coach, brand); a profile with no category is left out.
monitorStorestring""A name for a memory between runs (letters, digits, '.', '_', '-'). With it, each profile row says what changed since the last run of the same memory: change_type, changed_fields, followers_change, following_change, posts_change, new_posts. For a scheduled task. Empty = no memory.
maxItemsinteger0The most charged profile rows of the whole run, over every input, keyword and related account; 0 = no cap beyond your inputs and your charge limit.
proxyUrlstringYour own proxy (scheme://user:pass@host:port) for every call instead of ours. Leave empty: the Actor brings its own connections at no cost to you.

Errors

A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:

  • the status message starts with INPUT REJECTED;
  • the dataset holds one row, {"error": true, "code": "…", "message": "…"}, and no results;
  • the key-value store record ERROR holds the same object.

From code, check error on the first row before reading results.

A private, age-restricted, missing or unavailable profile, a keyword with no account or a value that names nothing is not an error: it gets one free row with its status and status_reason, and the run goes on with the others. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.

FAQ

Why do some business profiles take longer?

For many business accounts Instagram's profile endpoint answers an error instead of the profile. Those are read by the fallback route: five logged-out calls in parallel (the profile root, the page query for the category and account type, the owner's latest posts, the suggestions, the embed for the exact posts count). The row is whole; record_source says bundle, and posts_note says what that list of posts lacks (no video views, alt text or location).

What are the free rows?

Every value you give gets one row (an empty line is not a value), and so does every keyword: a keyword none of whose accounts gets a row of its own gets a free row that says why. ok rows are charged. Free: private (a private account's public fields, no posts), restricted (Instagram withholds the profile from logged-out visitors, e.g. an age-gated brand; the follower count, page category and badge come from Meta's Ad Library when it names the account), unavailable (no public profile and no source names it), not_found (no account: two connections agree), invalid, filtered, duplicate (the same profile as another value, or an equal form of it such as @NatGeo beside natgeo: read once), no_results (a keyword with no account), failed (try again), not_read (a cap or the time limit came first). For the profiles alone keep the rows whose status is ok.

Does it need an Instagram account, cookies or a login?

No. Everything is read from Instagram's public logged-out data with a plain HTTP client; nothing of yours is sent to Instagram.

Can it get the business e-mail and phone of the contact button, or the followers list?

No. The contact button's e-mail and phone, the followers and following lists and the 'About this account' details (join date, country) are shown to logged-in users only. Each row gives the e-mails and phones written in the bio itself, the website and bio links, and the kind of contact button (business_contact_method). To find e-mails on the profile's website, see our Instagram Email Scraper.

Is the follower count live?

Yes: it is read in the run, from the profile record or the profile root, the same figure Meta's Ad Library shows that minute. Nothing is cached between runs or buyers.

Which countries does it see?

Instagram serves the same profile to every country we tested (the US, Germany, the UK, Brazil and Japan gave the same posts, related accounts, bio and counts), so there is no country input.

I move from another Instagram profile scraper: which column is which?

The leader's keys map one to one: biography → biography, businessCategoryName → category, externalUrl → external_url, externalUrls → bio_links, fbid → fbid, followersCount → followers, followsCount → following, fullName → full_name, highlightReelCount → highlights_count, id → id, igtvVideoCount → igtv_count, inputUrl → input, isBusinessAccount → is_business, joinedRecently → is_joined_recently, latestIgtvVideos → latest_igtv, latestPosts → latest_posts, postsCount → posts_count, private → is_private, profilePicUrl → profile_pic_url, profilePicUrlHD → profile_pic_url_hd, relatedProfiles → related_profiles, url → url, username → username, verified → is_verified. externalUrlShimmed (Instagram's tracking redirect) is not delivered: external_url is the target.

How long do the picture and media URLs work?

Instagram signs every picture and media URL with an expiry, a few days after the read. Download what you need before it.

Integration

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/instagram-profile-scraper').call({"usernames": ["humansofny", "natgeo"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python

from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/instagram-profile-scraper').call(run_input={'usernames': ['humansofny', 'natgeo']})
items = client.dataset(run['defaultDatasetId']).list_items().items

CLI

$apify call hyperbach/instagram-profile-scraper --input '{"usernames": ["humansofny", "natgeo"]}'

REST

curl -X POST "https://api.apify.com/v2/acts/hyperbach~instagram-profile-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' -d '{"usernames": ["humansofny", "natgeo"]}'

Support

Disagree with a charge? Write to apify@hyperbach.com with the run ID. We will ask Apify to compensate you, and the charge comes back to your Apify account as platform credit.

See also

  • Instagram Posts Scraper — the posts and reels of Instagram profiles, with the whole caption, the exact publish time, likes, comments and plays.
  • Meta Ad Library Scraper — every ad a page runs on Facebook, Instagram, Messenger, WhatsApp and Threads, with the landing URL, media, run dates and EU reach.
  • Threads Scraper — Threads profiles with the exact follower count, their posts and replies with view counts, and keyword and tag search, without a login.
  • Instagram Reels Transcript Scraper — the spoken words of Instagram reels, by reel link or creator, with the exact posting time.
  • Instagram Hashtag Scraper — Instagram's own ranked list of top reels for a hashtag or a search keyword.
  • Facebook Pages Scraper — Facebook pages by URL, id, name or search words: the exact follower count, categories, address, phone, e-mail and websites, and the page transparency facts.

Run them together: Put the username of the profiles this run returns into Instagram Posts Scraper's Profiles to get every post and reel with likes, comments and plays.

This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.