# Bluesky Scraper | Enterprise Grade (`fetch_cat/all-in-one-bluesky-scraper`) Actor

Export public Bluesky replies, nested conversation context, author details, timestamps, and engagement metrics from post URLs or AT URIs.

- **URL**: https://apify.com/fetch\_cat/all-in-one-bluesky-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.72 / 1,000 comment extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bluesky Comments Scraper

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`, and `cid`)
- 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

```json
{
  "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"
}
```

### Ready-to-run examples

Open a public example to inspect its input, run it, or reuse it as a task:

- [Export Replies from a Bluesky Post](https://apify.com/fetch_cat/all-in-one-bluesky-scraper/examples/export-bluesky-post-replies)

#### Export the first 20 comments

```json
{
  "postUrls": [
    "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"
  ],
  "maxCommentsPerPost": 20,
  "maxDepth": 100
}
```

#### Monitor several posts

```json
{
  "postUrls": [
    "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m",
    "at://did:plc:example/app.bsky.feed.post/3example"
  ],
  "maxCommentsPerPost": 100,
  "maxDepth": 20,
  "maxRunSeconds": 120
}
```

### 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.

### Output fields

| Group | Fields |
|---|---|
| Record identity | `kind`, `id`, `uri`, `cid`, `url` |
| Author | `authorHandle`, `authorDid`, `authorName`, `authorAvatar` |
| Content | `text`, `languages`, `createdAt`, `indexedAt` |
| Engagement | `replyCount`, `repostCount`, `likeCount`, `quoteCount` |
| Thread context | `replyParentUri`, `replyRootUri`, `commentDepth` |
| Source context | `sourcePostUri`, `sourcePostUrl`, `sourcePostAuthorHandle` |

Records can be downloaded from the Dataset tab as JSON, CSV, Excel, XML, or RSS, or consumed through the API.

### 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.

### Pricing

Pay per run start and per comment saved. Subscription tiers receive volume rates. See the [live Pricing tab](https://apify.com/fetch_cat/all-in-one-bluesky-scraper/pricing) for current prices before starting a large run.

You are not charged a comment event for a reply-free post. Set `maxCommentsPerPost` to control the maximum output and cost per source post.

### API usage

Replace `$APIFY_TOKEN` with an Apify API token stored securely in your environment.

#### cURL

```bash
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

```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

```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:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?tools=fetch_cat/all-in-one-bluesky-scraper"
```

Example MCP client configuration:

```json
{
  "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 `uri` or `id`.
- 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.

### FAQ

**Does it require a Bluesky account?**\
No. It exports public thread data without a Bluesky login.

**Can I process multiple posts?**\
Yes. Add multiple values to `postUrls`; limits apply to each source post.

**Are nested replies included?**\
Yes, up to `maxDepth` and `maxCommentsPerPost`.

**Can I use an AT URI instead of a web URL?**\
Yes. Both public `bsky.app` post URLs and valid post AT URIs are accepted.

**How do I export CSV or Excel?**\
Open the run Dataset tab and choose the preferred download format, or request a format from the dataset API.

**How do I control spend?**\
Use a low `maxCommentsPerPost` value first and review the live Pricing tab before scaling.

### Related Actors

#### More Bluesky scrapers

- [Bluesky Actor Search Scraper](https://apify.com/fetch_cat/bluesky-actor-search-scraper)
- [Bluesky Followers Scraper](https://apify.com/fetch_cat/bluesky-followers-scraper)
- [Bluesky Profile Feed Scraper](https://apify.com/fetch_cat/bluesky-profile-feed-scraper)

* [Tweet Scraper](https://apify.com/fetch_cat/tweet-scraper)
* [Instagram Comments Scraper](https://apify.com/fetch_cat/instagram-comments-scraper)
* [LinkedIn Post Comments Scraper](https://apify.com/fetch_cat/linkedin-post-comments-scraper)

### 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.

# Actor input Schema

## `postUrls` (type: `array`):

Public Bluesky post URLs or at:// post URIs.

## `maxCommentsPerPost` (type: `integer`):

Maximum number of public replies to save for each source post.

## `maxDepth` (type: `integer`):

Maximum nested reply depth requested from Bluesky.

## `maxRunSeconds` (type: `integer`):

Optional total run budget; the Actor reserves 30 seconds for saving progress.

## Actor input object example

```json
{
  "postUrls": [
    "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"
  ],
  "maxCommentsPerPost": 20,
  "maxDepth": 100,
  "maxRunSeconds": 300
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "postUrls": [
        "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/all-in-one-bluesky-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "postUrls": ["https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"] }

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/all-in-one-bluesky-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "postUrls": [
    "https://bsky.app/profile/petebuttigieg.bsky.social/post/3lhtdtw23m22m"
  ]
}' |
apify call fetch_cat/all-in-one-bluesky-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fetch_cat/all-in-one-bluesky-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AM0eXi0TpFgC7nVJy/builds/adFcAWiaf8ToidKor/openapi.json
