# Bluesky Scraper: Posts, Profiles, Followers & Likers (No Login) (`spriggs-data/bluesky-scraper`) Actor

Scrape Bluesky without login or API keys: search posts by keyword/hashtag/date, user posts, profiles, followers & following, post replies, likers, reposters, quotes, starter pack and list members, custom feeds. Bio email/website extraction for leads. JSON, CSV, Excel.

- **URL**: https://apify.com/spriggs-data/bluesky-scraper.md
- **Developed by:** [Thomas Spriggs](https://apify.com/spriggs-data) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 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?

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, Followers, Likers & Starter Packs (No Login)

**Scrape Bluesky (bsky.app) data in minutes, with no account, cookies or API key.** One Actor covers 13 modes: **search posts** by keyword, hashtag or phrase (with date, language, author, mention and domain filters), **user posts**, **profiles**, **followers and following lists**, **post replies (comments)**, **likers**, **reposters**, **quote posts**, **starter pack members**, **list members** and **custom feed posts**. Export to JSON, CSV, Excel, or Google Sheets, or push to Make, Zapier, n8n, your AI agent or an API.

It uses Bluesky's official public AT Protocol API, so it's fast, stable and cheap. There's no headless browser to break, and no login is needed for anything except deep post search.

### What can this Bluesky scraper do?

| Mode | Input | You get |
|---|---|---|
| Search posts | keywords, `#hashtags`, `"exact phrase"` | Posts with text, author, likes, reposts, replies, quotes, hashtags, links, images, video, language, timestamps |
| Search users | keywords | Matching profiles (bio, avatar, optional follower counts, emails and websites) |
| Profiles | handles or profile URLs | Followers, following, post count, bio, join date, verification, labels |
| User posts | handles | A user's timeline (filters: no replies, with replies, media only, author threads, include reposts) |
| Followers / Following | handles | Full follower and following lists (up to every follower) |
| Post replies | post URLs | The whole comment thread with reply depth |
| Likers / Reposters | post URLs | Who engaged with a post, plus like timestamps |
| Quote posts | post URLs | Every quote post of a post |
| Starter pack members | `bsky.app/starter-pack/...` URLs | Everyone in a starter pack |
| List members | `bsky.app/profile/.../lists/...` URLs | Everyone on a curated list |
| Custom feed posts | `bsky.app/profile/.../feed/...` URLs | Posts currently in a feed (e.g. "What's Hot") |

**Built-in extras**

- **Lead mode:** pulls **emails and websites from bios** (`extractContacts`). Great for creator outreach and B2B prospecting on Bluesky.
- **Full profile stats for user lists** (`enrichProfiles`): adds follower, following and post counts to followers, likers and search results.
- **Brand and link monitoring:** the `domain` filter finds every post linking to your site, and `mentions` finds every post mentioning a handle.
- **Safe by default:** posts and accounts with Bluesky adult or graphic moderation labels are skipped (you can turn this off).
- **Predictable cost:** `maxItems` and Apify's "max cost per run" are both respected exactly.

### Why scrape Bluesky?

Bluesky has 40M+ registered users and is where many journalists, researchers, developers, artists and brands moved. Use the data for:

- **Social listening and sentiment analysis:** track keywords, hashtags, competitors and campaigns.
- **Lead generation and influencer discovery:** search users by niche, export followers of competitors, and get starter pack members with contacts.
- **Academic research and datasets:** collect posts by topic, date range and language for NLP or LLM training and evaluation.
- **Community and growth analytics:** see who likes, reposts and quotes your posts.
- **AI agents and RAG pipelines:** clean, flat JSON that's ready for LLMs.

### How to use it

1. Click **Try for free**.
2. Pick a **mode** (e.g. *Search posts*).
3. Enter search terms, handles or URLs (one per line).
4. Set **Max items** and click **Start**.
5. Download your data as JSON, CSV, Excel or HTML, or connect it via API or integrations.

#### Example input

```json
{
  "mode": "searchPosts",
  "searchTerms": ["#tattoo", "\"flash sale\""],
  "lang": "en",
  "since": "2026-10-01",
  "maxItemsPerInput": 100
}
```

#### Example output (post reply)

```json
{
  "type": "post",
  "url": "https://bsky.app/profile/finnthepanther.com/post/3mxftsdjls22y",
  "text": "Thank you for the safe travels from the airport to SF and back this week 🤝",
  "createdAt": "2026-10-09T01:40:57.561Z",
  "authorHandle": "finnthepanther.com",
  "authorDisplayName": "Finn the Panther",
  "likeCount": 6,
  "repostCount": 0,
  "replyCount": 0,
  "quoteCount": 0,
  "hashtags": [],
  "links": [],
  "images": [],
  "isReply": true,
  "threadDepth": 1,
  "sourceInput": "https://bsky.app/profile/bart.gov/post/3mxfiggrtxs2q"
}
```

#### Example output (profile)

```json
{
  "type": "profile",
  "handle": "bsky.app",
  "displayName": "Bluesky",
  "followersCount": 35201461,
  "followsCount": 15,
  "postsCount": 866,
  "createdAt": "2023-04-12T04:53:57.057Z",
  "url": "https://bsky.app/profile/bsky.app",
  "emails": [
    "support@bsky.app"
  ],
  "websites": []
}
```

With `extractContacts` on, the `emails` and `websites` fields are filled from bio text such as "Bookings: studio@example.com · mystudio.com".

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

This Actor uses **pay-per-event** pricing: a tiny start fee plus a flat price per result (post, profile, follower, like, reply or member). You pay only for the data you get, and higher Apify plans get automatic discounts. With the free Apify plan's monthly credit you can scrape thousands of Bluesky posts or profiles at no cost. See the **Pricing** tab for current rates.

### Limits and tips

- **Logged-out post search returns about 100 results per search term.** This limit is enforced by Bluesky. To get more, split the search into several terms or date ranges (`since`/`until`), or add your own **Bluesky handle and App Password** (Settings → Privacy and security → App passwords) in the optional *Deep search* section. Never use your main password. The App Password is only used to read search results.
- Every other mode (followers, likers, profiles, timelines and more) paginates fully without login.
- Rate limits are handled automatically with backoff.

### Is it legal to scrape Bluesky?

This Actor only reads **public data** through Bluesky's **official public API**, the same API every Bluesky app uses. It never posts, likes, follows or messages anyone, and it follows the Bluesky Developer Guidelines (no spam or automated interactions). Your results may still contain personal data, which is protected by GDPR and other laws. Use it only for legitimate purposes, and consult a lawyer if unsure. Respect deletions: re-run instead of keeping stale copies of posts users have deleted.

### FAQ

**Do I need a Bluesky account?** No, except for the optional deep post search beyond about 100 results per term.

**Can I scrape all followers of an account?** Yes. Set `maxItemsPerInput` high enough (e.g. 100000).

**Can I get emails?** Only emails and websites that people publish in their bio (`extractContacts`). There is no hidden data.

**Can I schedule it?** Yes. Use Apify Schedules (e.g. hourly keyword monitoring) and get results by webhook, email, Slack or Google Sheets.

**Does it work with AI agents and MCP?** Yes. Call it from the Apify MCP server or API. The output is flat JSON.

**Found a bug or need a field?** Open an issue in the Issues tab. Fixes usually ship within 48 hours.

*Keywords: Bluesky scraper, bsky scraper, Bluesky API, Bluesky followers export, Bluesky posts scraper, Bluesky hashtag scraper, Bluesky starter pack scraper, AT Protocol scraper, Bluesky data export, Bluesky lead generation.*

# Actor input Schema

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

Choose the data you want. Search modes use 'Search terms'; user modes use 'Handles'; post/list/pack/feed modes use 'URLs'.

## `searchTerms` (type: `array`):

Keywords, "exact phrases", #hashtags, or Bluesky search syntax (e.g. from:handle, lang:en). Used by 'Search posts' and 'Search users'.

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

e.g. bsky.app, @nytimes.com or https://bsky.app/profile/jay.bsky.team. Used by Profiles, User posts, Followers, Following.

## `urls` (type: `array`):

bsky.app URLs or at:// URIs. Post URL for Replies/Likers/Reposters/Quotes; https://bsky.app/starter-pack/... for Starter pack; .../lists/... for List; .../feed/... for Custom feed.

## `maxItemsPerInput` (type: `integer`):

Upper limit of results for each input line.

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

Hard cap for the whole run (keeps cost predictable). 0 = no cap.

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

'latest' = newest first, 'top' = most popular posts. Used by 'Search posts'.

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

Only posts created on/after this date.

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

Only posts created before this date.

## `lang` (type: `string`):

e.g. en, es, ja.

## `author` (type: `string`):

Handle or DID.

## `mentions` (type: `string`):

Handle or DID.

## `domain` (type: `string`):

e.g. nytimes.com - great for brand/link monitoring.

## `postFilter` (type: `string`):

Which posts to include from each user's timeline. Used by 'User posts / timeline'.

## `includeReposts` (type: `boolean`):

Include posts the user reposted.

## `extractContacts` (type: `boolean`):

Adds 'emails' and 'websites' fields parsed from profile bios (profile-type results).

## `enrichProfiles` (type: `boolean`):

Search users, followers, following, likers, reposters and pack/list members return basic profiles. Turn on to add followersCount, followsCount, postsCount, banner (one extra API call per 25 users).

## `skipAdultContent` (type: `boolean`):

Drops posts/profiles carrying Bluesky moderation labels porn, sexual, nudity, graphic-media.

## `blueskyHandle` (type: `string`):

Only needed for 'Search posts' beyond ~100 results per term. Everything else works without login.

## `blueskyAppPassword` (type: `string`):

Create one in Bluesky: Settings > Privacy and security > App passwords. Never use your main password. Read-only use.

## Actor input object example

```json
{
  "mode": "searchPosts",
  "searchTerms": [
    "#tattoo"
  ],
  "maxItemsPerInput": 100,
  "maxItems": 1000,
  "sort": "latest",
  "postFilter": "posts_no_replies",
  "includeReposts": false,
  "extractContacts": false,
  "enrichProfiles": false,
  "skipAdultContent": true
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerms": [
        "#tattoo"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("spriggs-data/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 = { "searchTerms": ["#tattoo"] }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,spriggs-data/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/46jCQk73ifLIr7dql/builds/82KaeB6YoG75EGe1e/openapi.json
