Bluesky Scraper | Posts, Profiles and Followers avatar

Bluesky Scraper | Posts, Profiles and Followers

Pricing

from $0.85 / 1,000 posts

Go to Apify Store
Bluesky Scraper | Posts, Profiles and Followers

Bluesky Scraper | Posts, Profiles and Followers

Bluesky scraper for posts, profiles, followers, likers and starter packs, no account or app password needed. Search keywords, hashtags or accounts: every post carries its author's follower count, every profile the emails in its bio. 43 rows in 6 seconds, 30 fields each, in our 2026 test run.

Pricing

from $0.85 / 1,000 posts

Rating

0.0

(0)

Developer

SilentFlow

SilentFlow

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Features

Limited permissions

Share

Bluesky Scraper | Posts, Profiles, Followers and Starter Packs (2026)

Bluesky posts, 30 fields each, from any search.

From SilentFlow. Creators of Facebook Search Scraper and JD Products Scraper (#1 for โ€œjd scraperโ€ in Apify Store search), with 920,000+ combined lifetime runs.

Every public Bluesky post and profile you need, one clean row each, and every post tells you how big its author's audience is. 43 rows from one keyword, three accounts and a thread in 6 seconds, without a Bluesky account.

Why choose this actor?

Found a great post on Bluesky but no idea whether its author speaks to 200 people or 200,000? Want the list of people who liked a launch post, not just the number? Tired of scrolling past hundreds of posts nobody reacted to?

  • The author's audience on every post. Each post row carries its author's followers, following and post counts and bio, in the same row as the text and the likes. In our default run, all 40 posts (from 15 different authors) came with them; in a 250-post keyword search, all 250 did, across 196 authors. No second run, no lookup table to join.
  • The people behind a post: who liked it and who reposted it. Paste a post link and choose who liked it or who reposted it: you get one profile row per person, with bio, follower counts and the emails or links written in their bio. Our run returned 10 likers of a Bluesky post, all 10 with their follower count, together with a people search and a starter pack: 30 profiles in 3 seconds.
  • Only the posts that took off. Set a minimum number of likes and the run skips everything below it, on keyword searches, account feeds, replies and quotes alike. Combined with a language and a date range, our run kept 10 French posts about the climate with at least 5 likes from the last 30 days, in 3 seconds, and left the 85 other posts it read out of the dataset.

Try Bluesky Scraper free

Try your first 43 rows

Paste this input in the Input tab, or keep the prefilled form, and press Start:

{
"queries": ["#opensource"],
"handles": ["bsky.app", "nytimes.com", "jay.bsky.team"],
"startUrls": [{ "url": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l" }],
"maxResults": 8
}

You get the 8 latest posts tagged #opensource, then for each of the three accounts its profile row and its 8 latest posts, then the official Bluesky welcome post with its first replies. That is 43 rows in our run: 40 posts and 3 profiles, in 6 seconds. Every post carries its author's follower count and bio. Swap the keyword and the handles for the ones you follow, and raise maxResults to go further back.

The Apify Free plan is enough to try it: no credit card, no Bluesky account, no app password.

How it works

Copy to your AI assistant

Paste this block into Claude, ChatGPT or Cursor to give it full context about this scraper:

You have access to the Bluesky Scraper on Apify: silentflow/bluesky-scraper
It reads public Bluesky posts and profiles, without any Bluesky account.
Input (no field is required, add at least one keyword, account or link):
- queries (array of strings): keywords, "exact phrases", #hashtags; Bluesky search filters work inside (from:nytimes.com, mentions:bsky.app, domain:github.com)
- handles (array of strings): accounts as handle (nytimes.com), @handle, profile link or DID; a bare name (alice) means alice.bsky.social
- startUrls (array of {url}): any bsky.app link: post, post/liked-by, post/reposted-by, post/quotes, profile, profile/followers, profile/follows, search?q=, hashtag/, custom feed, list, starter pack, go.bsky.app short link, at:// URI
- maxResults (integer, default 50): max rows per keyword, account or link (an account's profile row comes on top)
- searchType (latest | top | people, default latest): latest posts page back in time; top is Bluesky's first 100; people finds accounts
- since, until (string): date range, "2026-10-01" or an age such as "7 days"; until includes its whole day
- language (string): two-letter code, three-letter code or English name (fr, fra, French)
- minLikes (integer, default 0): skip posts with fewer likes
- accountData (posts | replies | media | videos | reposts | profile | followers | following, default posts): what each account returns; post modes start with the profile row
- postData (replies | likers | reposters | quotes, default replies): what each post link returns
Output: one row per post (type "post", 48 fields) or per account (type "profile", 27 fields), flat.
Post: id (string), url, uri (at://), cid, text, lang, hashtags[], mentions[] (handles), links[],
authorHandle, authorName, authorDid, authorAvatar, authorUrl, authorVerified (bool),
authorFollowersCount, authorFollowsCount, authorPostsCount (integers), authorBio,
likeCount, repostCount, replyCount, quoteCount, bookmarkCount (integers),
isReply, isRepost, isQuote, isThreadRoot, hasMedia (booleans), mediaType (image | video | null), mediaUrls[], videoUrl,
embedUrl, embedTitle, embedDescription (link card), quotedPostUrl, quotedPostText, quotedPostAuthor,
parentUri, parentUrl, threadRootUri, threadDepth (integer inside a thread read from a post link), repostedBy, labels[],
createdAt (RFC 3339 UTC), sourceInput, scrapedAt.
Profile: id (DID), url, did, handle, displayName, bio, emails[], links[] (from the bio), avatar, banner,
followersCount, followsCount, postsCount, listsCount, feedsCount, starterPacksCount (integers),
isVerified, isLabeler (booleans), dmPolicy (all | following | none), pinnedPostUrl, labels[],
joinedAt, indexedAt (RFC 3339), relation (null, follower, following, liker, reposter, listMember, starterPackMember, searchResult), sourceInput, scrapedAt.
Use apify-client for Python or JavaScript, or the Apify API.

How to scrape Bluesky posts

Three inputs, from the simplest to a full monitoring query. Each one runs as is.

Export the latest posts about a topic

{
"queries": ["web scraping"],
"maxResults": 250
}

The latest posts that match, newest first, each with its author's audience. In our run this returned 250 posts from 196 authors, covering the last 10 days, in 4 seconds. Bluesky shows a logged-out visitor only the first page of a search; this run keeps going back in time until it reaches your number.

Read an account: profile first, then its posts

{
"handles": ["nytimes.com"],
"accountData": "posts",
"maxResults": 100
}

One profile row (bio, links from the bio, followers, following, post count, join date, verified badge) and then the account's 100 latest posts, as they appear on its profile. Pick replies, media or videos to read the other tabs of the profile, or reposts to keep what the account shared.

Watch French posts about the climate that people reacted to

{
"queries": ["climat"],
"language": "French",
"minLikes": 5,
"since": "30 days",
"maxResults": 10
}

French-language posts from the last 30 days with at least 5 likes. In our run: 10 posts, all tagged French, each with 5 likes or more, in 3 seconds; the 85 other posts read on the way were left out.

Input parameters

ParameterTypeDefaultWhat it does
queriesarray of stringsnoneKeywords to search. Exact phrases in quotes, hashtags, and Bluesky's own search filters (from:, mentions:, domain:) work inside a keyword.
handlesarray of stringsnoneAccounts to read: handle, @handle, profile link or DID.
startUrlsarray of linksnoneAny bsky.app link, read as what it shows (see the formats below).
maxResultsinteger50Max rows per keyword, per account and per link.
searchTypelatest, top, peoplelatestLatest posts, Bluesky's top posts, or people whose name or bio matches.
sincedate or agenoneKeep posts published on or after this date.
untildate or agenoneKeep posts published on or before this date, the day included.
languagelanguageanyKeep posts tagged with this language.
minLikesinteger0Skip posts with fewer likes.
accountDataselectpostsFor each account: profile and posts, posts and replies, media, videos, reposts, profile only, followers or following.
postDataselectrepliesFor each post link: the post and its replies, who liked it, who reposted it, or the posts that quote it.

Formats accepted for accounts: a handle (nytimes.com, jay.bsky.team), an @handle (@bsky.app), a profile link (https://bsky.app/profile/nytimes.com), a DID (did:plc:z72i7hdynmk6r22z27h6tvur) or a bare name (alice, read as alice.bsky.social). The same account typed twice is read once.

Formats accepted for links:

  • a post: https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l (returns what postData asks for)
  • who liked, reposted or quoted a post: the same link followed by /liked-by, /reposted-by or /quotes
  • a profile and its lists of people: https://bsky.app/profile/nytimes.com, /followers, /follows
  • a search or a hashtag page: https://bsky.app/search?q=web+scraping, https://bsky.app/hashtag/photography
  • a custom feed: https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot
  • a list: https://bsky.app/profile/bsky.app/lists/3lvpca43j5z26
  • a starter pack: https://bsky.app/starter-pack/bsky.app/3mzdvli2fkq23, and its go.bsky.app short link
  • an at:// address of a post, feed, list or starter pack

Formats accepted for dates: a day (2026-10-31), a full timestamp (2026-10-31T18:00:00Z) or an age (12 hours, 7 days, 2 weeks, 1 month).

Formats accepted for the language: a two-letter code (fr), a regional code (pt-BR is read as Portuguese), a three-letter code (fra) or an English name (French).

What is skipped and said in the log: entries that are not Bluesky handles or links, accounts or posts that do not exist, and custom feeds that Bluesky only shows to logged-in members. The rest of the input still runs.

What data can you extract from Bluesky?

Each row is either a post (type: "post", 48 fields) or a profile (type: "profile", 27 fields). Both are flat: no nested object to unpack before a spreadsheet or a database can use them.

Post rows, in reading order:

  • Identity: id (the post id in its link), url (the permanent bsky.app link), uri (Bluesky's own address of the post) and cid.
  • Content: text, lang, hashtags, mentions (as handles) and links (the links written in the post and the link card).
  • Author: authorHandle, authorName, authorDid, authorAvatar, authorUrl, authorVerified, and the author's audience: authorFollowersCount, authorFollowsCount, authorPostsCount and authorBio.
  • Engagement: likeCount, repostCount, replyCount, quoteCount and bookmarkCount.
  • Kind of post: isReply, isRepost, isQuote, isThreadRoot, hasMedia.
  • Media and cards: mediaType (image or video), mediaUrls (full-size images, or the video thumbnail), videoUrl (the video stream), and the link card: embedUrl, embedTitle, embedDescription.
  • Quoted post: quotedPostUrl, quotedPostText, quotedPostAuthor.
  • Thread: parentUri, parentUrl (the post it answers), threadRootUri (the first post of the thread), and threadDepth (0 for a post you pasted, 1 for a direct reply, 2 for a reply to a reply). repostedBy names the account that reposted it when you read reposts.
  • Moderation and time: labels (content labels such as adult content warnings), createdAt.
  • Meta: sourceInput (the keyword, account or link that found the row) and scrapedAt.

Profile rows: id and did (the account's permanent id), url, handle, displayName, bio, emails and links found in the bio, avatar, banner, followersCount, followsCount, postsCount, listsCount, feedsCount, starterPacksCount, isVerified (blue check or trusted verifier), isLabeler, dmPolicy (who may message the account), pinnedPostUrl, labels, joinedAt, indexedAt, and relation: empty for an account you asked for, otherwise follower, following, liker, reposter, listMember, starterPackMember or searchResult, with sourceInput naming the account, post, list or keyword it relates to.

Usability facts: url, uri, id and did are permanent. A handle can change; the DID never does, so join on authorDid and did. Dates are RFC 3339 in UTC. Image and avatar links point to Bluesky's image servers and stay valid as long as the post or profile exists. A missing value is null (or an empty list), never an empty string.

Output example

A post row from the default run:

{
"type": "post",
"id": "3mzo3i4ec7d27",
"url": "https://bsky.app/profile/xmpp.org/post/3mzo3i4ec7d27",
"uri": "at://did:plc:hhyjgh7zxk33uavujv6hypm3/app.bsky.feed.post/3mzo3i4ec7d27",
"cid": "bafyreialmvgxj76x6w44xgjquxe5pcuqcvj5lz4neremc4w5dlrpcbz4sq",
"text": "#XMPP Community\n\nXMPP #Sprint in #London, #UK takes place from today till Sunday at The Mitre Hotel in #Greenwich.\n\nxmpp.org/2026/09/xmp...\n\n#jabber #chat #interoperability #selfhosting #rtc #opensource #decentralization #federation #messaging #collaboration",
"lang": null,
"hashtags": ["XMPP", "Sprint", "London", "UK", "Greenwich", "jabber", "chat", "interoperability", "selfhosting", "rtc", "opensource", "decentralization", "federation", "messaging", "collaboration"],
"mentions": [],
"links": ["https://xmpp.org/2026/09/xmpp-sprint-london/"],
"authorHandle": "xmpp.org",
"authorName": "XMPP Standards Foundation (XSF)",
"authorDid": "did:plc:hhyjgh7zxk33uavujv6hypm3",
"authorAvatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:hhyjgh7zxk33uavujv6hypm3/bafkreibavb5fmjizpijpima7ycn3mf4u5ul7npupgt5y7xn7akhu6g57pe",
"authorUrl": "https://bsky.app/profile/xmpp.org",
"authorVerified": false,
"authorFollowersCount": 182,
"authorFollowsCount": 13,
"authorPostsCount": 133,
"authorBio": "XMPP - Extensible Messaging and Presence Protocol\n\nPromoting open communication and open communication infrastructure\n\nStandardized within the IETF\n\nGetting started with XMPP: https://xmpp.org/getting-started/",
"likeCount": 1,
"repostCount": 0,
"replyCount": 0,
"quoteCount": 0,
"bookmarkCount": 0,
"isReply": false,
"isRepost": false,
"isQuote": false,
"isThreadRoot": true,
"hasMedia": true,
"mediaType": "image",
"mediaUrls": ["https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:hhyjgh7zxk33uavujv6hypm3/bafkreiffayv2on45meeuckp7jkduywncdcc4e7es6uhmluzlhtkqq7yfbm"],
"videoUrl": null,
"embedUrl": null,
"embedTitle": null,
"embedDescription": null,
"quotedPostUrl": null,
"quotedPostText": null,
"quotedPostAuthor": null,
"parentUri": null,
"parentUrl": null,
"threadRootUri": null,
"threadDepth": null,
"repostedBy": null,
"labels": [],
"createdAt": "2026-11-06T19:10:05Z",
"sourceInput": "#opensource",
"scrapedAt": "2026-11-06T19:30:39Z"
}

A profile row from the same run:

{
"type": "profile",
"id": "did:plc:z72i7hdynmk6r22z27h6tvur",
"url": "https://bsky.app/profile/bsky.app",
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"bio": "official Bluesky account (check username๐Ÿ‘†)\n\nBugs, feature requests, feedback: support@bsky.app",
"emails": ["support@bsky.app"],
"links": null,
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka",
"banner": "https://cdn.bsky.app/img/banner/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreichzyovokfzmymz36p5jibbjrhsur6n7hjnzxrpbt5jaydp2szvna",
"followersCount": 35552534,
"followsCount": 41,
"postsCount": 918,
"listsCount": 26,
"feedsCount": 7,
"starterPacksCount": 23,
"isVerified": true,
"isLabeler": false,
"dmPolicy": "none",
"pinnedPostUrl": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l",
"labels": [],
"joinedAt": "2023-04-12T04:53:57Z",
"indexedAt": "2026-11-04T15:41:10Z",
"relation": null,
"sourceInput": "bsky.app",
"scrapedAt": "2026-11-06T19:30:39Z"
}

In the dataset, the Posts view shows type, author, text, likes, reposts, replies, date and link; the Profiles view shows handle, name, bio, followers, following, posts, join date and profile link. Every field is in the full JSON, CSV and Excel exports.

Advanced usage

Turn a starter pack into a prospect list

{
"startUrls": [{ "url": "https://bsky.app/starter-pack/bsky.app/3mzdvli2fkq23" }],
"maxResults": 200
}

A starter pack is a hand-picked group of accounts on one topic. Each member becomes a profile row with bio, follower counts and the emails or links found in the bio, tagged starterPackMember. A Bluesky list (/lists/...) works the same way, tagged listMember. Sort by followersCount and you have a ranked outreach list.

Find people by what they do, then rank them by reach

{
"queries": ["data journalist", "climate scientist"],
"searchType": "people",
"maxResults": 100
}

People search matches names and bios. Each account comes with its follower, following and post counts, its join date and its verified badge. In our run, one keyword plus a likers list and a starter pack gave 30 profiles, every one with its follower count, in 3 seconds.

Collect everyone who engaged with a launch post

{
"startUrls": [
{ "url": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l/liked-by" },
{ "url": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l/reposted-by" },
{ "url": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l/quotes" }
],
"maxResults": 500
}

Likers and reposters come as profile rows (relation says which), the quotes as post rows with their own text and engagement. Instead of the three suffixed links, you can paste the plain post link and set postData to likers, reposters or quotes.

Run a daily brand watch on a schedule

{
"queries": ["mentions:nytimes.com", "domain:nytimes.com", "\"New York Times\""],
"since": "1 day",
"maxResults": 1000
}

Three keywords catch posts that tag the account, posts that link to the website, and posts that name the brand: replace The New York Times with your own brand, handle and domain. Schedule the run daily in Apify: with since set to 1 day, each run returns the last day only, and the same post found by two keywords is delivered once.

Rebuild a full conversation for research

{
"startUrls": [{ "url": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l" }],
"postData": "replies",
"minLikes": 10,
"maxResults": 1000
}

The post you paste always comes first (depth 0), then its direct replies, then the replies to those replies. Every reply keeps threadDepth and parentUri, so the tree can be rebuilt in any tool. minLikes keeps the replies people agreed with and never drops the post itself.

FAQ

What does this scraper extract? Public Bluesky posts (text, hashtags, mentions, links, images, videos, link cards, quoted posts, likes, reposts, replies, quotes, bookmarks, thread position, date) and public profiles (bio, emails and links from the bio, followers, following, posts, lists, feeds, starter packs, verified badge, join date). Every post also carries its author's follower count and bio.

Do I need a Bluesky account or an app password? No. The run reads what Bluesky shows to any visitor who is not logged in. There is nothing to connect and nothing to share.

What is Bluesky? Bluesky is a social network in the style of X (Twitter): short posts, replies, reposts, quotes and follows. It grew to tens of millions of accounts, with many journalists, researchers, developers and public institutions, and its public posts are open to read.

How far back does a keyword search go? With Latest posts, as far as maxResults asks: the run reads page after page back in time. In our test, web scraping returned 250 posts covering 10 days in 4 seconds. Top posts returns the first 100 that Bluesky ranks for a keyword, which is all Bluesky shows a logged-out visitor for that ranking.

Can I combine the filters? Yes, they all apply together. language: French, minLikes: 5 and since: 30 days keep French posts with at least 5 likes from the last 30 days. Inside a keyword you can also use Bluesky's own filters, such as from:nytimes.com climate, mentions:bsky.app or domain:github.com.

Can I mix keywords, accounts and links in one run? Yes. Keywords run first, then accounts and links, in the order you list them. maxResults applies to each of them, and a post found twice (by a keyword and by an account feed, for example) is delivered once.

How fresh is the data? Live: every run reads Bluesky at the moment it runs. Counts (likes, followers) are the ones Bluesky shows at that moment.

Why are some accounts or posts missing? Some Bluesky members ask that their posts and profile be hidden from visitors who are not logged in. This scraper respects that choice: those accounts are skipped and counted in the log (5 in our default run). Deleted posts and accounts are skipped too, and named in the log.

Why is lang empty on some posts? The language comes from the author's app, and some apps and bridged accounts do not tag it. The language filter only keeps posts that carry the language you ask for.

Do image and video links last? They point to Bluesky's media servers and work as long as the post exists. Download the files you want to archive.

Can I get a custom feed? Yes, paste its bsky.app link. Most public feeds work, such as Discover; a few feeds are built for the logged-in member (Following, Mutuals, Popular With Friends) and return nothing to a visitor: the log says so and the rest of the run goes on.

More SilentFlow scrapers

๐Ÿ›’ E-commerce

๐Ÿ’ผ Jobs

๐Ÿ  Real estate

๐Ÿ“ฃ Social media

๐Ÿข Business data

โœˆ๏ธ Travel

๐ŸŽฏ Lead generation

๐Ÿ”Ž SEO

๐ŸŽฌ Video

๐Ÿ“ฐ News

๐Ÿงฐ More tools

Support

Need something this scraper doesn't do yet? We ship features fast.

  • Feature requests go straight to our backlog
  • Enterprise needs? We do custom integrations and high-volume plans
  • Pricing questions? Check the Monetization tab on the actor page

Response time: usually under 24 hours.

This Actor extracts publicly available data from Bluesky, as shown to visitors who are not logged in. It does not bypass any login, paywall or CAPTCHA, never uses a Bluesky account, and skips the members who ask Bluesky to hide them from logged-out visitors. Users are responsible for complying with Bluesky's terms of service and applicable data protection laws (GDPR, CCPA, and PIPL where relevant). Posts, profiles, bios, emails and links found in bios are personal data: handle them accordingly, keep only what you need, and honor removal requests. The data returned is informational; verify accuracy for regulated use cases.

Bluesky Scraper by SilentFlow: public posts with their author's audience, profiles, followers, likers and starter packs, in one run.