# Bluesky Post Search Scraper (`apt_marble/bluesky-post-search-scraper`) Actor

Search public Bluesky posts with full text, author details, engagement, images, video and link previews. Automatic pagination with optional date filters.

- **URL**: https://apify.com/apt_marble/bluesky-post-search-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

from $0.40 / 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.
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 Post Search Scraper

Find public Bluesky posts by keyword and export their text, engagement, author information and media in a clean dataset. Search is cookieless. Images, videos, quoted posts and link previews are included whenever they are returned with the search results. There are no individual-post detail requests.

### What you get

- Post text, publication and indexing timestamps, languages and content labels.
- Likes, reposts, replies, quotes and bookmarks when available.
- Author handle, display name, avatar, account identifier and account creation date.
- Structured images with thumbnails, full-size URLs, alt text and aspect ratios.
- Available video playlists, thumbnails, captions, external previews and quoted-post content.
- Original content metadata including facets, mentions, hashtags, links, reply references and attachment metadata.
- Additional author and post information returned with search results, without an extra enrichment fee.

No media files are downloaded. Media metadata and links stay structured in JSON. CSV and Excel exports may represent these nested values as JSON strings. Missing fields are omitted, not guessed or filled with null placeholders. Zero engagement counts are kept.

### Start a search

1. Enter a **Search query**, such as `birds` or `technology`.
2. Choose **latest** or **top**.
3. Optionally enter **Since** and **Until** as **DD-MM-YYYY**, for example `07-10-2026`.
4. Set **Maximum results** and start the run.

The actor requests further search pages automatically until it reaches your result limit or available results end. No page-count input is needed. Results are deduplicated within each run. Old `maxPages` values are ignored.

```json
{
  "query": "birds",
  "sort": "latest",
  "since": "01-10-2026",
  "until": "07-10-2026",
  "maxItems": 250
}
```

### Inputs

| Input | Meaning |
| --- | --- |
| Search query | Keyword or search expression. |
| Sort | `latest` (default) or `top`. |
| Since (DD-MM-YYYY) | Optional first day, inclusive, in UTC. |
| Until (DD-MM-YYYY) | Optional last day, inclusive, in UTC. |
| Maximum results | Maximum unique posts to save. Default 100; allowed range 1 to 100,000. |

Dates are text fields to preserve day-month-year ordering. Leave either date blank to remove that bound. Impossible dates, a missing query, reversed date ranges and invalid limits end with a clear input message and no results. Try `birds`, `07-10-2026` and `100` as valid examples.

### Clean result fields

| Field | Contents |
| --- | --- |
| `text` | Full returned post text. |
| `createdAt`, `indexedAt`, `scrapedAt` | Publication, indexing and collection times. |
| `authorHandle`, `authorName`, `authorAvatar` | Readable author details. |
| `authorId`, `authorCreatedAt` | Stable author identifier and account creation date. |
| `likes`, `reposts`, `replies`, `quotes`, `bookmarks` | Returned engagement counts. |
| `languages`, `labels` | Language and moderation metadata. |
| `media` | Complete rendered media: image URLs, videos, external cards and quoted posts. |
| `contentDetails` | Other original content fields, including facets, attachments, reply references and record type. |
| `authorDetails` | Other author fields such as associated account information and author labels. |
| `postDetails` | Additional post fields not already included elsewhere. |
| `viewer`, `threadGate` | Viewer metadata and reply permissions, when available. |
| `postUri`, `contentId` | Unique post and content-version identifiers. |

The extra-information objects preserve new fields without creating duplicate raw-post columns. Original attachment metadata and rendered media are both retained because they contain different information. Post identifiers and media links are content, not internal request addresses. Internal retrieval URLs are not written to results, summaries or logs.

### Progress and run summary

Each accepted unique post is saved immediately. Short progress lines show results increasing page by page. The run summary reports saved posts, completed pages, request count, available-hit estimate when returned, result-limit status and a plain-language outcome.

An empty search is a successful run with an explanation. If a later page becomes unavailable or repeats its pagination cursor, already-saved results remain available and the run finishes successfully with a partial-result message. A service outage before any results, or a dataset/storage failure, is an infrastructure error and may fail the run.

### Limits

Maximum results is a ceiling, not a promise. Search indexing, visibility restrictions, pagination availability and rate limits can return fewer posts. Some queries allow a first page but restrict later pages; those runs retain their results and explain the partial outcome. The actor does not unlock private, deleted, restricted or paid-only content. No full-history or high-volume guarantee is made.

Only information returned with the search results is included. There are no profile-detail or individual-post lookups, invented metrics, private data or downloaded media files. Reuse must comply with applicable terms, copyright and privacy rules. This actor is independent and is not endorsed by Bluesky.

# Actor input Schema

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

Keyword or search expression.

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

latest or top

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

Optional first day, inclusive, in UTC. Enter DD-MM-YYYY, for example 07-10-2026. Leave blank for no date bound.

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

Optional last day, inclusive, in UTC. Enter DD-MM-YYYY, for example 07-10-2026. Leave blank for no date bound.

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

Maximum unique posts to save. Pagination is automatic until this limit or available results are exhausted.

## Actor input object example

```json
{
  "query": "Birds",
  "sort": "latest",
  "maxItems": 100
}
```

# 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 = {
    "query": "Birds"
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/bluesky-post-search-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": "Birds" }

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/bluesky-post-search-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/QvLY6TLEW0daH8Y1P/builds/0sBhT2XiQHPMmCRHn/openapi.json
