# Bluesky Scraper - Profiles, Posts, Followers & Search (`hospitable_easel/bluesky-account-scraper`) Actor

Scrape public Bluesky accounts with no login: profile stats, recent posts with engagement (likes/reposts/replies/quotes), and account discovery search.

- **URL**: https://apify.com/hospitable\_easel/bluesky-account-scraper.md
- **Developed by:** [aki ra](https://apify.com/hospitable_easel) (community)
- **Categories:** Social media, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 Scraper — Profiles, Posts, Followers & Account Search (No Login)

**Scrape public Bluesky data without an API key, app password, or login.** Get profile
stats, recent posts with full engagement metrics (likes, reposts, replies, quotes), and
discover accounts by search query. Export results to **JSON, CSV, or Excel** in one click.

> No authentication. No anti-bot challenges. No credentials to rotate. Just pass a list of
> handles (or a search term) and get clean, structured data.

### What you can scrape

- **Bluesky profile stats** — followers count, follows count, posts count, bio, display name, avatar, account created date
- **Recent posts** — text, timestamp, and per-post engagement (likes, reposts, replies, quotes, bookmarks), each with a direct `bsky.app` post URL
- **Followers & following lists** — export every follower of an account, or every account it follows (handle, display name, bio)
- **Account discovery / search** — find Bluesky accounts matching a query (handle, display name, or bio)

### Common use cases

- **Lead generation** — build lists of Bluesky accounts in a niche and pull their bio + reach
- **Competitor & brand monitoring** — track what specific accounts post and how it performs
- **Influencer research** — rank accounts by followers and engagement before outreach
- **Social listening** — watch a fixed set of accounts for new posts
- **AI / LLM datasets** — feed clean Bluesky text + engagement into your models or agents

### How to use it

1. Enter one or more Bluesky **handles** (without `@`), e.g. `bsky.app` — or a **search query** to discover accounts
2. Optionally set how many recent posts to fetch per account (0–1000)
3. Run the Actor and **download the results as JSON, CSV, or Excel**

At least one of `handles` or `searchQuery` is required.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `handles` | array | `["bsky.app"]` | Bluesky handles to scrape (without `@`) |
| `maxPostsPerAccount` | integer | `50` | Recent posts per handle (0–1000) |
| `includeProfile` | boolean | `true` | Emit one profile record per handle |
| `searchQuery` | string | — | Optional: find accounts matching this text |
| `searchLimit` | integer | `25` | Max accounts from the search query |
| `includeFollowers` | boolean | `false` | Also scrape each handle's followers |
| `includeFollows` | boolean | `false` | Also scrape the accounts each handle follows |
| `maxRelations` | integer | `100` | Cap on followers / follows fetched per handle |

### Output (dataset records)

Records are tagged by `type`: `profile`, `post`, `account_hit`, or `error`. Every dataset
can be exported to **JSON, CSV, Excel, XML, or HTML** from the Apify console or API.

Example post record:

```json
{
  "type": "post",
  "account": "bsky.app",
  "authorHandle": "bsky.app",
  "text": "This officially makes Bluesky the best-smelling social media platform",
  "createdAt": "2026-06-26T20:36:12.809Z",
  "likeCount": 104, "repostCount": 5, "replyCount": 3, "quoteCount": 1,
  "postUrl": "https://bsky.app/profile/bsky.app/post/3mp7sbnuyu22b"
}
````

### Why it stays fast and low-maintenance

All data comes from Bluesky's **public AppView XRPC API** (`public.api.bsky.app`) — an open,
documented REST API with **no authentication, no app password, and no anti-bot challenge**.
There are no credentials to rotate and the schema is stable, so the Actor rarely breaks
(unlike HTML scrapers that constantly fight anti-bot systems). It also paces requests politely
and retries on rate limits (HTTP 429) with backoff.

### Pricing

**Pay per result** — you only pay for the records you actually get. No monthly subscription.
See the live price on the Store page; a generous free tier lets you test before you commit.

### FAQ

**Do I need a Bluesky account, app password, or API key?**
No. This Actor only reads Bluesky's public data, so there is nothing to log in to.

**What output formats are supported?**
Any Apify dataset can be exported to JSON, CSV, Excel, XML, or HTML, or pulled via the API.

**Can it search posts by keyword across all of Bluesky?**
Not currently. Bluesky's full-text post search endpoint (`app.bsky.feed.searchPosts`) requires
authentication, so this Actor is intentionally **account-centric** to stay credential-free.
A logged-in keyword-search variant is a possible future add-on.

**How many posts can I get per account?**
Up to 1000 recent posts per handle (set with `maxPostsPerAccount`).

**Is it legal to scrape Bluesky?**
This Actor accesses only public data through Bluesky's official public API. You are responsible
for complying with Bluesky's terms and any applicable laws and privacy regulations in your use.

### Local development

The core client (`bluesky_client.py`) uses only the Python standard library:

```bash
python3 -c "from bluesky_client import scrape; print(list(scrape(['bsky.app'], max_posts_per_account=3)))"
```

The Actor wrapper (`src/`) additionally needs the `apify` SDK and the Apify CLI to run via
`apify run` and to publish via `apify push`.

# Actor input Schema

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

Bluesky handles to scrape (without @), e.g. bsky.app

## `maxPostsPerAccount` (type: `integer`):

How many recent posts to fetch per handle.

## `includeProfile` (type: `boolean`):

Also emit one profile record per handle (followers, posts count, bio).

## `searchQuery` (type: `string`):

Optionally find accounts matching this text (handle / display name / bio).

## `searchLimit` (type: `integer`):

How many accounts to return for the search query.

## `includeFollowers` (type: `boolean`):

Also scrape each handle's followers (one record per follower).

## `includeFollows` (type: `boolean`):

Also scrape the accounts each handle follows (one record per account).

## `maxRelations` (type: `integer`):

Cap on followers and on follows fetched per handle.

## Actor input object example

```json
{
  "handles": [
    "bsky.app"
  ],
  "maxPostsPerAccount": 50,
  "includeProfile": true,
  "searchLimit": 25,
  "includeFollowers": false,
  "includeFollows": false,
  "maxRelations": 100
}
```

# 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 = {
    "handles": [
        "bsky.app"
    ]
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bluesky Scraper - Profiles, Posts, Followers & Search",
        "description": "Scrape public Bluesky accounts with no login: profile stats, recent posts with engagement (likes/reposts/replies/quotes), and account discovery search.",
        "version": "0.1",
        "x-build-id": "YNJbmXAKOt3EvIHFF"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/hospitable_easel~bluesky-account-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-hospitable_easel-bluesky-account-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/hospitable_easel~bluesky-account-scraper/runs": {
            "post": {
                "operationId": "runs-sync-hospitable_easel-bluesky-account-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/hospitable_easel~bluesky-account-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-hospitable_easel-bluesky-account-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "handles": {
                        "title": "Account handles",
                        "type": "array",
                        "description": "Bluesky handles to scrape (without @), e.g. bsky.app",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxPostsPerAccount": {
                        "title": "Max posts per account",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "How many recent posts to fetch per handle.",
                        "default": 50
                    },
                    "includeProfile": {
                        "title": "Include profile stats",
                        "type": "boolean",
                        "description": "Also emit one profile record per handle (followers, posts count, bio).",
                        "default": true
                    },
                    "searchQuery": {
                        "title": "Account search query (optional)",
                        "type": "string",
                        "description": "Optionally find accounts matching this text (handle / display name / bio)."
                    },
                    "searchLimit": {
                        "title": "Max accounts from search",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "How many accounts to return for the search query.",
                        "default": 25
                    },
                    "includeFollowers": {
                        "title": "Include followers list",
                        "type": "boolean",
                        "description": "Also scrape each handle's followers (one record per follower).",
                        "default": false
                    },
                    "includeFollows": {
                        "title": "Include following list",
                        "type": "boolean",
                        "description": "Also scrape the accounts each handle follows (one record per account).",
                        "default": false
                    },
                    "maxRelations": {
                        "title": "Max followers/follows per account",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Cap on followers and on follows fetched per handle.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
