Bluesky Profile Details Scraper avatar

Bluesky Profile Details Scraper

Pricing

from $6.00 / 1,000 bluesky profile scrapeds

Go to Apify Store
Bluesky Profile Details Scraper

Bluesky Profile Details Scraper

Fetch public Bluesky profile details from handles, DIDs or bsky.app URLs for influencer research and identity resolution. Returns DID, handle, bio, counts, verification, media, labels and timestamps.

Pricing

from $6.00 / 1,000 bluesky profile scrapeds

Rating

0.0

(0)

Developer

Khadin Akbar

Khadin Akbar

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

16 days ago

Last modified

Share

What is Bluesky Profile Details Scraper?

Bluesky Profile Details Scraper turns a list of Bluesky handles, AT Protocol DIDs or bsky.app profile URLs into a dataset with one typed row per public account. Each row returns the permanent DID, current handle, display name, bio, follower, following and post counts, list, feed and starter-pack counts, verification signals, avatar and banner URLs, pinned post reference, moderation labels and account timestamps. Influencer researchers, community analysts, identity-resolution teams and AI agents use it to enrich known accounts, with no login or app password.

Why teams use this Bluesky profile scraper

  • Any identifier in. Mix handles such as bsky.app, @apify.com, DIDs and full profile URLs in one profiles list.
  • Stable identity key. did stays the same when a user changes handle, which makes joins and monitoring reliable.
  • Audience sizing. followersCount, followsCount and postsCount show reach and activity at collection time.
  • Verification signals. verificationStatus, trustedVerifierStatus, isVerified and isTrustedVerifier are normalized for easy filtering.
  • Account age. createdAt lets you separate established accounts from new ones.
  • Clean batches. deduplicate and ignoreInvalidProfiles keep mixed lists moving and the dataset tidy.

Best fit when you already know which Bluesky accounts you want: enriching an influencer list, resolving handles to DIDs, comparing audience sizes, or checking verification before outreach. The Actor is designed for profile records; posts and keyword discovery have their own Actors.

  • To discover accounts by topic first, start with Search Bluesky Posts, then pass the author handles into profiles here.
  • For the posts each account publishes, continue with Bluesky Posts Scraper using the same handles.

Example workflow: from a creator list to an outreach shortlist

A brand partnerships manager starts with a spreadsheet of fifty creator handles and profile URLs. They paste them into profiles with deduplicate on. The dataset returns each account's did, displayName, description, followersCount, postsCount, isVerified and createdAt. They filter out accounts created recently, rank the rest by followers and posting activity, and export the shortlist to their CRM keyed on did. A monthly schedule with the same list tracks audience growth for every creator.

How to scrape Bluesky profiles

  1. Add handles, DIDs or bsky.app profile URLs in Bluesky profiles.
  2. Keep Remove duplicate profiles and Continue past invalid profiles on, and adjust Maximum concurrent lookups if needed.
  3. Click Start, then export the dataset as JSON, CSV or Excel, or read it through the API.

Input

{
"profiles": [
"bsky.app",
"@apify.com",
"did:plc:z72i7hdynmk6r22z27h6tvur",
"https://bsky.app/profile/npr.org"
],
"maxConcurrency": 8,
"deduplicate": true,
"ignoreInvalidProfiles": true
}
FieldTypeWhat it controls
profilesarrayRequired. 1 to 500 handles, DIDs or bsky.app profile URLs.
maxConcurrencyintegerParallel lookups, from 1 to 20. Default 8.
deduplicatebooleanReturn one row per normalized handle or DID. Default true.
ignoreInvalidProfilesbooleanSkip malformed values and keep going. Default true.

Output

One dataset row per public Bluesky profile.

