# Bluesky Followers Scraper (`apt_marble/bluesky-followers-scraper`) Actor

Collect public followers of a Bluesky account with handles, DIDs, display names, bios and avatars.

- **URL**: https://apify.com/apt_marble/bluesky-followers-scraper.md
- **Developed by:** [Hamza](https://apify.com/apt_marble) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 result records

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 Followers Scraper

Collect public followers of a Bluesky account with handles, DIDs, display names, bios and avatars.

Use this actor when you need structured bluesky followers data that you can filter, export or join with your own records. It is a focused actor: it handles this task rather than mixing unrelated data in the same run.

### What you get

- Stable source identifiers for deduplication and joins.
- Structured results in the default dataset, ready to export as JSON, CSV, Excel or XML.
- Source links and an extraction timestamp on every record.
- A result cap to control run size. Paginated actors also have a page cap.
- Missing values remain null instead of being invented.

### Use cases

Public audience research, creator-network analysis and follower profile export.

For periodic research, schedule separate runs and compare their timestamps and IDs. The actor returns snapshots; it does not create a real-time stream or deliver alerts on its own.

### Example input

```json
{
  "actor": "https://bsky.app/profile/propublica.org",
  "maxItems": 100
}
```

The example uses concrete values that passed a live check on October 2, 2026. Different queries, accounts, dates or publications can produce fewer records or none.

### Input reference

| Field | Type | Required | Meaning |
| --- | --- | --- | --- |
| `actor` | string | Yes | Bluesky username (for example `propublica.org`) or a bsky.app profile link (for example `https://bsky.app/profile/propublica.org`). |
| `maxItems` | integer | No | Maximum followers to save (shown as "Maximum followers"). A cap is not a promise that this many followers exist. |
| `maxPages` | integer | No | Maximum source pages for paginated actors. Ignored by single-response actors. |

`maxItems` (Maximum followers) is a ceiling, not a guaranteed result count. A run stops when it reaches that cap, the page cap, the end of available results or an error. Single-response actors ignore `maxPages`. Results are deduplicated by `did` within the run, not across separate runs.

### Example output

One follower record, shown for its structure. Values change:

```json
{
  "handle": "chrisbellatina.bsky.social",
  "displayName": "Chris Bellatina",
  "profileUrl": "https://bsky.app/profile/chrisbellatina.bsky.social",
  "did": "did:plc:r5x2fedirwqtwuqrpzmc4l5q",
  "description": null,
  "avatar": null,
  "accountCreatedAt": "2026-10-05T19:33:11.556Z",
  "indexedAt": "2026-10-05T19:33:12.000Z",
  "scrapedAt": "2026-10-05T19:40:16.103Z"
}
```

### Output fields

| Field | Type | Meaning |
| --- | --- | --- |
| `handle` | string | Follower's Bluesky handle. |
| `displayName` | string or null | Follower's display name; null when not set. |
| `profileUrl` | string | Link to the follower's profile on bsky.app. |
| `did` | string | Follower's permanent Bluesky account ID. Used to remove duplicates within a run. |
| `description` | string or null | Follower's bio; null when empty. |
| `avatar` | string or null | Profile picture URL; null when not set. |
| `accountCreatedAt` | string or null | When the follower's account was created. |
| `indexedAt` | string or null | When Bluesky last indexed the profile. |
| `scrapedAt` | string | Extraction timestamp in UTC ISO 8601. |

If the username or link does not match a Bluesky profile, the run still finishes as Succeeded with no records and a clear "profile not found" message (run status and the RUN_SUMMARY record), with examples of valid input. Anything that is not a Bluesky handle or a bsky.app profile link is rejected with an explanation.

### Limits and data quality

Not a following-list actor. Follower list entries may omit profile counts, which are null. Live lists change while paginating; no guarantee of a complete snapshot. Personal data needs lawful handling.

Source availability, record order, rate limits and field coverage can change. A successful small test does not guarantee high-volume reliability or full historical coverage. Missing data is not proof that an event, post, person or listing does not exist. The actor fails on unexpected layouts or blocked responses rather than pretending that a block is a valid empty dataset. If a later page fails, a run can fail before saving its collected results.

### FAQ

#### Do I need an account or cookies?

No account or cookies are required for the supported public records. Private, deleted, restricted and paid-only data is outside the actor's scope.

#### Can I request more results than exist?

You can set the cap within the allowed range, but the actor only returns available matching records. Page caps and source limits still apply.

#### Does this monitor changes automatically?

No. Each run returns a snapshot. Use scheduled runs and your own comparison or notification workflow if you need monitoring.

#### Are missing fields estimated?

No. Missing fields stay null, or retain the documented empty array when no entries are returned. Engagement and price values are point-in-time source values, not predictions.

#### Can I use the data commercially?

Access to public records does not grant unlimited reuse rights. Check source terms, licenses, copyright and relevant privacy rules for your intended use. This actor is independent and is not endorsed by the named platform.

# Actor input Schema

## `actor` (type: `string`):

Bluesky handle (for example propublica.org) or a bsky.app profile link (for example https://bsky.app/profile/propublica.org).

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

Maximum number of followers to save. A cap is not a promise that this many followers exist.

## `maxPages` (type: `integer`):

Maximum source pages for paginated actors. Ignored by single-response actors.

## Actor input object example

```json
{
  "actor": "joycomes.bsky.social",
  "maxItems": 100,
  "maxPages": 20
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "actor": "joycomes.bsky.social"
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/bluesky-followers-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 = { "actor": "joycomes.bsky.social" }

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/bluesky-followers-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 '{
  "actor": "joycomes.bsky.social"
}' |
apify call apt_marble/bluesky-followers-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/bluesky-followers-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/I7ZlwcvOesNYD37Ub/builds/2RRhBzkjdCb2ymk9F/openapi.json
