Bluesky Scraper — Posts, Profiles, Feeds & Followers avatar

Bluesky Scraper — Posts, Profiles, Feeds & Followers

Pricing

$1.00 / 1,000 result items

Go to Apify Store
Bluesky Scraper — Posts, Profiles, Feeds & Followers

Bluesky Scraper — Posts, Profiles, Feeds & Followers

Scrape Bluesky without login: posts by keyword or hashtag, account feeds, likes, custom feeds, lists and reply threads, plus profiles, followers and following. Monitoring mode outputs only new posts.

Pricing

$1.00 / 1,000 result items

Rating

0.0

(0)

Developer

Trevor Ortega

Trevor Ortega

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Scrape Bluesky without logging in: posts by keyword or hashtag, any account's posts, replies, media or likes, custom feeds, lists, starter packs and full reply threads, plus profile data, followers and following lists. It uses Bluesky's public AT Protocol API, so there is no app password to share and no browser to slow things down: a run of 2,000 posts finishes in about 20 seconds.

Export to JSON, CSV or Excel, or pull the results through the API into Google Sheets, a database or an LLM pipeline. You pay only for the items you get.

What data does Bluesky Scraper extract?

Every item has type: "post" or type: "profile", plus source (the search term, account or URL it came from) and sourceType.

Posts

FieldDescription
uri, cid, postIdAT Protocol identifiers of the post
urlLink to the post on bsky.app
textPost text
createdAt, indexedAtWhen the post was written and when Bluesky indexed it (UTC ISO 8601)
langsLanguages the author tagged
authorHandle, authorDid, authorDisplayName, authorAvatar, authorUrl, authorLabelsWho wrote it
likeCount, repostCount, replyCount, quoteCount, bookmarkCountEngagement counts
hashtags, mentions (did + handle), linksFrom the post's rich-text facets
embedTypeimages, video, external, record (quote), recordWithMedia or null
imagesurl (full size), thumbnail, alt text, width, height
videoHLS playlist URL, thumbnail, alt, size
externalLinkLink card: url, title, description, thumbnail
quotedPostQuoted post: uri, url, text, author, counts, its media
isReply, replyParentUri, replyRootUri, replyToHandleReply context
labelsModeration and self-labels (e.g. porn, graphic-media)
isRepost, repostedByHandle, repostedAtWhen reposts are included
threadDepth, threadRootUriFor post threads (0 = the post, 1 = direct reply, ...)
likedByHandle, likedAtFor an account's likes

Profiles (profile data, followers, following, list members)

FieldDescription
handle, did, displayName, urlWho it is
descriptionBio
followersCount, followsCount, postsCountCounts
createdAtWhen the account was created
avatar, bannerImage URLs
labels, verifiedStatus, pinnedPostUri, listsCount, feedsCount, starterPacksCount, isLabeler, pronouns, websiteExtra profile data
relation, relationToHandleprofile, follower, following or listMember, and of which account
listName, listUri, listPurposeFor list and starter pack members

