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

\[💵 $0.35 / 1K] Export Bluesky/AT Protocol posts, profiles, followers, follows, and actor search results to clean CSV/JSON datasets for social listening, research, lead lists, analytics, and automation.

- **URL**: https://apify.com/webdata\_labs/bluesky-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** For creators, Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.25 / 1,000 results

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 Scraper - Posts, Profiles & Followers

**Export public Bluesky and AT Protocol data to clean Apify datasets - for social listening, research, lead discovery, dashboards, and automation.**

This Actor collects Bluesky **profiles, author feeds, followers, follows, actor search results, and authenticated post-search results**. It is built for users who want structured CSV/JSON output they can plug into spreadsheets, BI tools, APIs, and workflows - not deeply nested raw AT Protocol objects.

### ✅ What you get / ❌ what this isn't

| ✅ This Actor gives you | ❌ This Actor is not |
|---|---|
| Clean, typed dataset rows (CSV/JSON ready) | Not deeply nested raw AT Protocol objects |
| Posts, profiles, followers, follows, search | Not private, deleted, or login-only content |
| Public modes work with no Bluesky login | Not a tool that needs browser, cookies, or proxy setup |
| Separate dataset views per row type | Not a single firehose you have to untangle |

### 🔎 Why use this Actor

- Clean dataset rows instead of deeply nested raw AT Protocol objects.
- Separate Apify dataset views for `Overview`, `Posts`, `Profiles`, and `Relationships`.
- Public-data modes work without a Bluesky login.
- Most modes need no login; post search uses a Bluesky app password (the only authenticated mode).
- Output is designed for CSV/JSON export, dashboards, scheduled runs, and downstream APIs.
- Transparent limits and auth behavior, with no browser, cookies, or proxy setup required.

### 📊 What you can extract

| Mode | What it returns | Authentication |
|---|---|---|
| `actorSearch` | Bluesky profiles matching a keyword | Not required |
| `profiles` | Profile details for one or more handles/DIDs | Not required |
| `authorFeed` | Recent posts from one or more public accounts | Not required |
| `followers` | Followers of one or more public accounts | Not required |
| `follows` | Accounts followed by one or more public accounts | Not required |
| `searchPosts` | Public posts matching a keyword or phrase | Bluesky app password required |

The default mode is `authorFeed`, so a run with default input works immediately without any login. Post search requires a Bluesky app password because Bluesky's post-search endpoint requires authentication. Use a Bluesky **app password**, not your main account password.

### 👥 Who it's for

Researchers, social listeners, and growth teams working with public Bluesky data. Common jobs:

- Monitor Bluesky posts mentioning a brand, product, topic, or hashtag.
- Export public Bluesky profiles for research or lead discovery.
- Build follower/following lists around customers, competitors, creators, or communities.
- Collect recent posts from a list of public accounts.
- Feed Bluesky data into Google Sheets, Airtable, Make, Zapier, Slack, BI tools, or your own database.
- Build research datasets from public AT Protocol data.

### ⚙️ How to scrape Bluesky data

1. Open the Actor on Apify.
2. Pick a `mode` (`actorSearch`, `profiles`, `authorFeed`, `followers`, `follows`, or `searchPosts`).
3. Enter the `query` or `actors` (handles/DIDs) the mode needs.
4. For `searchPosts` only, add your `identifier` and `appPassword` (required for that mode).
5. Set `maxResults` (defaults to 100; `0` for unlimited).
6. Click **Start**, then download CSV/JSON/Excel or pull from the Apify API.

### 📥 Input examples

#### Search profiles

```json
{ "mode": "actorSearch", "query": "data science", "maxResults": 100 }
```

#### Get profiles

```json
{ "mode": "profiles", "actors": ["bsky.app", "jay.bsky.team"] }
```

#### Get recent posts from an account

```json
{ "mode": "authorFeed", "actors": ["bsky.app"], "maxResults": 100 }
```

#### Get followers

```json
{ "mode": "followers", "actors": ["bsky.app"], "maxResults": 500 }
```

#### Get accounts a user follows

```json
{ "mode": "follows", "actors": ["bsky.app"], "maxResults": 500 }
```

#### Search posts

```json
{
  "mode": "searchPosts",
  "query": "AI agents",
  "maxResults": 100,
  "sort": "latest",
  "identifier": "your-handle.bsky.social",
  "appPassword": "your-app-password"
}
```

### 📤 Output

Rows are pushed to the default Apify dataset as structured JSON records. Export as CSV, JSON, Excel, XML, RSS, or HTML.

| Type | Handle / Author | Text or Description | Engagement |
|---|---|---|---|
| `post` | `example.bsky.social` | `We are testing a new data workflow...` | 250 likes, 34 reposts |
| `profile` | `bsky.app` | `Official Bluesky account` | follower/follow/post counts |
| `follower` | `example.bsky.social` | `Follower of bsky.app` | profile metrics |

#### Dataset views

| View | Best for |
|---|---|
| `Overview` | Quick scan across all row types |
| `Posts` | Post text, author, URL, timestamps, and engagement counts |
| `Profiles` | Handles, display names, bios, avatars, and profile metrics |
| `Relationships` | Followers/follows rows with source and target accounts |

#### Sample post row

```json
{
  "recordType": "post",
  "uri": "at://did:plc:example/app.bsky.feed.post/3abc123",
  "url": "https://bsky.app/profile/did:plc:example/post/3abc123",
  "authorHandle": "example.bsky.social",
  "authorDisplayName": "Example Account",
  "text": "We are testing a new data workflow with Bluesky public posts.",
  "langs": ["en"],
  "createdAt": "2026-06-20T12:00:00.000Z",
  "replyCount": 12,
  "repostCount": 34,
  "likeCount": 250,
  "quoteCount": 4,
  "searchQuery": "AI agents"
}
```

