Bio-Link Scraper — Linktree, Beacons, Komi, link.me & More
Pricing
from $2.39 / 1,000 profiles
Bio-Link Scraper — Linktree, Beacons, Komi, link.me & More
Scrape bio-link profiles from link.me, Linktree, Tap.bio, Komi, Pillar, bio.link, Beacons, and any other link-in-bio host into one unified shape: identity, links, socials, and on-page contact info.
Pricing
from $2.39 / 1,000 profiles
Rating
0.0
(0)
Developer
ParseBird
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Bio-Link Scraper — Linktree, Beacons, Komi, link.me & More
Bio-Link Scraper turns any link-in-bio profile — Linktree, link.me, Beacons, Komi, Pillar, bio.link, Tap.bio, or any other bio-link host — into one unified row: identity, bio, avatar, on-page contact email, social accounts, featured links, and every outbound link, regardless of which platform the creator used.
| Native extractors for 7 major bio-link platforms plus a generic fallback for anything else — one consistent output shape no matter the source, so you never have to write platform-specific parsing. |
Copy to your AI assistant
Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor: Actor ID parsebird/biolink-scraper on Apify — call it with ApifyClient (client.actor("parsebird/biolink-scraper").call(run_input={"profileUrls": ["https://linktr.ee/shopify", "https://link.me/danucd"], "maxItems": 100})) — inputs are profileUrls (array of bio-link URLs, any mix of platforms) or usernames + platform (bare handles resolved against one platform: linkme, linktree, tapbio, beacons, biolink, komi, or pillar), plus includeRawData (boolean, default false), maxItems (default 100), and maxConcurrency (1–20, default 10) — output is one dataset row per profile with platform, username, displayName, bio, avatar, cover, verified, isAdult, visitCount, followerCount, email, phone, location, websites[], socialLinks[], featuredLinks[], links[], totalLinks, theme, createdAt, updatedAt, scrapedAt — API docs at https://apify.com/parsebird/biolink-scraper/api and API tokens at https://console.apify.com/settings/integrations.
What does Bio-Link Scraper do?
This link-in-bio scraper reads each profile's real page data — the same JSON or HTML the platform itself renders — and normalizes it into one shape:
- 🔗 7 native extractors: link.me, Linktree, Tap.bio, Komi, Pillar, bio.link, and Beacons, each reverse-engineered to its actual data source (not screen-scraped guesswork)
- 🌐 Generic fallback for any other bio-link host — identity, socials, and visible links via JSON-LD and OpenGraph
- 📋 Mix platforms freely in one run, or scrape a whole batch of usernames against a single platform
- 📧 On-page contact capture — email and phone, only when the creator put them on the page themselves (no third-party enrichment, no guessing)
- 🔁 One unified shape every time: the same fields whether the source is a rich JSON API or plain HTML
- 🧯 A bad, private, deleted, or blocked profile is logged and skipped — it never stops the rest of the batch
Coverage by platform
| Platform | Example profile URL | Coverage |
|---|---|---|
| link.me | https://link.me/danucd | Full — identity, all links (featured links included), socials, on-page email |
| Linktree | https://linktr.ee/shopify | Full — identity, all links, socials |
| Tap.bio | https://tap.bio/@nasa | Full — identity, card links, socials |
| Komi | https://kennyg.komi.io | Full — identity, all module links, socials, theme |
| Pillar | https://pillar.io/ninja | Full — identity, links, socials |
| bio.link | https://bio.link/art | Full — identity, links, socials, on-page email |
| Beacons | https://beacons.ai/defleppard | Identity + full social list + featured link (see FAQ) |
| Any other bio-link host | https://example.bio/name | Generic fallback — identity, socials, visible links |
Not supported: search/discovery by keyword (this actor scrapes profiles you supply — it does not find creators for you), private/deleted/password-locked profiles, analytics or click counts per link (bio-link platforms don't expose these publicly), and non-bio-link URLs (a random website returns only whatever generic identity markup it exposes).
Input parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| profileUrls | array of strings | one of these two | — | Bio-link profile URLs. Mix platforms freely — each is routed by host. |
| usernames | array of strings | one of these two | — | Bare handles, resolved against platform below (bulk-by-username mode). |
| platform | string | with usernames | linkme | Which platform the bare handles belong to: linkme, linktree, tapbio, beacons, biolink, komi, or pillar. Ignored for full profileUrls. |
| includeRawData | boolean | No | false | Attach the raw upstream payload (page JSON / GraphQL / JSON-LD) to each row for debugging or extra fields. |
| maxItems | integer | No | 100 | Hard cap on total dataset rows. |
| maxConcurrency | integer | No | 10 | Maximum profiles fetched in parallel (1–20). |
| proxy | object | No | off | Optional Apify Proxy for reaching bio-link hosts at high volume. |
Mixed platforms in one run
{"profileUrls": ["https://link.me/danucd","https://linktr.ee/shopify","https://kennyg.komi.io","https://bio.link/art"]}
Bulk by username (one platform)
{"usernames": ["danucd", "someone", "another"],"platform": "linkme"}
Output example
{"platform": "linkme","profileUrl": "https://link.me/danucd","username": "danucd","displayName": "Dana","bio": "ALL MY LINKS👇","avatar": "https://media.link.me/_resize/image/quality=90,format=webp/images/webp-images/user-profile/1169288/tmp-2541-1763300314455.webp","cover": null,"verified": false,"isAdult": false,"visitCount": "61.6k","followerCount": null,"email": "dana.danucd@gmail.com","phone": null,"location": null,"websites": [],"socialLinks": [{ "title": "Instagram", "url": "https://www.instagram.com/danucd/", "type": "social", "network": "instagram", "handle": "danucd", "position": null }],"featuredLinks": [{ "title": "Winner Song", "url": "https://open.spotify.com/album/2Ly7LE7i3ebCLcYkwD9sng", "type": "social", "network": "spotify", "position": 8 }],"links": [{ "title": "Instagram", "url": "https://www.instagram.com/danucd/", "type": "social", "network": "instagram", "position": null }],"totalLinks": 21,"theme": { "backgroundColor": "", "mainTextColor": "" },"createdAt": "2024-11-01 12:37:51","updatedAt": "2025-11-16 13:43:17","scrapedAt": "2026-09-27T13:39:34.085Z"}
Every row is the same shape regardless of source platform — fields the source doesn't expose come back null or empty rather than missing. featuredLinks[] is link.me-only (the featured button links in the middle of the page); it's also included in links[], which holds every outbound link on the page. Download the full results as JSON, CSV, Excel, HTML, or XML, or pull them with the Apify API.
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("parsebird/biolink-scraper").call(run_input={"profileUrls": ["https://linktr.ee/shopify", "https://link.me/danucd"],"maxItems": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["platform"], item["username"], item["totalLinks"])
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const run = await client.actor('parsebird/biolink-scraper').call({profileUrls: ['https://linktr.ee/shopify', 'https://link.me/danucd'],maxItems: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Use cases
- Build a lead list of creators/brands with their on-page contact email, straight from their bio-link page
- Monitor a competitor's or influencer's link-in-bio for new products, drops, or campaign links
- Migrate a creator's links from one bio-link platform to another without manual re-entry
- Enrich a creator database with social handles pulled from a single source of truth
- Audit which social platforms a roster of creators actually links from their bio page
How it works
- Give the Actor
profileUrls(any mix of platforms) orusernames+ aplatformfor bulk mode. - Each URL is routed by host to its native extractor — link.me, Linktree, Tap.bio, Komi, Pillar, bio.link, and Beacons each read from their real data source (an internal API, embedded page JSON, or the rendered HTML), not fragile CSS-only guessing. Anything else falls back to a generic JSON-LD/OpenGraph extractor.
- Every platform's raw shape is normalized into the same UnifiedProfile fields, so downstream processing never needs to know which platform a row came from.
- Each row is pushed to the dataset as soon as it's ready, so partial results are visible while the run is still going.
- A failed, private, or blocked profile is logged and skipped — it never stops the rest of the batch.
How much does it cost to scrape bio-link profiles?
| Event | Price per event | Price per 1,000 |
|---|---|---|
| profile-scraped | $0.00299 | $2.99 |
| contact-found | $0.00179 | $1.79 |
You're billed one profile-scraped event per profile returned in the dataset, and one additional contact-found event only when that profile exposes an on-page contact email. Pricing improves automatically with your Apify plan tier (Bronze $2.79/$1.69 per 1,000, Silver $2.59/$1.59, Gold $2.39/$1.49). Apify's free monthly platform credits cover a meaningful number of runs before you pay anything out of pocket.
Input/Output
Set profileUrls or usernames from the Input tab in Apify Console, or pass them as JSON via the API. Results land in the run's default dataset — open the Output tab to preview rows, or export as JSON, CSV, Excel, HTML, or XML.
Is it legal to scrape bio-link profiles?
Scraping publicly available data — the same identity, links, and contact info any visitor sees on a public bio-link page — for research, lead generation, or analysis is common practice, but always review each platform's Terms of Service for your specific use case and handle any captured contact information in line with applicable privacy law. Read more on Apify's blog about the legality of web scraping.
FAQ
Why does Beacons only return identity, socials, and one featured link?
Beacons publishes identity, a full social list, and one featured link through its own JSON-LD block. Its multi-link button list loads from a private, authenticated API that isn't reachable without logging in as the page owner — so that part genuinely isn't available publicly. The row's note field flags this explicitly.
What happens with a bio-link host you don't have a native extractor for?
It falls through to the generic extractor, which reads JSON-LD, OpenGraph meta tags, and visible outbound links. Coverage is identity + socials + visible links — the note field flags these rows too.
Why is featuredLinks[] only populated for link.me?
It's the only platform in this set with a distinct "featured button" section separate from its full link list. Every platform's full link list (featured links included, where applicable) is always in links[].
Can I mix a bulk-username run with specific profile URLs?
Yes — profileUrls and usernames can both be set in the same run; the Actor processes both sets (deduplicated).
What's in includeRawData?
The raw JSON, GraphQL response, or JSON-LD object the extractor parsed, attached as rawData on each row — useful for debugging or pulling a field this Actor doesn't map yet. Off by default to keep rows lean.
Can I run this on a schedule? Yes — use Apify's built-in Scheduler to re-check a roster of profiles daily or weekly.
I found a bug or a profile that won't resolve — where do I report it? Open an issue on the Actor's Issues tab in Apify Console with the URL that failed, and it'll get looked at.