Bluesky Scraper — Posts, Search, Profiles, Comments & Followers
Pricing
$1.20 / 1,000 results
Bluesky Scraper — Posts, Search, Profiles, Comments & Followers
Collect public Bluesky posts, keyword search results, profiles, replies, followers and following without logging in. Get text, likes, reposts, quotes, media and links as JSON or CSV for social listening, brand monitoring and research.
Pricing
$1.20 / 1,000 results
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Bluesky Scraper
Bluesky Scraper collects public Bluesky posts, keyword search results, profiles, replies, followers and following into one structured dataset, without a Bluesky login. Use it for social listening, brand monitoring, community research, content analysis and public account monitoring. You can combine accounts, individual posts and search terms in the same run. Every delivered row identifies its type and the original input that produced it, so you can keep different research questions together without losing their context.
What Bluesky Scraper collects
Profile rows include the account DID, handle, display name, full biography, profile URL and the follower, following and post counts when the source provides them. Optional fields include the avatar, banner, creation date, verification status and links extracted from the biography. Handles are returned without a leading @. If an account has an invalid handle, its public URL uses its stable DID instead.
Post rows include the public URL, globally unique record URI, author identifiers, original text, publication time, likes, reposts, direct reply count, quotes and bookmarks when available. Image, gallery and video links are returned with the post. Outgoing links, hashtags, mentions and source language codes are included where present. Reposts retain the original post author and carry a separate indicator and reposting account.
Comment rows represent public replies to an individual requested post. Each row carries the requested anchor post ID, its own comment ID, parent reference and depth. A direct reply has a null parent comment ID. The original thread root can differ from the requested anchor when you request a post that is itself a reply.
Use cases for a Bluesky scraper
- Social listening and brand monitoring. Search Bluesky posts for a brand, product, campaign hashtag or competitor and track mentions, engagement and language over time.
- Research and academic datasets. Build reproducible samples of public Bluesky posts for a topic or time window with
sinceanduntil, and keep the exact query that produced each row. - Influencer and creator analysis. Pull a creator's profile, follower count and author feed, then compare likes, reposts and quotes per post.
- Audience and community mapping. Export the followers or following list of an account as profile rows, optionally enriched with their own follower and post counts.
- Conversation analysis. Fetch the full public reply thread under a post to study reactions, sentiment and who replies to whom.
- Migration tracking. Monitor which accounts in your industry are active on Bluesky and how fast their audience grows, by running the same handles on a schedule.
Input
Supply at least one non-empty list of handles, post_urls or queries. A list accepts up to 100 entries. Accounts may be handles, DIDs or public profile URLs. Post inputs may be public Bluesky post URLs or AT record URIs. Queries accept terms and source-supported operators, including from:bsky.app and hashtags.
This input requests the official Bluesky profile without its author feed:
{"handles": ["bsky.app"],"include_posts": false}
This search input returns up to 250 recent posts for a term used in our collected source responses:
{"queries": ["climate"],"sort": "latest","max_items": 250}
include_posts defaults to true for account inputs. feed_filter defaults to posts_no_replies; the other supported values are posts_with_replies, posts_with_media and posts_and_author_threads. Reposts remain included unless you set include_reposts to false. These switches apply to author feeds.
include_comments defaults to true for individual post inputs. It does not fetch a thread for every search or feed result. Set it to false when you only need the selected posts and their engagement counts. include_followers and include_following default to false. Enable either to receive the related accounts as profile rows with the relationship origin attached.
Follower and following list responses usually omit account counts. Set enrich_profiles to true to request those counts as an additional step. Unavailable counts remain absent; a missing value does not imply zero followers. The run reports a warning if a requested enrichment could not complete.
For searches, since and until accept an ISO date or timestamp, lang accepts a two-letter language code and author restricts results to an account. sort defaults to latest. top delivers at most 100 posts per query and reports that limit when you request more.
Output
The default dataset contains profile, post and comment rows. Both record_type and _type identify the row type. Every row includes source, platform, fetched_at, input_type, input and a stable row_id. Times are normalized to UTC. The run's OUTPUT record contains delivery counts, warnings and completion information.
Profile records use profile_id, profile_url, handle, name, bio, followers, following and posts_count. Post records use post_id, post_url, uri, author_handle, author_id, text, posted_at, likes, shares and comments_count. Comments add comment_id, comment_url, parent_comment_id, parent_uri, thread_root_uri and depth.
shares means reposts; quotes have their own quotes field. comments_count is the source's direct reply count rather than the number of all descendants delivered. Bluesky does not provide a view count, so the scraper does not invent one. Record keys are unique within an author; use uri when joining posts globally.
You can export the dataset as JSON or CSV through Apify. JSON preserves media arrays and relationship references most naturally. When comparing runs, remember that engagement counts describe the moment the source response was fetched and may change later.
Example profile row
This is the real row returned for the input {"handles": ["bsky.app"], "include_posts": false}:
{"source": "bluesky-scraper","platform": "bluesky","record_type": "profile","_type": "profile","row_id": "[\"profile\",\"handle\",\"bsky.app\",\"did:plc:z72i7hdynmk6r22z27h6tvur\"]","input_type": "handle","input": "bsky.app","fetched_at": "2026-10-05T04:10:22.000Z","profile_url": "https://bsky.app/profile/bsky.app","profile_id": "did:plc:z72i7hdynmk6r22z27h6tvur","handle": "bsky.app","name": "Bluesky","bio": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app","avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka","banner_url": "https://cdn.bsky.app/img/banner/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreichzyovokfzmymz36p5jibbjrhsur6n7hjnzxrpbt5jaydp2szvna","followers": 35150226,"following": 15,"posts_count": 865,"lists_count": 18,"feeds_count": 7,"starter_packs_count": 15,"created_at": "2023-04-12T04:53:57.057Z","indexed_at": "2025-10-27T21:05:26.152Z","links": [],"pinned_post_uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l","verified_status": "none","labels": []}
Example post row
This is the real anchor post row returned for a post_urls input, before its reply rows:
{"source": "bluesky-scraper","platform": "bluesky","record_type": "post","_type": "post","row_id": "[\"post\",\"post_url\",\"at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mv6jm4auic2g\",\"at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mv6jm4auic2g\"]","input_type": "post_url","input": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mv6jm4auic2g","fetched_at": "2026-10-05T04:10:22.000Z","uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mv6jm4auic2g","post_id": "3mv6jm4auic2g","post_url": "https://bsky.app/profile/bsky.app/post/3mv6jm4auic2g","cid": "bafyreia6h2jdgzc7nuvsfpwdkw3synzz73vkobyamndabthoy4gb5zersq","author_handle": "bsky.app","author_id": "did:plc:z72i7hdynmk6r22z27h6tvur","author_name": "Bluesky","text": "Thanks for being with us here on Bluesky, the official app of sports™️","likes": 326,"shares": 16,"comments_count": 9,"quotes": 2,"bookmarks": 1,"indexed_at": "2026-09-10T16:59:31.364Z","posted_at": "2026-09-10T16:59:29.774Z","media": [],"links": [],"mentions": [],"hashtags": [],"langs": ["en"],"labels": [],"reply_parent_uri": "at://did:plc:2buz4gf5sew3rdwzbxsvcd4s/app.bsky.feed.post/3mv6ghymh3s27","reply_root_uri": "at://did:plc:2buz4gf5sew3rdwzbxsvcd4s/app.bsky.feed.post/3mv6ghymh3s27","is_reply": true,"is_repost": false}
Limits and continuation
max_items defaults to 100 and can be set from 1 to 10000. It applies separately to each account feed, each query, each requested post's replies and each account's follower or following list. The account profile and requested anchor post are additional rows. Two queries with a limit of 100 can therefore deliver up to 200 post rows.
Apify automatically follows continuation pages. If you consume individual responses, send the returned cursor with the same original input and options to continue. Warnings explain incomplete source results. Large threads may be truncated by Bluesky, and deleted or blocked replies are unavailable. Search results are also subject to source indexing and moderation: pagination cannot guarantee a complete historical archive.
Bluesky Scraper compared with other options
| This Bluesky scraper | Bluesky's own API | Browser export extensions | Single-purpose scrapers | |
|---|---|---|---|---|
| Code required | No | Yes, plus pagination and rate handling | No | No |
| Login required | No | Search needs extra setup | Varies | Varies |
| Posts, search, profiles, replies and followers in one run | Yes | Separate endpoints | Usually one page at a time | One data type per actor |
| More than 100 search results per query | Yes, with sort: latest | Manual cursor handling | Limited by scrolling | Varies |
| Scheduling, webhooks and integrations | Yes, through Apify | Build it yourself | No | Yes |
| Input kept on every row | Yes (input_type, input) | No | No | Varies |
If you only need a handful of posts once, a browser extension is fine. If you need repeatable datasets, several data types at once, or a Bluesky API without writing and hosting your own client, this actor saves that work.
Pricing
The actor uses a result event for each delivered dataset row, regardless of whether it is a profile, post or comment. At launch that is $0.0012 per row, so 1,000 rows cost $1.20; the Apify pricing panel on this page always shows the current event price. Empty results incur no result events and there is no actor start event in this product's charging configuration. A run with partial results charges only for the rows it delivers, and continuation pages do not charge duplicate rows again.
Users without a paid Apify plan receive at most ten dataset rows per run. Their requested volume is limited before collection, and delivery and result events are capped at ten. This cap applies to the combined dataset across all row types and inputs. Paid users retain their requested limits.
FAQ
Do I need a Bluesky account?
No account credentials are required for the public data this actor currently collects. Private, deleted or blocked records are not made available by the scraper. Search availability depends on what Bluesky exposes publicly and can change.
Can I search Bluesky posts without an account?
Yes. Put your terms in queries and the actor returns matching public posts with their engagement counts. Use author or the from: operator to search posts by one user, lang to restrict the language, and since and until for a date range.
Can I fetch more than 100 search results?
Yes, use sort: latest and increase max_items. Collection continues through older time windows and removes repeated record URIs. sort: top remains limited to one source page with at most 100 results. Dense groups of identical timestamps can limit further progress; the run reports that condition.
How do I export Bluesky followers?
Add the account to handles and set include_followers (or include_following) to true. Each related account becomes a profile row that you can download as CSV or JSON from the dataset. Set include_posts to false if you only want the list.
Why are follower counts missing from follower rows?
The public relationship lists omit these counts. Enable enrich_profiles to request full profiles for those accounts. If a profile is unavailable, its missing count stays absent and the run reports incomplete enrichment.
Are all replies in a large thread included?
Bluesky can omit replies from large threads. The actor reports an incomplete thread when the available direct replies do not match the source count, or unavailable reply nodes are present. A successful run may therefore contain useful comment rows together with a source warning.
How do I separate different research inputs?
Filter on input_type and input. These fields retain the original account, URL or query, while record_type separates profiles, posts and comments. The same post found through two different inputs retains both contexts; repeated rows within a continuation are removed.
Can I use this Bluesky scraper as an API?
Yes. Every Apify actor can be started through the Apify API or client libraries, and the dataset can be read as JSON or CSV when the run finishes. You can also schedule runs or send results to other tools with webhooks and integrations.