Instagram Email Scraper & Phone Finder: Bio, Website, Leads avatar

Instagram Email Scraper & Phone Finder: Bio, Website, Leads

Pricing

from $2.50 / 1,000 profiles

Go to Apify Store
Instagram Email Scraper & Phone Finder: Bio, Website, Leads

Instagram Email Scraper & Phone Finder: Bio, Website, Leads

Instagram profiles to emails and phones, no login: an Instagram email finder and phone number scraper. One lead per profile: the bio email and phone, link in bio, website contact pages, linked TikTok, YouTube, Threads and Telegram bios, category, exact counts, engagement, related profiles.

Pricing

from $2.50 / 1,000 profiles

Rating

0.0

(0)

Developer

Moxlade

Moxlade

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

4 days ago

Last modified

Share

Instagram profiles to emails and phones, without a login. Give it usernames or profile links and get one row per profile: the email and phone written in the bio, the external link and every bio link, category and account type, the exact follower, following and post counts, engagement over the recent posts (up to 12), and the related accounts Instagram shows (up to 50). Then the contact finder goes further — it resolves the link in bio (Linktree, Beacons, lnk.bio and 60+ others), crawls the website's contact, about, privacy, terms and imprint pages, and reads the linked TikTok, YouTube, Threads and Telegram bios — and returns every email, phone and WhatsApp number once, each with the page it came from and an MX status. No account, no cookies, proxies handled for you. Pay per contact found.

A business and a creator, with their contacts

Give it this:

{
"usernames": [
"garyvee",
"zachking"
],
"findContacts": true
}

Back comes one row per profile (or a free row that says why there is none) — the fields below are the ones this real row carried; every row has the same 71, and a field the source did not show arrives as null, not as a zero:

{
"row_type": "profile",
"input": "mkbhd",
"input_index": 1,
"source_kind": "profile",
"status": "ok",
"scraped_at": "2026-10-12T10:01:53Z",
"username": "mkbhd",
"user_id": "28943446",
"full_name": "Marques Brownlee",
"profile_url": "https://www.instagram.com/mkbhd/",
"biography": "I promise I won't overdo the filters.",
"external_url": "https://mkbhd.com/",
"bio_links": [{"url": "https://mkbhd.com/", "title": null, "type": "external"}],
"is_private": false,
"is_verified": true,
"is_business_account": true,
"is_professional_account": true,
"account_type": "business",
"contact_method": "CALL",
"has_contact_button": true,
"follower_count": 5287960,
"following_count": 581,
"posts_count": 2118,
"igtv_count": 14,
"highlight_reel_count": 2,
"profile_pic_url": "https://scontent-iad3-2.cdninstagram.com/v/t51.82787-19/587817368_18545874469015447_3745195562993032801_n.jpg?stp=dst-jp …",
"profile_pic_url_hd": "https://scontent-iad3-2.cdninstagram.com/v/t51.82787-19/587817368_18545874469015447_3745195562993032801_n.jpg?stp=dst-jp …",
"email": "contact@support.mkbhd.com",
"emails": ["contact@support.mkbhd.com", "business@mkbhd.com"],
"contacts": [
{
"type": "email",
"value": "contact@support.mkbhd.com",
"source": "website",
"source_url": "https://mkbhd.com/pages/contact",
"raw": "contact@support.mkbhd.com",
"also_on": null,
"mx": "ok"
},
"… 1 more"
],
"contacts_count": 2,
"contact_sources": ["website", "youtube"],
"website_url": "https://mkbhd.com/",
"website_domain": "mkbhd.com",
"website_title": "MKBHD",
"website_pages_read": [{"url": "https://mkbhd.com/", "type": "home", "status": "ok", "contacts": 0}, "… 4 more"],
"website_read_from": "live",
"website_read_at": "2026-10-12T10:01:58Z",
"linked_accounts": {"youtube": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ", "instagram": "https://instagram.com/MKBHD", "twitter": "https://twitter.com/MKBHD", "discord": "ht …,
"networks_read": [{"network": "youtube", "url": "https://www.youtube.com/channel/UCBJycsmduvYEL83R_U4JriQ", "status": "ok", "read_from": "live", "contacts": 1}],
"recent_posts_read": 12,
"avg_likes": 206663.4,
"avg_comments": 1908.4,
"median_likes": 92786,
"engagement_rate": 0.039443,
"avg_video_views": 4133704.4,
"last_post_at": "2026-10-02T20:50:14Z",
"posts_per_week": 0.66,
"related_profiles": [{"username": "tomcruise", "user_id": "6970394928", "full_name": "Tom Cruise", "is_verified": true, "is_private": false}, "… 38 more"],
"related_count": 39,
"record_source": "web_profile_info",
"profile_read_from": "live",
"profile_read_at": "2026-10-12T16:24:58Z"
}

The same actor, asked differently:

  • Just the bio and the profile, no website crawl — {"usernames": ["nasa", "redbull"], "findContacts": false}
  • Expand a seed into its related creators, keep only those with a contact — {"usernames": ["garyvee"], "relatedProfilesPerSeed": 20, "onlyWithContact": true, "maxItems": 20}
  • Watch a list's follower counts from run to run — {"usernames": ["garyvee", "zachking"], "stateStoreName": "my-watchlist"}

What a row carries

Three places a contact hides, all read. The bio text and the recent captions (the email or phone written there, in E.164); the link in bio resolved and its website crawled — the home page plus the contact, about, privacy, terms and imprint pages, following the site's own links first; and the linked TikTok, YouTube, Threads and Telegram bios. Every email, phone and WhatsApp number comes back once, with the exact page it was read from and an MX check on each email.

The whole public profile, exact. The pk and username, the exact follower, following and post counts (not the rounded 11K the page shows), the bio with its mentions and hashtags, the external link and every bio link, the business or creator category, the account type, the verified and private flags, the story-highlight and IGTV counts, how many of the recent posts are reels, and engagement over the recent posts (up to 12; the last 6 on a row whose record_source is graphql) — average and median likes, average comments, average video views, an engagement rate and a posting rate.

Honest about the contact button. Instagram shows a business account's contact-button email and phone to logged-in viewers only. This Actor does not log in, so it does not invent those values: it tells you the account has a contact button and which kind (TEXT, CALL or EMAIL), and finds the real address in the bio, the website and the linked networks instead. What it cannot reach logged out — that button's value, the follower and liker lists, keyword, hashtag and location search, and About this account — it never ships as an empty column that reads like a miss.

Discovery that stays public. Ask for the related profiles Instagram shows next to each account and get them as full rows of their own (up to 50 a seed), each with seed_username so you can see where it came from. It is the one discovery Instagram serves a visitor, and it turns a short seed list into a wide lead list.

Filters before you pay. Keep only profiles above or below a follower count, of a given account type, or that have a contact at all — a profile a filter leaves out is a free row with its identity and the reason, never charged. maxItems caps the charged rows; a missing, private-empty or unreadable handle is a free row that says which.

Built for lists and schedules. Any number of usernames in one run, the same profile given several ways merged into one row. Turn on onlyNew with a saved task and each run delivers only the profiles no earlier run did; keep only stateStoreName and every run shows how each account's followers moved since the last read. Every row says whether its website contacts were read live or from our cache, and when. Ready-made: monitor related accounts for new leads.

Measured, not promised. Every figure on this page comes from our own runs. One profile's record is about 50 KB on the wire; the contact finder reads a profile's link in bio, website pages and linked networks in about 1 MB.

All 71 fields of a row

Every row carries all of them. A field the source did not show arrives as null, never as a zero or an empty string, and the note says when that happens.

fieldtypewhat it holds
row_typestringAlways profile (one row type).
inputstringThe value you gave that this row answers (the first form, when the same profile was given several ways).
input_indexintegerThe 1-based position of the input in your list.
inputs_mergedarrayOther forms of the same profile you gave (a handle and a link), merged into this row.
source_kindstringprofile (a profile you named) or related (a related profile read with relatedProfilesPerSeed).
seed_usernamestringOn a related-profile row: the profile it was found next to.
statusstringok = a delivered profile; not_found, invalid, failed, filtered, duplicate = a free row that says why there is no profile.
status_detailstringWhy a row is not ok, in words.
scraped_atstringWhen this row was read (UTC).
usernamestringThe Instagram username, lower-cased.
user_idstringInstagram's numeric id of the account, as a string (the pk).
full_namestringThe display name.
profile_urlstringThe profile's link on instagram.com.
biographystringThe bio text, as written.
bio_mentionsarrayThe @accounts named in the bio.
bio_hashtagsarrayThe #tags in the bio.
external_urlstringThe link in the bio (the website or link-in-bio URL Instagram shows).
bio_linksarrayEvery bio link: url, title, type. Business and creator accounts can show several.
is_privatebooleanThe account is private (its posts are not served; identity, counts and bio still are).
is_verifiedbooleanThe account has Instagram's verified badge.
is_business_accountbooleanThe account is a business account.
is_professional_accountbooleanThe account is a professional account (business or creator).
account_typestringbusiness, creator or personal, derived from the account's own flags; professional when the record does not say business or creator (a handle the record route answers a schema error for).
categorystringThe business or creator category Instagram shows (Fitness Trainer, Entrepreneur); null when none.
contact_methodstringThe contact button the account chose: TEXT, CALL or EMAIL; null when there is none. Instagram shows the button's value to logged-in viewers only, so this is the flag, not the address.
has_contact_buttonbooleanThe account has a contact button (the value is login-only on Instagram's side; the finder gets the address from the bio and the website instead).
follower_countintegerFollowers, exact.
following_countintegerFollowing, exact.
posts_countintegerPosts, exact (not the rounded 11K the page shows).
igtv_countintegerIGTV videos on the account (Instagram's long-video tab). Not a reels count: the logged-out record carries no reels total.
recent_reels_countintegerHow many of the recent posts read are reels; null when a video's reel flag is unknown (a row whose record_source is graphql).
highlight_reel_countintegerStory highlights on the profile.
pronounsarrayThe pronouns the account set, when any.
profile_pic_urlstringProfile picture URL (signed, it expires).
profile_pic_url_hdstringHigh-resolution profile picture URL (signed, it expires).
emailstringThe first email found, for a flat CRM column; emails has them all.
phonestringThe first phone found, in E.164; phones has them all.
whatsappstringThe first WhatsApp number found, in E.164; whatsapp_numbers has them all.
emailsarrayEvery email found, each once, across the bio, the captions, the links, the website and the linked networks.
phonesarrayEvery phone found, each once, in E.164.
whatsapp_numbersarrayEvery WhatsApp number found, each once, in E.164.
contactsarrayOne object per distinct contact: type (email / phone / whatsapp), value, source (bio / caption / bio_link / link_in_bio / website / tiktok / youtube / threads / telegram), source_url (the evidence), raw (as written), also_on (other places it was seen), and mx for an email.
contacts_countintegerHow many distinct contacts were found (the contact_found charge equals this).
contact_sourcesarrayThe kinds of source the contacts came from.
website_urlstringThe website the link in bio resolved to (the crawl's starting page).
website_domainstringThe website's registrable domain.
website_titlestringThe website's title or og:site_name.
website_pages_readarrayEach website page read: url, type (home / contact / about / privacy / terms / imprint), status, contacts found on it.
website_read_fromstringlive (read this run) or cache (kept from an earlier read; see website_read_at).
website_read_atstringWhen the website was read (UTC); older than the run when it came from the cache.
link_in_bio_pagesarrayEach link-in-bio page resolved (Linktree and the like): url, host, status, links, contacts.
linked_accountsobjectThe other-network accounts found (a URL per network: instagram, facebook, twitter, linkedin, tiktok, youtube, threads, telegram and more).
networks_readarrayEach linked network read for contacts: network, url, status, read_from, contacts.
finder_notestringWhat the contact finder did or could not do, in words.
recent_posts_readintegerHow many recent posts the engagement figures are over (up to 12; pinned posts left out).
avg_likesnumberAverage likes over the recent posts.
avg_commentsnumberAverage comments over the recent posts.
median_likesintegerMedian likes over the recent posts.
engagement_ratenumber(average likes + average comments) / followers, over the recent posts.
avg_video_viewsnumberAverage video views over the recent video posts.
last_post_atstringWhen the most recent of the read posts was published (UTC).
posts_per_weeknumberPosting rate over the span of the recent posts read (pinned posts left out).
recent_postsarrayWith includeRecentPosts: the recent posts, up to 12 (6 when record_source is graphql): shortcode, url, display_url (the image; signed, it expires), taken_at, likes, comments, video_views, is_video, is_reel (false for a photo; null for a video the record does not label), is_pinned, caption.
related_profilesarrayThe related profiles Instagram shows for this account (up to 50; fewer or none for some accounts): username, user_id, full_name, is_verified, is_private.
related_countintegerHow many related profiles the record carried.
followers_previousintegerWith the monitoring memory on: the follower count the last delivered run saw.
followers_changeintegerWith the memory on: the change in followers since the last delivered run.
previous_read_atstringWith the memory on: when this profile was last delivered (UTC).
record_sourcestringweb_profile_info (the full record) or graphql (the page's own record, for a handle Instagram answers a schema error for: identity, counts, bio and links, filled with the profile embed's posts count and last 6 posts and Instagram's related suggestions; no category or contact method).
profile_read_fromstringlive (Instagram read this run) or cache (the profile and its contacts kept from a live read in the last 30 days; see profile_read_at).
profile_read_atstringWhen the profile was read live from Instagram; on a cache row, the time of that earlier read.
rawobjectWith includeRaw: Instagram's own profile object, without the posts' media payloads.
run_tagstringThe runTag you set, copied onto every row.

Ways to run it

Read profiles. Put usernames, @handles or profile links in usernames, one per line. Each gives one row with the bio, the links, the counts, the engagement and the bio's own email and phone. The same profile given several ways is one row; a value that is not a profile is a free row that says where it belongs. Ready-made: exact follower counts and engagement rate for a list, recent posts with likes, comments and image links.

Find contacts beyond the bio. findContacts (on by default) resolves the link in bio, crawls the website and reads the linked networks. Choose the website pages with websitePages and bound them with maxWebsitePages; bound the aggregator's outbound links with maxLinkInBioLinks; turn the network bios off with readLinkedNetworks. On a creator's or a personal account a bio link is crawled as its website only when the domain carries the account's name: a link to a brand, a shop or a coaching platform is named in finder_note, not crawled, so their contacts are never sold as the profile's. Every contact carries its source and source_url. Ready-made: email and phone of a business profile, creators' emails from the bio, link in bio and website.

Expand related profiles. relatedProfilesPerSeed reads that many of the related accounts Instagram shows for each profile, as full rows of their own. It is the one discovery Instagram serves a visitor; the follower and liker lists and keyword, hashtag and location search are login-only and are not offered. Ready-made: related accounts of a brand as lead rows.

Filter and cap before the charge. minFollowers, maxFollowers, accountTypes and onlyWithContact keep only the profiles you want; a filtered profile is a free row. maxItems caps the charged rows. onlyNew with stateStoreName makes a scheduled run deliver only what is new. Ready-made: business accounts with 50K+ followers and an email, monitor related accounts for new leads.

Everything you can ask for

What to read

A list of Instagram profiles. Every form is accepted; a value that is not a profile comes back as a free row that says why.

inputacceptsdefaultwhat it changes
usernamesarray[]Instagram profiles, one per line, in any form: garyvee, @garyvee, https://www.instagram.com/garyvee/, or instagram.com/garyvee?hl=en. Each gives one row with the bio, the emails and phones written in it, the external link and every bio link, category and account type, exact counts, engagement over the recent posts (up to 12), and the contact finder's results. The same profile given several ways is one row. A numeric user id or a post or reel link is read too: the id's account, or the post's author (https://www.instagram.com/p/<code>/). A value that is not an Instagram profile is a free row that says so.
inputacceptsdefaultwhat it changes
relatedProfilesPerSeedinteger0Also read this many of the related profiles Instagram shows for each profile you give (0-50; Instagram shows up to 50, fewer or none for some accounts). Each related profile is a full row of its own, with source_kind related and seed_username set, charged like any profile. 0 reads none; the related accounts are listed on the seed's row either way.

Contact finder

Beyond the bio and the captions: the link in bio resolved, the website crawled, the linked other-network bios read.

inputacceptsdefaultwhat it changes
findContactsbooleantrueResolve the link in bio (Linktree, Beacons, lnk.bio and 60+ others), read the website's pages and the linked TikTok, YouTube, Threads and Telegram bios for more emails, phones and WhatsApp numbers. On a creator's or a personal account a bio link is read as its website only when the domain carries the account's name, so a brand's or a platform's contacts are never sold as the profile's. Turn it off to read only the Instagram record (the bio and the captions).
websitePagesarray[]Which of the website's pages the finder reads, beyond the home page. Empty reads all five types. The finder follows the site's own links first and the standard paths second.
maxWebsitePagesinteger8The most pages the finder reads on one profile's website (the home page counts). Most sites yield their contacts in two or three.
maxLinkInBioLinksinteger3When the bio points at a link aggregator (Linktree and the like), how many of its outbound links the finder checks. One whose domain carries the profile's name (its username or full name) is crawled as its website; a shop, a brand or an affiliate link is named in the row's note, never crawled, so a brand's contacts are never sold as the profile's. The aggregator page itself is always read.
readLinkedNetworksbooleantrueWhen a profile links a TikTok, YouTube, Threads or Telegram account (in the bio, the bio links or the website), read that account's public bio for contacts too, logged out. A network whose page is a login wall is reported, not promised.
refreshWebsitesbooleanfalseA profile read in the last 30 days is served from our side with its contacts, and website and network results are kept for repeat runs; every row says where its profile and its website contacts came from (profile_read_from, website_read_from) and when (profile_read_at, website_read_at). Turn this on to read every profile, website and network live this run.

Row options

inputacceptsdefaultwhat it changes
includeRecentPostsbooleanfalseAdd the recent posts to each row, up to 12 (6 on a row whose record_source is graphql): shortcode, URL, image link, time, likes, comments, video views, pinned flag, caption. The engagement averages are on every row regardless.
includeRawbooleanfalseAdd Instagram's own profile object to each row (raw), without the posts' image and video payloads.

Filters (applied before the charge)

A profile a filter leaves out is a free row with its identity and the reason, never charged.

inputacceptsdefaultwhat it changes
minFollowersinteger0Deliver only profiles with at least this many followers. 0 = no minimum.
maxFollowersinteger0Deliver only profiles with at most this many followers. 0 = no maximum.
accountTypesarray[]Deliver only these account types. Empty keeps all. business = a business account, creator = a professional non-business account, personal = neither. A professional account whose record does not say which (account_type professional) matches both business and creator.
onlyWithContactbooleanfalseDeliver only profiles for which an email, phone or WhatsApp number was found; a profile with none is a free row.

Monitoring and limits

inputacceptsdefaultwhat it changes
onlyNewbooleanfalseWith a saved task and stateStoreName, deliver only profiles no earlier run of this memory delivered; a profile skipped this way is a free row. With relatedProfilesPerSeed, a skipped seed still gives its new related profiles. To track follower change instead, leave this off and keep stateStoreName: every profile is delivered with how its follower count moved since the last read.
stateStoreNamestring""A name for the memory that onlyNew and the follower-change columns use, so the same task finds the same memory. Empty derives one from the usernames.
maxItemsinteger0Stop after this many charged profile rows (free rows do not count). 0 = no limit.
runTagstring""A label copied onto every row of this run, for your own grouping. Optional.
proxyUrlstring—Optional. Your own proxy as scheme://user:pass@host:port, used in front of the Actor's own exits. Leave empty to use the maintained exits (recommended).

If an input can't be used

The run still ends Succeeded and charges nothing. Its status message begins INPUT REJECTED and says what to change. The dataset holds a single row, {"error": true, "code": …, "message": …}, with no results, and the key-value record ERROR repeats it, so an agent should check error on the first row. A search that finds nothing is not an error, only an empty dataset. A run marked Failed is a fault on our side, not your input; it costs nothing and reaches us.

Before you run it

Does it return the email behind Instagram's contact button? Not that exact value — Instagram shows a business account's contact-button email and phone to logged-in viewers only, and this Actor does not log in. It tells you the account has a contact button and which kind, and it finds the real email and phone in the bio, the recent captions, the link in bio, the website's pages and the linked TikTok, YouTube, Threads and Telegram bios. On an account whose only contact is behind the button and nowhere public, you get the profile and the button flag, and the row is honest that no address was found.

Where do the contacts come from, and how do I know? Every contact carries a source and a source_url: bio, caption, bio_link, link_in_bio (the resolved aggregator page), website (with the exact page), or the name of a linked network (tiktok, youtube, threads, telegram). The same contact found in two places is listed once, with the other places in also_on. Emails carry an mx status (ok, none or unknown).

Does it need a login, a cookie or a proxy? No. Instagram is read logged out, through maintained exits; the websites and linked networks are read logged out too. There is nothing for you to supply. You may put your own proxy in proxyUrl if you prefer; it is used in front of the Actor's own exits.

What does a run cost, and what is free? You pay per profile delivered and per distinct contact found. A profile that a filter leaves out, a handle that does not exist, a private account with nothing readable, or a value that is not a profile is a free row that says why, and a run that fails before its first row charges nothing. Before the first request the log says the most the run can cost at your plan's prices.

Can it find profiles by keyword, hashtag or location, or list a target's followers? No. Instagram serves those lists to logged-in viewers only, so this Actor does not offer them — it would have to log in, which it does not do. The one discovery it has is the related profiles Instagram shows a visitor, through relatedProfilesPerSeed. Give it the handles you already have, or expand them through related profiles.

Is this legal, and what about personal data? Everything is read from what Instagram and the linked sites serve a logged-out visitor: no account, no cookie, nothing behind a login. A business or creator profile's public contact details are what the account itself published to be contacted by. Every row is read at run time, so an account or a page that has been removed cannot be returned by a later run. What you may do with the data depends on your purpose and your jurisdiction, and that part is yours, not ours.

What it costs

Pay for the profiles you read and the contacts you find. No start fee, no platform usage billed to you. Prices fall with your Apify plan.

per 1,000FreeStarterScaleBusiness
Profile (profile)$5.00$4.25$3.50$2.50
Contact found (contact_found)$4.995$4.24575$3.4965$2.4975

A profile row is $0.005 on the Free plan ($0.0025 on Business), whether a contact is found or not. Each distinct email, phone or WhatsApp number found for it is $0.004995 more ($0.0024975 on Business), counted once across the bio, the captions, the link in bio, the website and the linked networks. A profile with no contact costs the row only; turn on onlyWithContact and it is a free row instead. With findContacts off only the contacts written in the bio and the captions are found and charged. Free: a handle that does not exist, a value that is no Instagram profile, a profile a filter leaves out, a duplicate, a profile the exits could not read, and a run that failed before its first row. A run that stops early (a timeout, an abort) is charged for the rows it delivered. maxItems counts the charged profile rows; before the first request the log says the most the profile rows can cost at your plan's prices and the price of each contact. Enterprise plans have their own rates; the Actor's Pricing tab shows the price for your plan.

eventwhat one event isper 1,000
profileOne profile row: identity, exact counts, bio, links, category, account type, the contact-button flag, engagement over 12 posts and the related profiles. Charged only once the row is in your dataset.$5.00
contact_foundOne distinct email, phone or WhatsApp number found for a profile, across the bio, the captions, the link in bio, the website and the linked networks. One per distinct contact; a profile with none is not charged for one.$4.995

Who asks this

Lead generation and outbound teams — turn a list of Instagram handles into a contact list: the email and phone from the bio and the website, in E.164 and MX-checked, one row per profile, flat columns for your CRM.

Influencer and creator marketing — vet and reach creators: exact followers and engagement, the account type and category, the business contact route, and the email behind the link in bio — plus the related creators Instagram suggests.

Agencies and researchers — a wide, deduplicated contact set from a seed list: related profiles expanded, the website and the linked networks read, every contact with its evidence.

Developers and agents — one call, typed JSON rows, one row per input in order, a free labelled row for every miss, and a run summary to check a pipeline against.

Questions

support@moxlade.com

Every figure on this page was measured on our own runs or read from our own tables, on the date given next to it.