Bluesky Scraper - Posts, Profiles, Threads, Followers
Pricing
from $2.00 / 1,000 results
Bluesky Scraper - Posts, Profiles, Threads, Followers
Scrape Bluesky (bsky.app) without login: keyword post search (latest/top, date, language, author, hashtag, domain filters), author feeds with engagement counts and media, profiles, full reply threads, followers, follows and people search. Pure HTTP via the public AT Protocol API.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Thirdwatch
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 hours ago
Last modified
Categories
Share
What you get
Scrape Bluesky (bsky.app) without an account, an app password or a browser. This Actor talks to the public AT Protocol AppView over plain HTTP, so it is fast, cheap and does not risk any login of yours. One Actor covers seven jobs:
| Mode | You give | You get |
|---|---|---|
searchPosts | keywords (+ your app password) | posts matching the query, newest-first or ranked by engagement, with date / language / author / hashtag / domain filters |
authorFeed | handles | an account's posts with like, repost, reply, quote and bookmark counts, media, quoted posts and a repost flag |
profile | handles or DIDs | one profile record per account: bio, follower / following / post counts, avatar, banner, verification |
thread | post URLs | the post plus every reply below it, flattened with a depth field |
followers | handles | who follows the account |
follows | handles | who the account follows |
searchActors | keywords | people search: profiles whose name, handle or bio matches |
It accepts plain handles (bsky.app), @handles, DIDs (did:plc:...), at:// URIs and any bsky.app URL (profile, post, followers, follows, hashtag, search) and routes each one to the right mode automatically.
One exception to "no login": in 2026 Bluesky switched off post search for logged-out clients (bsky.app itself shows "Search is currently unavailable when logged out"). Six of the seven modes above are fully public. searchPosts alone needs a Bluesky app password of your own, passed in the optional identifier / appPassword fields; the Actor opens a session on your account's PDS and runs the search through it. Never use your main password - create an app password under Settings -> Privacy and security -> App passwords and revoke it whenever you like.
Pricing is $0.50 per 1,000 records on the free plan and drops on paid Apify plans. There is no platform fee on top; you pay only for what lands in the dataset.
Why scrape Bluesky?
Bluesky has grown into one of the largest open social networks, and unlike most platforms its data model (AT Protocol) is designed to be read publicly. That makes it the easiest place to get real, timestamped, engagement-scored social data for:
- Brand and keyword monitoring - track mentions of your product, competitor or campaign hashtag as they happen with
searchPostssorted bylatest. - Audience research - pull an account's followers or the accounts it follows, then profile them.
- Influencer discovery -
searchActorsfor a niche, thenprofilethe shortlist to compare follower counts and posting volume. - Content analysis - export an author's full feed with engagement counts to see what performs.
- Conversation mining - pull a viral post's whole reply thread with
threadfor sentiment or Q&A datasets. - Academic and journalism datasets - reproducible keyword pulls with
since/untilwindows and language filters.
Input
All fields are optional; give at least one of queries, handles or postUrls.
| Field | Type | Default | Notes |
|---|---|---|---|
mode | select | auto | auto derives the mode from your inputs: postUrls -> thread, queries -> searchPosts, handles -> authorFeed. Set profile, followers, follows or searchActors explicitly. |
queries | list of strings | Keywords for searchPosts / searchActors. Inline operators work: from:handle, mentions:handle, lang:en, since:2026-01-01, #tag, domain:example.com. | |
handles | list of strings | Accounts for authorFeed / profile / followers / follows. Handle, @handle, DID or profile URL. | |
postUrls | list of strings | Posts for thread. https://bsky.app/profile/{handle}/post/{id} or at:// URI. Profile / followers / follows / hashtag / search URLs are accepted here too and routed by shape. | |
maxItems | integer | 100 | Cap per keyword / handle / post URL (1 - 10,000). profile mode always returns one record per handle. |
sort | latest / top | latest | searchPosts ordering. |
since, until | date | searchPosts window. YYYY-MM-DD or full ISO 8601. | |
language | string | searchPosts. BCP-47 code such as en, pt, ja. | |
author | string | searchPosts. Only posts by this handle / DID. | |
mentions | string | searchPosts. Only posts mentioning this handle / DID. | |
hashtag | string | searchPosts. Only posts carrying this tag. | |
domain | string | searchPosts. Only posts linking to this domain. | |
identifier | string | searchPosts only. Your Bluesky handle or email. | |
appPassword | secret string | searchPosts only. An app password for that account (encrypted at rest by Apify). | |
includeReplies | boolean | false | authorFeed. Include the account's replies to other people. |
includeReposts | boolean | true | authorFeed. Include reposts (flagged is_repost: true). |
threadDepth | integer | 6 | thread. Reply levels to collect (1 = direct replies only, max 100). |
minLikes, minReposts, minReplies | integer | 0 | Drop posts / replies below these counts. Applied locally after fetching. |
Example: keyword search, English, last week, top posts
{"queries": ["open source AI", "#rustlang"],"sort": "top","since": "2026-09-01","language": "en","maxItems": 200,"identifier": "you.bsky.social","appPassword": "xxxx-xxxx-xxxx-xxxx"}
Example: an account's posts plus its followers
{"handles": ["bsky.app"],"postUrls": ["https://bsky.app/profile/bsky.app/followers"],"maxItems": 500,"includeReposts": false}
Example: full reply thread of a post
{"postUrls": ["https://bsky.app/profile/cee.wtf/post/3muplmkx56s2k"],"threadDepth": 10,"maxItems": 2000}
Example: profiles for a list of handles
{"mode": "profile","handles": ["bsky.app", "jay.bsky.team", "did:plc:z72i7hdynmk6r22z27h6tvur"]}
Output
Every record has a kind discriminator (post, reply, profile, follower, follow), a query field naming the input that produced it, and scraped_at. Records are deduplicated by post URI or account DID across the whole run.
Post and reply records
{"kind": "post","uri": "at://did:plc:xb2urvqt5f4zzccjs46hysbf/app.bsky.feed.post/3muplmkx56s2k","cid": "bafyreidu2rxt55wzm3wmadbp6fzfrik6idvmh34qk23gwsssx6fqdgxbqm","id": "3muplmkx56s2k","url": "https://bsky.app/profile/cee.wtf/post/3muplmkx56s2k","text": "throng.cee.wtf i've invented a new way to browse bluesky","created_at": "2026-09-04T18:25:36.591Z","indexed_at": "2026-09-04T18:26:09.958Z","langs": ["en"],"author_did": "did:plc:xb2urvqt5f4zzccjs46hysbf","author_handle": "cee.wtf","author_display_name": "cee","author_avatar": "https://cdn.bsky.app/img/avatar/plain/...","author_verified": false,"author_url": "https://bsky.app/profile/cee.wtf","like_count": 7838,"repost_count": 1856,"reply_count": 339,"quote_count": 622,"bookmark_count": 1492,"is_reply": false,"reply_parent_uri": null,"reply_root_uri": null,"is_repost": false,"reposted_by_did": null,"reposted_by_handle": null,"is_pinned": false,"links": ["https://throng.cee.wtf"],"mentions": [],"tags": [],"labels": [],"embed_type": "video","images": [],"video": {"playlist": "https://video.bsky.app/watch/.../playlist.m3u8","thumbnail": "https://video.bsky.app/watch/.../thumbnail.jpg","alt": "","width": 1874,"height": 1298},"external": null,"quoted_post": null,"query": "https://bsky.app/profile/cee.wtf/post/3muplmkx56s2k","scraped_at": "2026-09-07T17:38:52+00:00"}
Field notes:
embed_typeis one ofimages,video,external(link card),record(quote post),recordWithMedia(quote + media),gallery, ornull.imagesis a list of{thumb, fullsize, alt, width, height}.externalis{uri, title, description, thumb}.quoted_postcarries the quoted post'suri,url, author,text,created_atand its own engagement counts, or{"uri": ..., "unavailable": "viewNotFound" | "viewBlocked" | "viewDetached"}when it cannot be shown.links,mentions(DIDs) andtagsare parsed from the post's rich-text facets, so links are the real targets rather than truncated display text.is_repost/reposted_by_handleare set onauthorFeedentries the account reposted; the record itself is the original post by its original author.- Reply records from
threadaddsource_post_uri,source_post_url,source_post_author_handleanddepth(1 = direct reply to the post). The root post is included askind: "post"withdepth: 0. labelsare moderation labels applied to the post (for example!no-unauthenticatedon the author).
Profile, follower and follow records
{"kind": "profile","did": "did:plc:z72i7hdynmk6r22z27h6tvur","handle": "bsky.app","display_name": "Bluesky","description": "official Bluesky account ...","avatar": "https://cdn.bsky.app/img/avatar/plain/...","banner": "https://cdn.bsky.app/img/banner/plain/...","url": "https://bsky.app/profile/bsky.app","followers_count": 34817452,"follows_count": 14,"posts_count": 827,"created_at": "2023-04-12T04:53:57.057Z","indexed_at": "2025-10-27T21:05:26.152Z","verified": true,"is_labeler": false,"lists_count": 17,"feedgens_count": 7,"starter_packs_count": 14,"pinned_post_uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l","labels": [],"query": "bsky.app","scraped_at": "2026-09-07T17:38:50+00:00"}
follower and follow records share this shape and add subject_did, subject_handle and subject_display_name (the account whose graph you asked for). Note that the Bluesky graph endpoints return the compact profile view, so followers_count, follows_count, posts_count, banner and the *_count association fields are null on those records; run profile mode on the DIDs if you need the counts.
How it works
The Actor calls the unauthenticated public AppView (public.api.bsky.app) endpoints defined by the AT Protocol lexicons: app.bsky.feed.searchPosts, app.bsky.feed.getAuthorFeed, app.bsky.actor.getProfiles, app.bsky.feed.getPostThread, app.bsky.graph.getFollowers, app.bsky.graph.getFollows, app.bsky.actor.searchActors, and com.atproto.identity.resolveHandle to turn a handle in a post URL into the DID an at:// URI needs. Pages of up to 100 items are walked with the server cursor until maxItems is reached or the feed ends. Between pages the Actor pauses briefly to stay far below Bluesky's published limit of 3,000 requests per five minutes per IP, and it backs off on 429.
Because everything is a JSON API call, one run of 1,000 posts typically finishes in well under a minute on 256 MB of memory.
Zero results and failures
The Actor distinguishes between "Bluesky answered and there was nothing" and "Bluesky could not be reached":
- A keyword with no matches, an account with no posts, or a deleted post produce an empty result for that input and the run still succeeds. The status message says so.
- A
searchPostsinput withoutidentifier/appPasswordis reported as unreachable with an explanation; if it was the only thing you asked for, the run fails with that message rather than returning an empty dataset. - If an input is not a valid handle, DID or bsky.app URL it is skipped with a warning.
- If the AppView rejects or never answers every input (network outage, edge refusal), the run is marked failed so you are not billed for, and do not silently accept, an empty dataset.
Limitations
- Only public data is returned. Accounts that opted out of unauthenticated viewing (
!no-unauthenticated) show the label and may return no posts. searchPostsrequires your own app password (see above) and is served by Bluesky's search index, which is not exhaustive for very old posts; usesince/untilwindows for historical pulls. Bluesky rate-limits authenticated sessions per account as well as per IP.- Followers / follows are returned in the AppView's own order (most recent first). Very large graphs (millions) are cut by
maxItems. - Like lists, feeds generators and starter-pack contents are not scraped by this Actor.
- No sentiment or "content category" scoring is added; the output is the raw, complete data so you can run your own models on it.
Integrations
Use the Apify API or one of the Apify client libraries (Python, JavaScript) to run the Actor and read its dataset, or connect it to Zapier, Make, Google Sheets, Slack, Airbyte or a webhook. Schedules let you re-run a keyword pull hourly or daily to build a rolling archive.
Related Actors
Other social scrapers by Thirdwatch: Twitter/X, Reddit, TikTok, Instagram, Pinterest, YouTube.
Legal
This Actor only reads data that Bluesky serves publicly to anyone without an account, through the API the network was designed around. You are responsible for using the output in line with Bluesky's terms, applicable privacy law and the rights of the people whose posts you collect.
Use cases
- Marketers monitoring social presence and engagement
- Researchers building social-media datasets
- Teams tracking public figures and trends
Last verified: 2026-09
More scrapers at thirdwatch.dev.