# Bluesky Scraper: Posts, Profiles, Feeds & Interactions (`autofacts/bluesky-scraper`) Actor

Scrape Bluesky posts, profiles, followers, feeds, threads, likes, reposts and authenticated search/hashtag results.

- **URL**: https://apify.com/autofacts/bluesky-scraper.md
- **Developed by:** [Proooxy](https://apify.com/autofacts) (community)
- **Categories:** Social media, AI, MCP servers
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 bluesky 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bluesky Scraper: Posts, Profiles, Feeds & Interactions

Scrape Bluesky public data through the AT Protocol XRPC APIs: posts, profiles, author feeds, followers, following, custom feeds, threads, likers and reposters, plus app-password search, hashtag results and authenticated account likes.

### 🎯 Features

| Feature | Description |
|---------|-------------|
| Multi-mode coverage | One Actor covers search, profile, posts, followers, following, feed, thread, likers, reposters, actorLikes and hashtag modes |
| Public API first | Most profile, feed, thread and interaction modes use `public.api.bsky.app` without credentials |
| Authenticated modes | Search, hashtag and actorLikes modes use a Bluesky app password |
| Interaction exports | Export post likers and reposters, which many competing Actors omit |
| Clean JSON | Posts and profiles are normalized for monitoring, BI and RAG pipelines |

### 🚀 Quick Start

```json
{
    "mode": "posts",
    "handles": ["bsky.app"],
    "maxItems": 100
}
```

Search requires an app password:

```json
{
    "mode": "search",
    "query": "open source AI",
    "language": "en",
    "identifier": "your-handle.bsky.social",
    "appPassword": "YOUR_APP_PASSWORD",
    "maxItems": 100
}
```

### 📋 Input

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | `search`, `profile`, `posts`, `followers`, `following`, `feed`, `thread`, `likers`, `reposters`, `actorLikes`, `hashtag` |
| `query` | string | Search text or hashtag text |
| `handles` | array | Handles for profile, posts, followers and following; for actorLikes, use the authenticated account handle or DID |
| `postUri` | string | AT URI for thread, likers and reposters |
| `feedUri` | string | AT URI for a custom feed |
| `dateFrom` | string | Earliest date for search/hashtag modes |
| `language` | string | Optional language filter for search |
| `identifier` | string | Bluesky handle/email for search, hashtag and actorLikes authentication |
| `appPassword` | secret string | Bluesky app password for search, hashtag and actorLikes; do not use your main password |
| `maxItems` | integer | Maximum saved items |

### 📤 Output

Post item:

```json
{
    "itemType": "post",
    "mode": "posts",
    "uri": "at://did:plc:.../app.bsky.feed.post/...",
    "author": { "handle": "bsky.app", "displayName": "Bluesky" },
    "text": "Example post text",
    "createdAt": "2026-06-11T00:00:00Z",
    "replyCount": 10,
    "repostCount": 20,
    "likeCount": 100,
    "url": "https://bsky.app/profile/bsky.app/post/..."
}
```

Profile item:

```json
{
    "itemType": "profile",
    "mode": "followers",
    "did": "did:plc:...",
    "handle": "alice.bsky.social",
    "displayName": "Alice",
    "followersCount": 1234,
    "url": "https://bsky.app/profile/alice.bsky.social"
}
```

### 🍳 Recipes

#### Brand monitoring

```json
{
    "mode": "search",
    "query": "\"my brand\"",
    "identifier": "your-handle.bsky.social",
    "appPassword": "YOUR_APP_PASSWORD",
    "maxItems": 500
}
```

#### Export a creator's audience

```json
{
    "mode": "followers",
    "handles": ["bsky.app"],
    "maxItems": 1000
}
```

#### Analyze who engaged with a post

```json
{
    "mode": "likers",
    "postUri": "at://did:plc:.../app.bsky.feed.post/...",
    "maxItems": 1000
}
```

#### Export your authenticated account likes

Bluesky only exposes `actorLikes` for the authenticated account. Use the same account handle in `handles` and `identifier`.

```json
{
    "mode": "actorLikes",
    "handles": ["your-handle.bsky.social"],
    "identifier": "your-handle.bsky.social",
    "appPassword": "YOUR_APP_PASSWORD",
    "maxItems": 500
}
```

### 💳 Pricing

Pay-per-event: **$0.001 per saved item**. A 1,000-item export costs **$1.00**.

### ❓ FAQ

**Do I need credentials?**

Only for `search`, `hashtag` and `actorLikes`. Create an app password in Bluesky settings and pass it as `appPassword`. Public profile/feed/thread/likers/reposters modes do not require credentials.

**How do I find a feed URI?**

Open a feed in Bluesky, copy its AT URI from developer tooling or API output, and pass it as `feedUri`. Feed URIs look like `at://did:plc:.../app.bsky.feed.generator/...`.

### ⚠️ Legal & Compliance

This Actor uses the open AT Protocol APIs and only reads public Bluesky data, plus likes from the account that authenticates with an app password. Use an app password rather than your main password.

***

### 🤖 Use with AI agents

This Actor is callable as a tool by any MCP-capable agent — Claude, Cursor, VS Code — or by your
own code, with no wrapper and nothing extra to deploy.

**Connect over MCP**

```
https://mcp.apify.com?tools=autofacts/bluesky-scraper
```

In a client that reads an `mcpServers` configuration block:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=autofacts/bluesky-scraper",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

The agent reads this Actor's parameters and their descriptions straight from the input
schema, and the hosted server infers the result field types from the dataset schema — so a
model knows what to send and what comes back before it ever calls anything.

**Or call the API directly**

```bash
curl -X POST "https://api.apify.com/v2/acts/autofacts~bluesky-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"query": "openai", "handles": ["bsky.app"]}'
```

The response body is the dataset records described above.

### 🧰 Other Actors by autofacts

Apify only auto-recommends Actors in the same category, so here are the ones that actually pair with this scraper:

| Actor | What it's for |
| :--- | :--- |
| [Instagram Scraper](https://apify.com/autofacts/instagram-scraper) | Instagram profiles, posts, Reels and comments, with no login |
| [TikTok Transcript API & Subtitle Scraper](https://apify.com/autofacts/tiktok-subtitle-transcript-scraper) | TikTok captions and transcripts |
| [YouTube Transcript Scraper API](https://apify.com/autofacts/youtube-subtitle-transcript-scraper) | Video captions as clean text |
| [Google Trends Trending Now](https://apify.com/autofacts/google-trends-trending-now) | What is trending on Google right now, in 125 countries, to set beside what people post |
| [Schema Markup Scraper & SEO Auditor](https://apify.com/autofacts/metadata-scraper) | JSON-LD, Open Graph and a 0-100 SEO audit of any URL |
| [HTML to PDF & URL to PDF API](https://apify.com/autofacts/universal-web-printer) | Turn any URL or HTML into PDF, PNG, JPEG or WebP |

All of them: [apify.com/autofacts](https://apify.com/autofacts)

# Actor input Schema

## `mode` (type: `string`):

What to scrape.

## `query` (type: `string`):

Search text for search mode, or hashtag text for hashtag mode. Hashtag mode automatically prefixes #.

## `handles` (type: `array`):

Bluesky handles for profile, posts, followers and following modes. For actorLikes, provide the authenticated account handle or DID.

## `postUri` (type: `string`):

AT URI for thread, likers or reposters mode, e.g. at://did:plc:.../app.bsky.feed.post/...

## `feedUri` (type: `string`):

AT URI for a custom feed, e.g. at://did:plc:.../app.bsky.feed.generator/...

## `dateFrom` (type: `string`):

Earliest post date for authenticated search/hashtag modes (YYYY-MM-DD).

## `language` (type: `string`):

Optional BCP-47 language filter for search, e.g. en.

## `depth` (type: `integer`):

Reply depth for thread mode.

## `identifier` (type: `string`):

Required for search, hashtag and actorLikes modes. Use your handle or email.

## `appPassword` (type: `string`):

Required for search, hashtag and actorLikes modes. Generate an app password in Bluesky settings; do not use your main password.

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

Maximum number of posts or profiles to extract and save. Each saved item is charged as one event.

## Actor input object example

```json
{
  "mode": "posts",
  "query": "openai",
  "handles": [
    "bsky.app"
  ],
  "depth": 6,
  "maxItems": 100
}
```

# Actor output Schema

## `overview` (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 = {
    "query": "openai",
    "handles": [
        "bsky.app"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("autofacts/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 = {
    "query": "openai",
    "handles": ["bsky.app"],
}

# Run the Actor and wait for it to finish
run = client.actor("autofacts/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 '{
  "query": "openai",
  "handles": [
    "bsky.app"
  ]
}' |
apify call autofacts/bluesky-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,autofacts/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/MA2YFrG1gBXWqg0zg/builds/Gi9ZMSJkYq45H97rk/openapi.json
