# Bluesky Posts Scraper (`dbott23/bluesky-posts-scraper`) Actor

Scrape Bluesky posts by keyword or profile. Supports hashtags, quoted phrases, and @handle filters. Filter by date, sort latest or top, toggle replies/reposts. Uses the public AT Protocol API — no proxies or browser needed. Output ready for brand monitoring, research, and social analytics.

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

## Pricing

from $1.00 / 1,000 post scrapeds

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/platform/actors/running/actors-in-store#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 Posts Scraper

Export Bluesky posts by **keyword search** or **user profile** — no browser required. Get post text, author, engagement metrics, timestamps, and embedded media URLs in a clean JSON or CSV dataset. Works with the public AT Protocol API.

### What it does

- **Keyword search** — search Bluesky for any term and collect matching posts (requires Bluesky credentials for search)
- **Profile scraping** — scrape posts from any public Bluesky profile without credentials
- Filter by date range, include or exclude replies and reposts
- Returns structured data ready to export as JSON, CSV, or Excel

### Use cases

- **Social listening** — track mentions of your brand, product, or topic on Bluesky
- **Trend research** — collect posts around a hashtag or keyword for analysis
- **Competitor monitoring** — see what's being posted about competitors
- **Influencer research** — pull posts from specific Bluesky accounts
- **Sentiment analysis** — feed posts into NLP pipelines or AI models
- **Dataset building** — create Bluesky post datasets for research or fine-tuning

### Input

| Field | Type | Description |
|---|---|---|
| `searchQueries` | string\[] | Keywords to search (e.g. `["AI tools", "#buildinpublic"]`). Requires Bluesky credentials. |
| `profiles` | string\[] | Bluesky handles to scrape (e.g. `["jack.bsky.social"]`). Public — no credentials needed. |
| `maxPosts` | integer | Max posts to collect per query or profile (default: `100`). |
| `sortBy` | string | `latest` (default) or `top`. |
| `sinceDate` | string | Only collect posts after this date (ISO format: `"2025-01-01"`). |
| `includeReplies` | boolean | Include reply posts when scraping profiles (default: `false`). |
| `includeReposts` | boolean | Include reposts when scraping profiles (default: `false`). |
| `blueskyIdentifier` | string | Your Bluesky handle or email (required for keyword search). |
| `blueskyAppPassword` | string | Your Bluesky app password (required for keyword search). Create one at Settings → App Passwords. |

At least one of `searchQueries` or `profiles` must be provided.

> **Note:** Keyword search requires a Bluesky account. Profile scraping is public and does not require credentials.

### Output

Each result is one post:

```json
{
  "uri": "at://did:plc:abc123/app.bsky.feed.post/xyz789",
  "cid": "bafyreig...",
  "author_handle": "alice.bsky.social",
  "author_display_name": "Alice",
  "text": "Just shipped a new feature! #buildinpublic",
  "created_at": "2026-07-20T14:32:00Z",
  "like_count": 42,
  "repost_count": 11,
  "reply_count": 5,
  "is_reply": false,
  "is_repost": false,
  "embed_type": null,
  "embed_url": null,
  "query": "#buildinpublic",
  "post_url": "https://bsky.app/profile/alice.bsky.social/post/xyz789"
}
```

### Pricing

This actor uses **Pay per result** pricing:

- **$1.00 per 1,000 posts** scraped
- A run collecting 200 posts costs **~$0.20**

### Frequently asked questions

**Do I need a Bluesky account to use this?**
For keyword/hashtag search: yes, you need a Bluesky handle and app password. For profile scraping (collecting posts from a specific user), no credentials are needed — public profiles are accessible via the AT Protocol API.

**How do I create an app password?**
Log in to Bluesky → Settings → Privacy & Security → App Passwords → Add App Password. Use the generated password as `blueskyAppPassword`. Do not use your main account password.

**What's the maximum number of posts I can collect?**
Set `maxPosts` up to any number. In practice, Bluesky's search API paginates in batches of 100. Very high limits on keyword searches may be rate-limited — 500–1,000 posts per query is a reliable range.

**Can I filter posts by date?**
Yes. Set `sinceDate` to an ISO date string (e.g. `"2026-01-01"`) to only collect posts after that date.

***

### More from dbott23

| Actor | What it does |
|---|---|
| [App Store & Google Play Reviews Scraper](https://apify.com/dbott23/appstore-reviews-scraper) | Export iOS and Android app reviews by keyword or app ID |
| [Trustpilot Reviews Scraper](https://apify.com/dbott23/trustpilot-reviews-scraper) | Export Trustpilot reviews to CSV or JSON — no API key needed |
| [B2B Reviews Scraper](https://apify.com/dbott23/b2b-reviews-scraper) | Pull reviews from G2, Capterra, and Trustpilot in one run |
| [AI Brand Visibility Tracker](https://apify.com/dbott23/ai-brand-visibility-tracker) | Track how AI assistants mention your brand vs. competitors |
| [AI Citation Auditor](https://apify.com/dbott23/ai-citation-auditor) | Check if your website is cited by ChatGPT, Perplexity, and Gemini |
| [Reddit Posts Scraper](https://apify.com/dbott23/reddit-posts-scraper) | Scrape posts, comments, and user histories from any subreddit |
| [YouTube Comments Scraper](https://apify.com/dbott23/youtube-comments-scraper) | Export comments from any YouTube video — no proxies needed |
| [Google Maps Reviews Scraper](https://apify.com/dbott23/google-maps-reviews-scraper) | Extract reviews from any Google Maps business listing |

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords or phrases to search Bluesky posts for. Supports quoted phrases, from:handle, and hashtags.

## `profiles` (type: `array`):

Bluesky handles to scrape posts from (e.g. bsky.app or user.bsky.social). '@' prefix is optional.

## `maxPosts` (type: `integer`):

Maximum number of posts to fetch for each search query or profile.

## `sortBy` (type: `string`):

How to sort keyword search results. Ignored for profiles (always newest first).

## `sinceDate` (type: `string`):

Optional. Only include posts created on or after this date.

## `includeReplies` (type: `boolean`):

Include reply posts when scraping profiles.

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

Include reposts when scraping profiles.

## `blueskyIdentifier` (type: `string`):

Your Bluesky handle (e.g. yourname.bsky.social) or email. Required for keyword search. Profile scraping works without it.

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

An app password from Bluesky Settings → Privacy and Security → App Passwords. Never use your main account password.

## Actor input object example

```json
{
  "searchQueries": [
    "artificial intelligence"
  ],
  "maxPosts": 100,
  "sortBy": "latest",
  "includeReplies": false,
  "includeReposts": false
}
```

# Actor output Schema

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

All scraped posts with text, author, engagement metrics and dates.

# 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 = {
    "searchQueries": [
        "artificial intelligence"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dbott23/bluesky-posts-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 = { "searchQueries": ["artificial intelligence"] }

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Futm8sElGmMayKCZV/builds/nh8jQSk6Bwg996mbQ/openapi.json
