Bluesky Threads Scraper
Pricing
from $0.75 / 1,000 unique post delivereds
Bluesky Threads Scraper
Scrape Bluesky user posts, threads, replies and quotes from handles, profile links or post IDs. Export engagement counts, raw JSON/CSV and conversation graphs. No login.
Pricing
from $0.75 / 1,000 unique post delivereds
Rating
0.0
(0)
Developer
Inus Grobler
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Security
Limited permissionsShare
Collect public Bluesky user posts, reply threads and quote discussions without a Bluesky login. Paste handles, profile links, post links or author/post IDs into one list. Export raw posts with engagement snapshots and the parent/root relationships needed to reconstruct conversations.
Quick start
- In Users or posts, paste your targets, one per line. Try
@bsky.appfor a user feed orbsky.app/3l6oveex3ii2lfor a conversation. - Set Maximum posts. The default 10-post preview costs $0.00755, including the start fee.
- Click Start. Use the Output tab to view posts, compare engagement, inspect relationships or download JSON/CSV and graph files.
{"postUrls": ["@bsky.app", "bsky.app/3l6oveex3ii2l"],"maxPosts": 10}
Only the target list is required. The API key remains postUrls and accepts users as well as posts. Maximum posts is one global limit across all targets and discussion context. Overlapping post URIs are saved and charged once per run.
Pricing
$0.75 per 1,000 unique post rows delivered, plus $0.00005 per run. Platform usage, conversation graph JSON, relationship CSV and the coverage summary are included. No rental or separate page, request, retry, duplicate or graph fee.
| Delivered posts in one run | Total price |
|---|---|
| 10 | $0.00755 |
| 100 | $0.07505 |
| 1,000 | $0.75005 |
Authored posts, collected replies, ancestors and quote posts each count as one post when saved. A run with no saved posts has only the start fee. Saved posts remain chargeable if a run later fails or is aborted. The current Console price is authoritative.
Set the spending limit in Apify’s run options. The Actor reduces its output limit to what the remaining budget can buy: $0.05 permits 66 posts after the start fee. The summary reports maxTotalChargeUsd when this reduces output. Allow at least $0.0008 for the start plus one post. Requests rejected before creating a run incur no charge.
What you can collect
- User posts: cursor-paginated posts authored by selected users, with their replies included by default. Reposts are excluded.
- Conversations: supplied posts, available ancestors, nested replies and known unfinished reply branches.
- Quote discussions: one level of available quotes and their replies, with quote edges kept separate from reply relationships.
- Integration-ready data: stable post identities, timestamps, source links, public engagement counts, media/rich-text references and deduplicated JSON/CSV graph exports.
Brand/community teams can review responses around accounts and announcements. Researchers can retain discussion context and stable identities. Developers can load the raw posts and typed edges into their own databases and monitoring tools.
Supported targets
| Target | Result |
|---|---|
@bsky.app or bsky.app | The account’s own posts and replies |
jay | User jay.bsky.social; use a full handle for other domains |
| A public profile link or user DID | The user’s authored feed |
bsky.app/3l6oveex3ii2l | That post’s available conversation |
| A full Bluesky post link or post AT-URI | That post’s available conversation |
You can mix up to 100 targets. Prefix numeric-looking usernames with @ to disambiguate them from post IDs.
For a post ID, paste author/postId in the same target list, for example bsky.app/3l6oveex3ii2l. In JSON/API input you can also supply a bare key with postAuthor:
{"postUrls": ["3l6oveex3ii2l"],"postAuthor": "bsky.app","maxPosts": 10}
Post keys are scoped to an author’s repository. The Actor never guesses an author, and a CID alone is not a supported address. When postAuthor is set, unqualified targets are post keys; prefix usernames with @ to keep them user targets.
Optional settings
The form has only four optional controls, all for user targets. Leave the defaults for a first run. Direct post links automatically collect available conversations, including replies, ancestors and quotes.
| Form control | Default | Purpose |
|---|---|---|
| Include replies written by the user | On | Include the user's authored replies (includeUserReplies) |
| Include conversations for user posts | Off | Add available discussions, including other authors (expandUserThreads) |
| From date | Unset | First date for authored user posts, inclusive (since) |
| Through date | Unset | Last date for authored user posts, inclusive (until) |
Dates such as 2026-10-01 use UTC; an end date includes the entire day. ISO timestamps with timezones are also accepted. Date filters select user-feed posts, so direct conversations and optional discussion context may include posts outside the window. For example:
{"postUrls": ["@bsky.app"],"maxPosts": 100,"includeUserReplies": false,"since": "2026-10-01","until": "2026-11-04"}
Discussion expansion adds other authors’ posts to the global limit. Hidden quote-list entries count toward the discovery allowance but produce no saved row. Source collection stops at the request limit or after three minutes; already fetched valid records are retained. Repeated pages/cursors and bounded-buffer limits are reported explicitly.
JSON/API overrides
Existing integrations keep the same fields, types and defaults. Technical options stay out of the form; use the Input tab's JSON editor or the API when you need them.
| API field | Default | Purpose |
|---|---|---|
postAuthor | Unset | Author context for bare post IDs |
includeQuotes | true | Discover available quotes for supplied or expanded user posts |
includeAncestors | true | Include up to 80 available ancestors for each thread seed |
maxQuotesPerInput | 25 | Source quote-entry allowance per input, shared across a user’s expanded posts |
maxReplyDepth | 1000 | Requested descendant depth; actual source depth can be lower |
maxRequests | 100 | All source HTTP attempts, including lookups and retries |
Output and downloads
Every row is one unique source post in this run. Missing counters are omitted; real zero counts remain zero.
| Fields | Meaning |
|---|---|
uri, cid, postId | Full post identity, observed record version and short author-scoped key |
url, authorDid, authorHandle | Source link and available author identity |
text, createdAt, observedAt | Source text, posting time and collection time |
parentUri, rootUri, quotedUri | Actual reply parent, conversation root and quoted post; null when absent |
likeCount, replyCount, repostCount, quoteCount | Public engagement snapshots, where exposed |
mediaUrls, linkUrls, hashtags, mentionDids | Source media references and rich-text metadata |
The table offers Posts, Engagement and Relationships views with readable headings and clickable post links. Raw dataset JSON/CSV retains the full field set. The Output tab also links to:
- Conversation graph JSON: collected nodes, unresolved references and zero-based input membership.
- Reply and quote edges CSV:
from,to,typerelationships usingreplies_toandquotes. - Coverage summary: per-target outcomes, limits, errors and collection counts.
Here is an observed post, with text shortened for display. Counters and timestamps change between snapshots.
{"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l","cid": "bafyreicnt42y6vo6pfpvyro234ac4o6ijug6adwwrh7awflgrqlt4zibxq","postId": "3l6oveex3ii2l","url": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/post/3l6oveex3ii2l","authorDid": "did:plc:z72i7hdynmk6r22z27h6tvur","text": "👋 Bluesky is an open social network…","createdAt": "2024-10-17T07:06:51.491Z","observedAt": "2026-11-03T19:01:44.604Z","parentUri": null,"rootUri": null,"quotedUri": null,"languages": ["en"],"hashtags": [],"mentionDids": [],"linkUrls": [],"mediaUrls": [],"mediaAltTexts": [],"authorHandle": "bsky.app","authorDisplayName": "Bluesky","indexedAt": "2024-10-17T07:06:51.491Z","likeCount": 63754,"replyCount": 8711,"repostCount": 9552,"quoteCount": 723,"bookmarkCount": 276}
Python API example
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("thescrapelab/bluesky-threads-scraper").call(run_input={"postUrls": ["@bsky.app"],"maxPosts": 100,})if run is None:raise RuntimeError("Actor run failed")for post in client.dataset(run.default_dataset_id).iterate_items():print(post["postId"], post["text"], post["url"])store = client.key_value_store(run.default_key_value_store_id)graph = store.get_record("GRAPH")["value"]coverage = store.get_record("RUN_SUMMARY")["value"]
Coverage, troubleshooting and support
Fewer posts than requested? Source visibility, exhausted discovery or a request, time, buffer or spending limit can apply. Check the per-target reasons in the coverage summary. A mixed run preserves valid targets when another fails; zero valid posts produces an explicit failed run.
Are all replies and quotes guaranteed? No. The public API can hide branches, omit siblings or return fewer levels than requested. Counters are snapshots, not completeness percentages. Coverage is reported as partial, unknown or no_more_discoverable_branches; the last only means this crawl’s observed frontier ended. Missing records do not establish deletion.
What is excluded? Logged-out visibility preferences are honored. Quotes of replies or quotes of quotes need their own target links. Each run is an independent snapshot; keyword search, follower lists, private content and historical change monitoring are outside this Actor’s scope. Media files are referenced rather than downloaded.
Can I restart an old run? Start a new run for a fresh snapshot. Restarting a run with saved posts is refused before collection, preserving its output without duplicate post charges.
Need help? Open this Actor’s Issues tab with the run ID, a public example target and expected behavior. Do not include access tokens or private information.
Source references: Bluesky HTTP API, AT URI addressing, thread interface and visibility preferences.