FieldWhat it contains
requestedProfileThe value you sent
didPermanent AT Protocol identifier
handle, displayName, descriptionCurrent handle, name and bio
profileUrl, avatarUrl, bannerUrlProfile link and media
followersCount, followsCount, postsCountAudience and activity counts at collection time
listsCount, feedGeneratorsCount, starterPacksCountPublic lists, custom feeds and starter packs
isLabelertrue for moderation labeler accounts
verificationStatus, trustedVerifierStatus, verificationCountBluesky verification signals
isVerified, isTrustedVerifierNormalized verification flags
labelsPublic moderation label values, when present
pinnedPostUriAT URI of the pinned post
createdAt, indexedAtAccount creation and indexing times
source, scrapedAtData route, such as bluesky-public-api, and collection time
{
"requestedProfile": "bsky.app",
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"description": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app",
"profileUrl": "https://bsky.app/profile/bsky.app",
"avatarUrl": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka",
"bannerUrl": "https://cdn.bsky.app/img/banner/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreichzyovokfzmymz36p5jibbjrhsur6n7hjnzxrpbt5jaydp2szvna",
"followersCount": 35101640,
"followsCount": 15,
"postsCount": 865,
"listsCount": 18,
"feedGeneratorsCount": 7,
"starterPacksCount": 15,
"isLabeler": false,
"verificationStatus": "none",
"trustedVerifierStatus": "valid",
"verificationCount": 0,
"isVerified": false,
"isTrustedVerifier": true,
"labels": [],
"pinnedPostUri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l",
"createdAt": "2023-04-12T04:53:57.057Z",
"indexedAt": "2025-10-27T21:05:26.152Z",
"source": "bluesky-public-api",
"scrapedAt": "2026-10-01T01:34:02.813Z"
}

The dataset holds profile rows only. The OUTPUT record carries the run outcome (COMPLETE, PARTIAL, VALID_EMPTY or UPSTREAM_FAILED) and billing totals, and RUN_SUMMARY lists skipped and unresolved values.

Pricing

This Actor uses Pay per event plus Apify platform usage. You pay one Bluesky profile scraped event for each validated profile saved to the dataset and one Actor Start event per run. Duplicate, malformed and unresolved values are never charged as profiles. Platform usage is billed separately by Apify.

Worked example in words: a list of ten distinct, valid handles costs ten Bluesky profile scraped events plus one Actor Start event, plus a small amount of platform usage. Check the live Pricing tab on this page for current event prices.

API example

curl -X POST "https://api.apify.com/v2/acts/khadinakbar~bluesky-profile-details-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"profiles": ["bsky.app", "apify.com", "https://bsky.app/profile/npr.org"]}'
from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("khadinakbar/bluesky-profile-details-scraper").call(run_input={
"profiles": ["bsky.app", "apify.com"],
"maxConcurrency": 8,
})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
print(p["did"], p["handle"], p["followersCount"], p["isVerified"])

Use with AI agents (MCP)

Connect the Actor to Claude, ChatGPT, Cursor or any MCP client through Apify MCP and ask:

Get the DIDs, bios, follower counts and verification status for these Bluesky handles: bsky.app, apify.com, npr.org. Then rank them by followers.

The agent passes the handles in profiles, reads rows from the dataset, and keys each account on did. Every row keeps profileUrl and scrapedAt for citation, and the OUTPUT record tells the agent whether every value resolved. Cost scales with the number of distinct valid profiles you send.

Best results

Starting situationHelpful actionExpected outcome
A messy list from a spreadsheetPaste handles, @handles and URLs togetherOne normalized row per account
Long-term trackingStore did as the key, not handleStable joins across handle changes
Repeated entriesKeep deduplicate onOne row and one charge per account
A few malformed valuesKeep ignoreInvalidProfiles onValid rows saved, skips listed in RUN_SUMMARY
Audience growth reportsSchedule the same list and compare followersCountA growth trend per creator
Large listsRaise maxConcurrency toward 20Faster batches

Builder's note

I built this Actor on Bluesky's public AppView API, the route Bluesky provides for public web use, so profile reads need no account. I designed the row around the DID because handles can change while the DID stays the same, which matters for anyone tracking accounts over time. I found that real input lists mix handles, @ prefixes and URLs, so normalization and deduplication happen before any lookup or charge.

FAQ

Do I need a Bluesky account or app password?

No. The Actor reads public profile data.

What is a DID?

A DID is the permanent AT Protocol identifier for an account. It stays the same when the handle changes.

Does it return posts or follower lists?

It returns profile records. Use Bluesky Posts Scraper for posts.

How fresh are the counts?

Counts reflect the moment of collection, recorded in scrapedAt.

Responsible use

This Actor collects public Bluesky profile data. Profiles describe real people, so use the data with a lawful basis under privacy laws such as the GDPR and CCPA, respect Bluesky's terms, and honor opt-outs before any outreach. Bluesky is a trademark of Bluesky PBC; this independent Actor is not affiliated with or endorsed by Bluesky.