Export public replies from Bluesky post threads as structured JSON, CSV, Excel, or API-ready records. Monitor customer feedback, community response, campaign engagement, and public conversations without a Bluesky login.
Provide one or more public post URLs or AT URIs. The Actor follows the conversation tree, saves nested replies, preserves source-post context, and returns clean records ready for analysis.
What data can you export?
Each comment includes:
- Stable post identifiers (
id,uri, andcid) - Canonical comment and source-post URLs
- Author handle, DID, display name, and avatar
- Comment text and language tags
- Creation and indexing timestamps
- Reply, repost, like, and quote counts
- Parent and root reply references
- Conversation depth and source-post author
{
"kind": "comment",
"id": "3mk66abcxyz2q",
"uri": "at://did:plc:example/app.bsky.feed.post/3mk66abcxyz2q",
"cid": "bafyreiexample",
"url": "https://bsky.app/profile/reply-user.bsky.social/post/3mk66abcxyz2q",
"authorHandle": "reply-user.bsky.social",
"authorDid": "did:plc:example",
"authorName": "Reply User",
"authorAvatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:example/example@jpeg",
"text": "This is a useful write-up.",
"createdAt": "2026-04-23T14:02:11.000Z",
"indexedAt": "2026-04-23T14:02:12.000Z",
"languages": ["en"],
"replyCount": 1,
"repostCount": 0,
"likeCount": 7,
"quoteCount": 0,
"replyParentUri": "at://did:plc:2q2hs5o42jhbd23pp6lkiauh/app.bsky.feed.post/3lhtdtw23m22m",
"replyRootUri": "at://did:plc:2q2hs5o42jhbd23pp6lkiauh/app.bsky.feed.post/3lhtdtw23m22m",
"commentDepth": 1,
"sourcePostUri": "at://did:plc:2q2hs5o42jhbd23pp6lkiauh/app.bsky.feed.post/3lhtdtw23m22m",
"sourcePostUrl": "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m",
"sourcePostAuthorHandle": "404media.co"
}
Input settings
| Field | Type | Description |
|---|---|---|
postUrls |
string array | Public Bluesky post URLs or AT URIs. |
maxCommentsPerPost |
integer | Maximum replies saved per source post, from 1 to 1,000. |
maxDepth |
integer | Maximum nested reply depth requested. |
maxRunSeconds |
integer | Optional 35–300 second run budget. |
Use low limits while validating a new workflow, then increase the limit for scheduled production runs.
Who is it for?
- Social media teams tracking public reactions to posts and announcements
- Marketing analysts comparing engagement across campaigns
- Community managers finding recurring questions and feedback themes
- Researchers studying public conversation structures and reply networks
- Developers and data teams feeding Bluesky comments into dashboards, warehouses, or AI pipelines
Use cases
- Monitor replies to product announcements and campaigns.
- Analyze public feedback and conversation depth.
- Refresh engagement dashboards on an Apify schedule.
- Compare comment volume and sentiment across source posts.
- Archive public discussion context for reproducible research.
- Send new replies to a webhook, spreadsheet, CRM, or data warehouse.
API usage
Replace $APIFY_TOKEN with an Apify API token stored securely in your environment.
cURL
curl -X POST "https://api.apify.com/v2/acts/fetch_cat~all-in-one-bluesky-scraper/runs?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"postUrls":["https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"],"maxCommentsPerPost":20}'
JavaScript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/all-in-one-bluesky-scraper').call({
postUrls: ['https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m'],
maxCommentsPerPost: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
Python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('fetch_cat/all-in-one-bluesky-scraper').call(run_input={
'postUrls': ['https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m'],
'maxCommentsPerPost': 20,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
Use the same Actor from Apify schedules, webhooks, Make, Zapier, n8n, or any HTTP-capable application.
MCP and AI agents
Add the Apify MCP server to Claude Code:
claude mcp add apify --transport http "https://mcp.apify.com?tools=fetch_cat/all-in-one-bluesky-scraper"
Example MCP client configuration:
{
"mcpServers": {
"apify": {
"type": "http",
"url": "https://mcp.apify.com?tools=fetch_cat/all-in-one-bluesky-scraper"
}
}
}
Example prompts:
- “Export up to 50 replies from this public Bluesky post and summarize common questions.”
- “Collect comments from these three Bluesky post URLs and compare engagement.”
- “Return the authors and text of nested replies at depth two or greater.”
Tips
- Start with 20 comments to verify the selected post and output shape.
- Use canonical public post URLs copied from Bluesky when possible.
- Use AT URIs when another Bluesky integration already supplies them.
- Schedule recurring runs for engagement monitoring.
- Deduplicate downstream records by
uriorid. - Keep run limits aligned with the number and size of source threads.
Limits and expected behavior
- Only publicly available Bluesky threads can be exported.
- Deleted, blocked, moderated, or otherwise unavailable replies cannot be returned.
- Deeply nested threads are limited by
maxDepth,maxCommentsPerPost, and source availability. - A public post with no replies completes successfully with an empty dataset and run summary.
- Invalid or unavailable source posts are reported clearly rather than converted into fabricated rows.
- Counts reflect the values available when each reply is collected and may change later.
Support
Open an issue on the Actor page with the public post URL, expected result, and run ID. Do not include private credentials, tokens, or personal data that is not already public.