How to use Bluesky Scraper

  1. Pick what you want, and combine as many as you like in one run:
    • Search terms: keywords, phrases or hashtags (#python, "open source"), with optional filters for date range, language, author, mentioned account and linked domain.
    • Accounts: handles, DIDs or profile URLs, and What to get from accounts (posts, posts and replies, media, videos, likes, followers, following, or profile data only).
    • Bluesky URLs: posts (with their reply thread), custom feeds, lists, starter packs, profile pages, /followers and /follows pages, search and hashtag pages.
  2. Set Max items (and optionally Max items per source) to cap the run and the cost.
  3. Click Start. Results appear in the Dataset tab, with separate views for posts and profiles.

Input example

{
"searchTerms": ["#python", "climate change"],
"searchSort": "latest",
"since": "7 days",
"language": "en",
"profiles": ["nytimes.com"],
"profileContent": "posts",
"startUrls": [
{ "url": "https://bsky.app/profile/bsky.app/feed/whats-hot" },
{ "url": "https://bsky.app/profile/bsky.app/post/3mv6jm4auic2g" },
{ "url": "https://bsky.app/profile/bsky.app/followers" }
],
"maxItemsPerSource": 200,
"maxItems": 1000
}

Output example

{
"type": "post",
"uri": "at://did:plc:tartlcpup67v55wn7z35pet6/app.bsky.feed.post/3mxhxudjb5k25",
"url": "https://bsky.app/profile/coredispatch.xyz/post/3mxhxudjb5k25",
"postId": "3mxhxudjb5k25",
"text": "It's been a while, but Core Dispatch 11 is out! Happy Python 3.15 final day to all that celebrate! Congrats to @hugovk.dev ...",
"createdAt": "2026-10-09T21:58:59.110Z",
"langs": ["en"],
"authorHandle": "coredispatch.xyz",
"authorDid": "did:plc:tartlcpup67v55wn7z35pet6",
"authorDisplayName": "Core Dispatch",
"likeCount": 3,
"repostCount": 1,
"replyCount": 0,
"quoteCount": 0,
"isReply": false,
"hashtags": [],
"mentions": [{ "did": "did:plc:3yxbv667vvngelzbmtphu6lf", "handle": "hugovk.dev" }],
"links": ["https://coredispatch.xyz/editions/11"],
"embedType": "external",
"externalLink": { "url": "https://coredispatch.xyz/editions/11", "title": "Core Dispatch #11", "description": "Welcome back to Core Dispatch! ...", "thumbnail": "https://cdn.bsky.app/img/feed_thumbnail/plain/..." },
"images": [],
"video": null,
"quotedPost": null,
"labels": [],
"isRepost": false,
"source": "python",
"sourceType": "search"
}
{
"type": "profile",
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"description": "official Bluesky account (check username👆) ...",
"url": "https://bsky.app/profile/bsky.app",
"followersCount": 35206293,
"followsCount": 17,
"postsCount": 867,
"createdAt": "2023-04-12T04:53:57.057Z",
"avatar": "https://cdn.bsky.app/img/avatar/plain/...",
"banner": "https://cdn.bsky.app/img/banner/plain/...",
"relation": "profile",
"source": "bsky.app",
"sourceType": "profile"
}

How to scrape Bluesky posts by keyword or hashtag

Add the words to Search terms, one per line. Hashtags (#python), exact phrases ("machine learning") and Bluesky operators (from:handle, lang:en, domain:nytimes.com) all work. Latest returns posts newest first and keeps paging back in time until Max items or Posted after is reached. Top returns Bluesky's most relevant posts; without a login Bluesky serves only the first page of top results, so expect up to about 100 top posts per term. Narrow the search with Posted after/before (a date or a period such as 7 days), Language, From account, Mentioning account and Linking to domain.

Does it work without a Bluesky account or app password?

Yes. Everything comes from Bluesky's public AppView API, the same data the bsky.app website shows to logged-out visitors. You never share credentials. Posts that their authors restricted to logged-in users are not returned, and Bluesky's search refuses some filter combinations without a login: a search made only of operators (for example just from:bsky.app) returns a single page and cannot use date filters, so add a keyword or use Accounts to get someone's full history.

How to export Bluesky followers and following lists

Put the accounts in Accounts and choose Followers or Following under What to get from accounts, or paste the /followers and /follows page URLs. Each follower comes out as a profile item with handle, display name, bio, avatar, created date and, with Full profile details on (default), followers/following/posts counts. Lists and starter packs work the same way with What to get from lists set to Members.

Can I scrape a post's replies, custom feeds and lists?

Yes. Paste a post URL to get the post and its whole reply tree (set the depth with Reply depth), a custom feed URL (https://bsky.app/profile/<creator>/feed/<name>) to get the posts that feed serves, or a list URL to get the recent posts of its members. An account's liked posts are public on Bluesky too: choose Liked posts to get them, each with likedAt.

Monitor changes on a schedule

Turn on Only new posts (monitoring) to get a feed of what appeared since the last run: the Actor remembers which posts (and followers, likes or list members) earlier runs of the same input returned and outputs only new ones. Items already seen are dropped before they are saved, so they are not charged, and newest-first sources (searches, account posts, followers) stop at the first page with nothing new, so a quiet watch costs a request or two. Max items per source then sets how many of the newest items are checked per source (50 is plenty for a daily schedule). Save the input as a task, add a Schedule in Apify (hourly or daily), and give each watch its own Monitoring key if several schedules use the same input. Every output item carries changeType: "new"; like and follower counts are not tracked, so previousValues does not appear.

Pricing

Pay per result: one post or one profile is one result. There is no start fee and no subscription; Apify's free plan is enough to try it. Platform usage is billed separately and is small (about $0.005 per 1,000 items, mostly dataset storage).

Integrations and API

Use the run in Zapier, Make, n8n or Google Sheets, or call it from Python/Node with the Apify client. See the API tab for ready-made snippets. Proxy: Apify datacenter proxy (the default) is enough; it spreads requests over IPs so large runs do not hit Bluesky's per-IP rate limit.

This Actor collects only data that Bluesky publishes openly through its public API to anyone without an account: posts, public profile data (handles, display names, bios, avatars, counts) and public social-graph records such as follows and likes. It does not log in, read direct messages, or access content restricted to logged-in users. Public data can still include personal information, so you are responsible for how you use it and for complying with Bluesky's terms, the authors' copyright, and privacy laws such as the GDPR.

Support

Found a bug or need a field added? Open an issue in the Issues tab; it is usually answered within a day.