Bluesky Scraper: Posts, Search, Profiles, Followers
Pricing
from $1.10 / 1,000 post or profiles
Bluesky Scraper: Posts, Search, Profiles, Followers
Scrape Bluesky with its official public API, no login: search posts by keyword, hashtag, author or date, get any profile's posts, profiles, followers and follows, replies to a post, likers and reposters. Clean rows with links, hashtags, images and counts.
Pricing
from $1.10 / 1,000 post or profiles
Rating
0.0
(0)
Developer
Charles Markette
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Bluesky Scraper collects public Bluesky data through Bluesky's official public API, with no login and no account needed. It can search posts by keyword, hashtag, author, language or date, get every post from a profile, get profile details with follower, following and post counts, list a profile's followers or the accounts it follows, get the replies to a post, and list who liked or reposted a post. Paste bsky.app links, handles or DIDs, or read them from another run's dataset. Each post comes as one clean row: text, date, author, like, repost, reply and quote counts, hashtags, mentions, links, images, link cards and quoted posts.
Why this Actor
- Official API, no login. Every request goes to Bluesky's public AppView API (
api.bsky.app), the same public data the Bluesky app shows to someone who isn't signed in. No cookies, no browser, no account of yours at risk. - Takes what you copy.
https://bsky.app/profile/alice.bsky.social,@alice.bsky.social,alice(read as alice.bsky.social),did:plc:..., post links likehttps://bsky.app/profile/alice.bsky.social/post/3l...andat://URIs all work. - Accurate rich text. Hashtags, mentions and links are read from Bluesky's facets, which count UTF-8 bytes, so text with emoji or accents is cut correctly. Link cards, image alt text and quoted posts are parsed too.
- Polite and reliable. At most 3 requests at a time, retries when Bluesky is busy or rate-limits (honouring
Retry-AfterandRateLimit-Reset), and a pause when the rate-limit window runs low. A failed input becomes a free row with anerrormessage instead of stopping the run. - No duplicates. A post found by two searches is output (and charged) once per run. If the run is restarted on the platform, rows already saved aren't output or charged again.
Use cases
- Brand and keyword monitoring: search your brand, product or competitors every hour with Posted after =
2 hours, and get alerts for new posts. - Social listening and research: collect posts on a topic or hashtag, in a language, over a date range, with engagement counts.
- Influencer and lead research: profile details, follower counts and bios for a list of accounts; followers of a competitor or a community account.
- Content analysis: a creator's full posting history with likes, reposts, replies, quotes, links and images.
- Conversation analysis: all replies under a post, with their depth in the thread, or the accounts that liked or reposted it.
How to use it
- Choose What to scrape.
- Add Search terms (Search posts), Profiles (Posts from profiles, Profiles, Followers, Following) or Post links (Replies, Who liked, Who reposted). Or pick a Dataset to read inputs from.
- Set Max items per input (default 100) and, if you like, Max output rows for the whole run.
- Run it. Export as CSV, Excel or JSON, or chain it with an integration.
Input example: search
{"mode": "search","searchQueries": ["web scraping", "#opendata"],"sort": "latest","since": "7 days","lang": "en","maxItemsPerQuery": 200}
Input example: a profile's posts, without reposts
{"mode": "profilePosts","handles": ["https://bsky.app/profile/bsky.app"],"authorFeedFilter": "posts_no_replies","includeReposts": false,"maxItemsPerQuery": 500}
Output example: a post (shortened)
{"uri": "at://did:plc:abc123.../app.bsky.feed.post/3l6abcxyz2k2a","cid": "bafyrei...","url": "https://bsky.app/profile/alice.bsky.social/post/3l6abcxyz2k2a","text": "Café ☕ cats 🐈 #caturday with @bob.bsky.social see example.com/cats","createdAt": "2026-10-20T12:00:00.123Z","indexedAt": "2026-10-20T12:00:01.000Z","lang": "en","langs": ["en"],"authorHandle": "alice.bsky.social","authorDid": "did:plc:abc123...","authorDisplayName": "Alice","authorAvatar": "https://cdn.bsky.app/img/avatar/plain/...","replyCount": 2,"repostCount": 5,"likeCount": 40,"quoteCount": 1,"isReply": false,"replyToUri": null,"rootUri": null,"isRepost": false,"repostedBy": null,"hashtags": ["caturday"],"mentions": ["bob.bsky.social"],"mentionDids": ["did:plc:bob..."],"links": ["https://example.com/cats"],"images": [{"url": "https://cdn.bsky.app/img/feed_fullsize/plain/...@jpeg", "alt": "A grey cat"}],"video": null,"externalLink": null,"quotedPostUri": null,"labels": [],"query": "cats","sourceInput": "cats","scrapedAt": "2026-10-22T09:00:00.000Z","error": null}
Other post columns: replyToHandle, repostedAt, quotedPostText, quotedPostAuthorHandle, externalLink ({uri, title, description} for link cards), video ({playlist, thumbnail, alt}) and threadDepth (in Replies to posts: 1 = a direct reply, 2 = a reply to a reply, 0 = the post itself).
Output example: a profile (shortened)
{"did": "did:plc:abc123...","handle": "alice.bsky.social","displayName": "Alice","description": "Cats and code.","avatar": "https://cdn.bsky.app/img/avatar/plain/...","banner": "https://cdn.bsky.app/img/banner/plain/...","followersCount": 1200,"followsCount": 310,"postsCount": 4210,"createdAt": "2023-05-01T10:00:00.000Z","indexedAt": "2024-01-01T00:00:00.000Z","labels": [],"pinnedPostUri": "at://did:plc:abc123.../app.bsky.feed.post/3k...","url": "https://bsky.app/profile/alice.bsky.social","sourceInput": "alice","error": null}
Followers rows add followerOf and subjectDid (the profile they follow); Following rows add followedBy and subjectDid; Who liked rows add likedPostUri and likedAt; Who reposted rows add repostedPostUri. A run summary (per-input pages, rows, why each input stopped) is saved as OUTPUT in the key-value store.
How much does it cost?
Pay per event: $1.10 per 1,000 posts or profiles ($0.0011 per output row), with Apify platform usage included. Each run also has Apify's run start fee of $0.005 (one start event per GB of run memory; the default 256 MB run is charged one). These rows are free: inputs that aren't a valid handle, DID, link or search term, profiles or posts that don't exist, and inputs Bluesky couldn't answer for (each with an error). Duplicates skipped within a run cost nothing.
Worked examples (Actor-start charge not included):
- 1,000 posts from a keyword search: 1,000 × $0.0011 = $1.10.
- 500 profiles with follower counts: $0.55.
- An hourly brand monitor that finds about 20 new posts each run: about $0.022 per run, roughly $16 per month for 720 runs.
If you set a maximum cost per run, the Actor stops cleanly at that limit and keeps everything it saved.
FAQ and limits
What data can it get?
Only public data that Bluesky's public API serves without signing in. It can't see private or signed-in-only content, blocked content, deleted posts or direct messages. Accounts that ask Bluesky to hide their content from logged-out viewers may return nothing, or a free error row with Bluesky's reason.
How far back does search go?
As far as Bluesky's search returns results. Search is run by Bluesky, and deep into a result list it can stop returning more pages; the Actor then stops that search cleanly and notes why in the run summary. For a long history, run several searches with narrower Posted after / Posted before ranges, or use Posts from profiles for specific accounts. Top sort is Bluesky's own ranking.
Are the like and follower counts live?
They are the counts at the moment of the run (see scrapedAt). Run again to refresh them.
Why are followersCount and postsCount empty in Followers mode?
Bluesky lists followers without their counts. Turn on Add follower and post counts to look each account up (one extra request per 25 accounts, same price per row).
Can it get every reply in a thread?
It gets the replies in Bluesky's public thread view, up to the Reply depth you set (default 6 levels). Replies Bluesky doesn't include there, such as deleted or blocked ones, are not output.
Does it watch for only new posts?
Each run outputs what it finds. For "only new posts" monitoring, schedule it with Posted after (for example 2 hours on an hourly schedule), or pass the results through Merge & Deduplicate Datasets (below) to keep only posts you haven't seen before.
Is it fast?
It stays within Bluesky's public rate limits on purpose: at most 3 requests at a time, 100 posts or accounts per request. When Bluesky rate-limits, the Actor waits for the window to reset and continues.
Related Actors
| Actor | Use it to |
|---|---|
| Merge & Deduplicate Datasets | Keep only posts you haven't seen in earlier runs, for a "new posts only" monitor. |
| Send Email Report & Slack, Discord, Teams, Telegram Alerts | Get an alert with the new posts after each scheduled run. |
| Google Sheets Sync | Send posts or profiles to a Google Sheet. |
| Dataset Filter & Transform | Keep only posts above a like count, rename or flatten fields before export. |
Data source: Bluesky's public AppView API. This Actor is not made by or affiliated with Bluesky Social PBC.