# Bluesky Scraper - Posts, Profiles, Search (`slanlabs/bluesky-scraper`) Actor

Search Bluesky posts, pull author feeds, profiles, and threads via the official open AT Protocol API. No login. Agent-ready pay-per-event pricing.

- **URL**: https://apify.com/slanlabs/bluesky-scraper.md
- **Developed by:** [SlanLabs](https://apify.com/slanlabs) (community)
- **Categories:** Social media, AI
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 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.

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, Search

Search Bluesky posts, pull author feeds, full profiles and entire threads through the official, open AT Protocol API (api.bsky.app). No login, no app password, no scraping - Bluesky's public API is deliberately open, which makes this one of the most reliable social-data Actors you can run.

### Why Bluesky data

Bluesky is where a growing share of tech, science, journalism and policy conversation now happens first. Because the AT Protocol is open by design, you can finally monitor a social network without fighting anti-bot walls. Use it for brand monitoring, researcher tooling, trend detection, founder and VC watching, or feeding fresh social context into an LLM pipeline.

### What you get per result

Posts: `text`, `author` (handle + display name), `createdAt`, `likeCount`, `repostCount`, `replyCount`, `uri`, direct `postUrl`, language tags. Profiles: handle, display name, bio, follower/following/post counts, avatar, joined date. Threads: the full reply tree flattened into rows with parent links.

### Modes

- `search-posts` - full-text search across all of Bluesky, newest or top-ranked first, with language and date filters
- `author-feed` - every post (or just original posts, no replies/reposts) from one handle
- `profile` - a single handle's full public profile
- `thread` - a post URL in, the whole conversation out

### Inputs

| Field | Required | Description |
| --- | --- | --- |
| `mode` | yes | One of the four modes above |
| `query` | search-posts | Search terms, e.g. `"AI agents"` |
| `handle` | author-feed, profile | e.g. `bsky.app` |
| `postUrl` | thread | Full bsky.app post URL |
| `sort` | no | `latest` (default) or `top` for search |
| `since` / `until` | no | Date bounds (YYYY-MM-DD) |
| `lang` | no | ISO language filter, e.g. `en` |
| `maxResults` | no | Default 100, max 1000 |

### Example

```json
{ "mode": "search-posts", "query": "apify", "sort": "latest", "since": "2026-10-01", "lang": "en", "maxResults": 200 }
```

### FAQ

**Is this allowed?** Yes. The AT Protocol API is open and documented; no authentication is needed for public data, and no site scraping is involved.

**Do I need a Bluesky account?** No.

**How current is search?** Near real-time - new posts are searchable within seconds.

**What does it cost?** Pay-per-event: $2 per 1,000 results plus minimal compute. Only pay for rows returned.

**Can I monitor a topic continuously?** Yes - schedule runs and use `since` for incremental pulls; rows are dedupe-friendly via their AT `uri`.

**Can agents call it?** Yes - limited-permissions, pay-per-event, agent-ready.

### Pipeline patterns

**Topic monitoring.** Schedule `search-posts` with `sort=latest` and a rolling `since`; each post's AT Protocol `uri` is a stable dedupe key. Pipe new matches to Slack, email, or an LLM for relevance triage.

**Competitor and founder tracking.** `author-feed` on a list of handles gives you everything key people say publicly, without an account or a follow graph.

**Conversation capture.** When a post about your product takes off, run `thread` on its URL to archive the entire discussion for analysis.

**Language-targeted listening.** `lang` plus `since` makes per-language community monitoring cheap - useful for global launches.

### Field notes

Engagement counts (`likeCount`, `repostCount`, `replyCount`) are point-in-time snapshots at fetch; re-fetch the same `uri` later to track growth. `lang` values come from Bluesky's own language tagging and are reliable for major languages. Profiles include counts at fetch time - schedule `profile` runs to build follower-growth series. All timestamps are ISO 8601 UTC.

### More FAQ

**Does search cover all of Bluesky?** Yes - the official search index covers the whole public network, not a sample.

**Can I get images and video?** Post rows include the text and metadata; media embeds are referenced by the post URL. Text-first keeps rows clean for analysis.

**What about quote posts and replies?** They appear in search and feeds like any post; `thread` mode reconstructs reply structure.

**Is there a firehose?** The AT Protocol has one, but for monitoring jobs targeted search is far cheaper - you pay per result, not per gigabyte.

**Why did a handle return nothing?** The account may not exist, may have no posts matching your filters, or may have changed handles. Verify the handle on bsky.app.

**Deleted posts?** Gone from the API - capture early if a conversation matters.

### More official-API Actors from SlanLabs

- [App Store Reviews (Official Apple Feeds)](https://apify.com/slanlabs/app-store-reviews) - every public review for any iOS app, any country
- [App Store Top Charts (Official Apple Feeds)](https://apify.com/slanlabs/app-store-top-charts) - live top free, paid and grossing charts for apps, books, podcasts and music
- [SEC EDGAR Filings Search & Monitor](https://apify.com/slanlabs/sec-edgar-filings) - full-text search and company feeds from the SEC's official APIs
- [GDELT Global News Monitor](https://apify.com/slanlabs/gdelt-news-monitor) - worldwide news coverage in 65+ languages, updated every 15 minutes
- [Hacker News Search & Monitor](https://apify.com/slanlabs/hackernews-monitor) - every story and comment since 2006, plus the live front page
- [US Government Spending & Contracts (USASpending)](https://apify.com/slanlabs/usaspending-contracts) - federal contracts, grants and loans by keyword, agency, NAICS or recipient

# Actor input Schema

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

search-posts: full-text post search. author-feed: recent posts by one account. profile: profile cards for one or more handles. post-thread: a post and its replies. search-actors: find accounts.

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

For search-posts / search-actors. Supports plain text; combine with filters below.

## `handle` (type: `array`):

For author-feed (one handle) and profile (one or more). Example: \["nytimes.com", "bsky.app"]

## `postUrl` (type: `string`):

For post-thread: https://bsky.app/profile/<handle>/post/<id> or at:// URI.

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

search-posts only.

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

search-posts only: only posts after this time, e.g. 2026-10-01T00:00:00Z.

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

search-posts only: only posts before this time.

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

search-posts only: restrict to a language, e.g. en.

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

Stop after this many results.

## Actor input object example

```json
{
  "query": "artificial intelligence",
  "handle": [
    "bsky.app"
  ],
  "sort": "latest",
  "maxResults": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Bluesky posts/profiles dataset

## `summary` (type: `string`):

Run summary

# 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": "artificial intelligence",
    "handle": [
        "bsky.app"
    ]
};

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

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

```

## MCP server setup

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