# Bluesky Scraper — Search Posts, Profiles & Threads (`grilled_gorge/bluesky-scraper`) Actor

Unofficial Bluesky data tool for searching posts and exporting public profiles, author feeds, and complete threads. Not affiliated with Bluesky Social PBC.

- **URL**: https://apify.com/grilled\_gorge/bluesky-scraper.md
- **Developed by:** [Jonathan Willburry](https://apify.com/grilled_gorge) (community)
- **Categories:** Social media, News
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

### What does Bluesky Scraper do?

> **Unofficial and independent:** This Actor is not affiliated with, sponsored by, or endorsed by Bluesky Social PBC or the Bluesky service.

**Bluesky Scraper** searches public [Bluesky](https://bsky.app/) posts and exports structured posts, profiles, author feeds, and complete conversation threads. It uses official public AT Protocol APIs, requires no Bluesky login, and handles cursor pagination, handle resolution, thread traversal, and dataset formatting for you.

Run it manually, schedule recurring searches on Apify, call it through the API, or connect its dataset to Make, Zapier, Google Drive, webhooks, and other integrations.

### Why use Bluesky Scraper?

- Monitor public posts about a brand, product, industry, event, or research topic.
- Export profile statistics and original posts for selected handles.
- Collect a post together with its parent context and nested replies.
- Build research datasets with stable AT URIs, public URLs, timestamps, and engagement counts.
- Combine several search terms, profiles, and post URLs in one run.

### Ready-to-run examples

- [Monitor brand mentions on Bluesky](https://apify.com/grilled_gorge/bluesky-scraper/examples/monitor-brand-mentions-on-bluesky)
- [Scrape posts from a Bluesky profile](https://apify.com/grilled_gorge/bluesky-scraper/examples/scrape-bluesky-profile-posts)
- [Scrape all replies from a Bluesky thread](https://apify.com/grilled_gorge/bluesky-scraper/examples/scrape-bluesky-thread-replies)

Each example opens with a working configuration that you can copy and adjust.

### How to use Bluesky Scraper

1. Open the Actor and select **Try for free**.
2. Keep the default search or replace it with your own terms.
3. Choose whether search results should be ordered by latest or top.
4. Optionally add profile handles, DIDs, or public bsky.app post URLs.
5. Set the maximum number of results and start the run.
6. Open the Dataset tab to preview or export the collected records.

The result budget is shared fairly across all supplied searches, profiles, and post URLs so one source does not consume the entire run.

### Input

| Field            | Description                                                           |
| ---------------- | --------------------------------------------------------------------- |
| `searchQueries`  | Terms or phrases used to search public posts.                         |
| `sort`           | `latest` or `top` search ordering.                                    |
| `profileHandles` | Handles or DIDs whose profile and original posts should be collected. |
| `includeReplies` | Include the selected authors' replies in their feeds.                 |
| `postUrls`       | Public bsky.app post URLs to expand into threads.                     |
| `maxItems`       | Total dataset limit across every source, from 1 to 10,000.            |

Example thread and profile input:

```json
{
    "searchQueries": [],
    "sort": "latest",
    "profileHandles": ["bsky.app"],
    "includeReplies": false,
    "postUrls": ["https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l"],
    "maxItems": 20
}
```

### Output

The Actor saves flat `post` and `profile` records. This post example came from a live default run and was verified against the public Bluesky API:

```json
{
    "type": "post",
    "uri": "at://did:plc:xhrtfphu4gzqrztkpb3a63qf/app.bsky.feed.post/3mqvw7rjlpo2y",
    "url": "https://bsky.app/profile/babygoldie.bsky.social/post/3mqvw7rjlpo2y",
    "cid": "bafyreicdxflp2lnxtfixhp2trimh5bxoujq5skk6gvsfcutivp2wvihhfy",
    "authorHandle": "babygoldie.bsky.social",
    "authorDisplayName": "News by babygoldie",
    "authorDid": "did:plc:xhrtfphu4gzqrztkpb3a63qf",
    "text": "[5/5] the non-invasive diagnosis rate of gallbladder cancer has increased to 92%. Liu Yingbin said: \"After artificial intelligence penetrates into medicine, it has fundamentally changed the diagnosis and treatment model of malignant tumors. (CCTV Finance)",
    "createdAt": "2026-07-18T09:10:30.279580+00:00",
    "langs": ["en"],
    "likeCount": 0,
    "repostCount": 0,
    "replyCount": 0,
    "quoteCount": 0,
    "imageUrls": [],
    "externalUrl": null,
    "isReply": true,
    "parentUri": "at://did:plc:xhrtfphu4gzqrztkpb3a63qf/app.bsky.feed.post/3mqvw7qv3lo2c",
    "rootUri": "at://did:plc:xhrtfphu4gzqrztkpb3a63qf/app.bsky.feed.post/3mqvw7oxdyw2c",
    "query": "artificial intelligence",
    "scrapedAt": "2026-07-18T09:10:52.282Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data table

| Record             | Main fields                                                 |
| ------------------ | ----------------------------------------------------------- |
| Post identity      | `uri`, `cid`, `url`, `authorHandle`, `authorDid`            |
| Post content       | `text`, `createdAt`, `langs`, `imageUrls`, `externalUrl`    |
| Engagement         | `likeCount`, `repostCount`, `replyCount`, `quoteCount`      |
| Thread context     | `isReply`, `parentUri`, `rootUri`                           |
| Profile identity   | `did`, `handle`, `displayName`, `url`, `avatarUrl`          |
| Profile statistics | `followersCount`, `followsCount`, `postsCount`, `createdAt` |
| Provenance         | `query`, `scrapedAt`                                        |

Profile descriptions are retained for context, but email addresses and phone-number patterns are removed before storage.

### How much does it cost to scrape Bluesky?

The Actor uses lightweight public API requests and no paid proxies. Pricing is pay-per-event: one start event plus one result event for each saved post or profile. Check the Pricing tab before starting a run; `maxItems` directly limits the maximum number of result charges.

### Tips and advanced options

- Use focused phrases instead of broad single words for more relevant searches.
- Remove the default search query when you only want profiles or threads.
- Set `includeReplies` to false when you only need an author's original posts.
- Use DIDs when you need a stable identity that does not change with a handle.
- Large threads can contain many replies; use `maxItems` to keep output and cost bounded.

### FAQ, disclaimers, and support

#### Does this Actor need a Bluesky account?

No. It only reads public endpoints and does not request credentials.

#### Does profile mode include reposts?

No. The Actor filters author feeds to posts written by the selected profile. Use post search to discover reposted content separately.

#### How many posts can one search query return?

Bluesky's public search API currently rejects requests for follow-up result pages, so a single query returns roughly its first 100 posts. The Actor keeps everything it collected, logs a warning, and continues with the remaining sources. To gather more posts, add several narrower queries instead of one broad one.

#### What happens to deleted, blocked, or invalid posts?

Unavailable thread nodes are skipped. Invalid handles and URLs produce a warning while the remaining sources continue.

Bluesky content is user-generated and can be inaccurate, offensive, copyrighted, or later deleted. Collect and process it only where you have a lawful purpose, follow applicable privacy rules, and comply with Bluesky's terms and policies. For bugs, feature requests, or custom solutions, use the Actor's Issues tab.

# Actor input Schema

## `searchQueries` (type: `array`):

Terms or phrases to search across public Bluesky posts.

## `sort` (type: `string`):

Return the latest or top matching posts.

## `profileHandles` (type: `array`):

Bluesky handles or DIDs whose public profiles and posts should be returned.

## `includeReplies` (type: `boolean`):

Include replies when collecting posts from profile author feeds.

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

Public bsky.app post URLs whose parent posts and reply threads should be returned.

## `maxItems` (type: `integer`):

Maximum number of dataset items across all searches, profiles, feeds, and threads.

## Actor input object example

```json
{
  "searchQueries": [
    "artificial intelligence"
  ],
  "sort": "latest",
  "profileHandles": [],
  "includeReplies": false,
  "postUrls": [],
  "maxItems": 100
}
```

# Actor output Schema

## `dataset` (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 = {
    "searchQueries": [
        "artificial intelligence"
    ],
    "profileHandles": [],
    "postUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("grilled_gorge/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 = {
    "searchQueries": ["artificial intelligence"],
    "profileHandles": [],
    "postUrls": [],
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "artificial intelligence"
  ],
  "profileHandles": [],
  "postUrls": []
}' |
apify call grilled_gorge/bluesky-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=grilled_gorge/bluesky-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/QqRfYHCvJ6gzdc4th/builds/mzy65x0Pm1pihU0Rr/openapi.json