#### Sample profile row

```json
{
  "recordType": "profile",
  "did": "did:plc:example",
  "handle": "example.bsky.social",
  "displayName": "Example Account",
  "description": "Public profile bio text.",
  "followersCount": 12000,
  "followsCount": 320,
  "postsCount": 1800
}
```

For debugging or advanced use, enable `includeRaw` to include the original Bluesky API object in each row.

### 🔑 Authentication notes

Most modes use public Bluesky AppView endpoints and do not need credentials. Only `searchPosts` requires authentication:

- `identifier`: your Bluesky handle or email
- `appPassword`: a Bluesky app password

Create an app password in Bluesky under `Settings -> Privacy and security -> App passwords`. You can revoke app passwords at any time.

### 💵 How much does it cost?

This Actor is priced per exported dataset row. You pay only for results plus Apify platform usage. `maxResults` defaults to 100 to keep the first run cheap and fast; set it higher for bigger exports, or `0` for unlimited (the run pages until Bluesky has no more results). Unlimited runs can be large and long-running on high-volume queries.

### 🔁 Run it on the Apify platform

Schedule recurring monitoring, call it from the Apify API, export to CSV/JSON/Excel/RSS, or pipe results into Make, Zapier, Slack, BI tools, or your own database.

### ⚠️ Limits and caveats

- This Actor only returns public Bluesky data.
- It does not access private, deleted, or login-only user content.
- Result availability depends on Bluesky/AT Protocol public API behavior.
- Unlimited runs can be large and long-running; set a number for a predictable cap.
- Respect Bluesky terms, user privacy, and downstream data rules.

### 🧩 Related Actors

- [Threads Scraper](https://apify.com/webdata_labs/threads-scraper) - posts, profiles and search on Meta's text network.
- [LinkedIn Ads Library Scraper](https://apify.com/webdata_labs/linkedin-ads-library-scraper) - the B2B side of the same question: who is advertising what to whom.
- [TikTok Comments Scraper](https://apify.com/webdata_labs/tiktok-comments-scraper) - the comment thread under any video, with authors and engagement.
- [Google Maps No Social Media Leads](https://apify.com/webdata_labs/google-maps-no-social-media-leads) - places with no Instagram or Facebook presence to sell into.
- [Pinterest Trends Scraper](https://apify.com/webdata_labs/pinterest-trends-scraper) - keyword demand and save counts, the planning end of the funnel.

### ❓ FAQ

**Do I need a Bluesky login?** No for profiles, feeds, followers, follows, and actor search. Post search needs a Bluesky app password.

**Is this a Bluesky API?** It is an Apify Actor that turns public Bluesky/AT Protocol data into structured, API-accessible datasets.

**Does it collect private data?** No. Public data only; it does not access private, deleted, or login-only content.

### 🛠️ Support

If a run fails or a field is missing, open an Actor issue with the run URL, the input you used, and the field or behavior you expected.

### ⭐ Rate this Actor

If this Actor saved you time, please take 30 seconds to leave a review on the **Reviews** tab of [Bluesky Scraper - Posts, Profiles, Followers](https://apify.com/webdata_labs/bluesky-scraper) - reviews are the main trust signal other users see, and they directly decide which features get built next. If something is broken or a field is missing, please [open an issue](https://apify.com/webdata_labs/bluesky-scraper/issues) first - we typically respond within a day and would love the chance to fix it before you rate.

# Actor input Schema

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

What public Bluesky data to export. All modes work without login except searchPosts, which needs a Bluesky app password.

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

Search query for post search or actor search. Required for searchPosts and actorSearch.

## `actors` (type: `array`):

Bluesky handles or DIDs. Required for profiles, authorFeed, followers, and follows.

## `maxResults` (type: `integer`):

Maximum dataset rows to push. For multiple actors this is the total cap across all actors. Default 100. Set to 0 for unlimited - the run keeps paging until Bluesky has no more results.

## `since` (type: `string`):

Optional lower bound for post search, for example 2026-06-01T00:00:00Z.

## `until` (type: `string`):

Optional upper bound for post search, for example 2026-06-20T23:59:59Z.

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

Sort order for post search where supported by the Bluesky AppView.

## `includeRaw` (type: `boolean`):

Include raw Bluesky objects in dataset rows. Useful for debugging, but increases dataset size.

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

Optional Bluesky handle/email for authenticated endpoints. Currently required for searchPosts because Bluesky post search requires auth.

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

Optional Bluesky app password. Use an app password, not your main account password.

## `serviceUrl` (type: `string`):

Bluesky AppView service URL. The public AppView works for public data and does not require login.

## `authServiceUrl` (type: `string`):

Bluesky service URL used for login-only endpoints.

## `delayMs` (type: `integer`):

Polite delay between paginated API requests.

## Actor input object example

```json
{
  "mode": "authorFeed",
  "query": "AI agents",
  "actors": [
    "bsky.app"
  ],
  "maxResults": 100,
  "sort": "latest",
  "includeRaw": false,
  "serviceUrl": "https://public.api.bsky.app",
  "authServiceUrl": "https://bsky.social",
  "delayMs": 250
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset view with the most useful fields for quick inspection.

## `posts` (type: `string`):

Post-focused fields for searchPosts and authorFeed results.

## `profiles` (type: `string`):

Profile-focused fields for profiles, followers, follows, and actorSearch results.

## `relationships` (type: `string`):

Follower/follow relationship view.

# 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": "AI agents",
    "actors": [
        "bsky.app"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdata_labs/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": "AI agents",
    "actors": ["bsky.app"],
}

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

```

## MCP server setup

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