Bluesky Threads Scraper avatar

Bluesky Threads Scraper

Pricing

from $0.75 / 1,000 unique post delivereds

Go to Apify Store
Bluesky Threads Scraper

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

Inus Grobler

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Security

Limited permissions

Share

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

  1. In Users or posts, paste your targets, one per line. Try @bsky.app for a user feed or bsky.app/3l6oveex3ii2l for a conversation.
  2. Set Maximum posts. The default 10-post preview costs $0.00755, including the start fee.
  3. 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 runTotal 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

TargetResult
@bsky.app or bsky.appThe account’s own posts and replies
jayUser jay.bsky.social; use a full handle for other domains
A public profile link or user DIDThe user’s authored feed
bsky.app/3l6oveex3ii2lThat post’s available conversation
A full Bluesky post link or post AT-URIThat 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 controlDefaultPurpose
Include replies written by the userOnInclude the user's authored replies (includeUserReplies)
Include conversations for user postsOffAdd available discussions, including other authors (expandUserThreads)
From dateUnsetFirst date for authored user posts, inclusive (since)
Through dateUnsetLast 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 fieldDefaultPurpose
postAuthorUnsetAuthor context for bare post IDs
includeQuotestrueDiscover available quotes for supplied or expanded user posts
includeAncestorstrueInclude up to 80 available ancestors for each thread seed
maxQuotesPerInput25Source quote-entry allowance per input, shared across a user’s expanded posts
maxReplyDepth1000Requested descendant depth; actual source depth can be lower
maxRequests100All 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.

FieldsMeaning
uri, cid, postIdFull post identity, observed record version and short author-scoped key
url, authorDid, authorHandleSource link and available author identity
text, createdAt, observedAtSource text, posting time and collection time
parentUri, rootUri, quotedUriActual reply parent, conversation root and quoted post; null when absent
likeCount, replyCount, repostCount, quoteCountPublic engagement snapshots, where exposed
mediaUrls, linkUrls, hashtags, mentionDidsSource 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,type relationships using replies_to and quotes.
  • 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 ApifyClient
client = 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.