Bluesky Posts Scraper — Search, Feeds & Threads avatar

Bluesky Posts Scraper — Search, Feeds & Threads

Pricing

from $5.00 / 1,000 public bluesky post scrapeds

Go to Apify Store
Bluesky Posts Scraper — Search, Feeds & Threads

Bluesky Posts Scraper — Search, Feeds & Threads

Bluesky Posts Scraper searches public posts, exports author feeds and threads, and returns clean engagement data for research from $0.005 per result.

Pricing

from $5.00 / 1,000 public bluesky post scrapeds

Rating

0.0

(0)

Developer

Khadin Akbar

Khadin Akbar

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

21 hours ago

Last modified

Share

Search public Bluesky posts, collect posts from public author feeds, or export a public post and its reply thread. Every result has the same analysis-ready shape: post text, stable AT URI, canonical URL, author identity, timestamps, engagement counts, links, hashtags, mentions, media URLs, and discovery metadata.

Use this Actor for social listening, brand and competitor monitoring, journalism, academic research, community discovery, link tracking, or Bluesky datasets for AI workflows. It needs no Bluesky login, cookies, app password, or user session. Results are available as JSON, CSV, Excel, XML, RSS, or through the Apify API and MCP integrations.

Pricing is $0.005 per validated post plus a $0.00005 start event. Apify platform usage is additional. Duplicate posts, filtered-out records, and invalid records are not charged as results. maxResults is a hard run-wide cap, so a value of 100 caps result-event charges at $0.50 plus the start event.

What it collects

The Actor supports three focused workflows:

  • Keyword search: submit phrases, hashtags, URLs, or Bluesky search syntax. Sort by latest or top results and optionally filter by time, language, author, mentioned account, linked domain, exact URL, or tags.
  • Author feeds: submit handles, DIDs, or bsky.app/profile/... URLs. Choose whether the feed includes replies, media posts, author threads, or video posts.
  • Posts and threads: submit a public post URL or AT URI. Return the root post alone or traverse public replies to a configurable depth.

It deliberately does not scrape private data, direct messages, login-only content, follower lists, or user credentials. For profile biography and account metadata rather than posts, use Bluesky Profile Details Scraper.

Output fields

Each dataset item is a validated post record with these field groups:

  • Identity: postUri, postUrl, cid
  • Content: text, languages, hashtags, mentions, links, mediaUrls, embedType
  • Author: authorDid, authorHandle, authorDisplayName, authorAvatar
  • Timing: createdAt, indexedAt, scrapedAt
  • Engagement: likeCount, repostCount, replyCount, quoteCount
  • Thread context: isReply, replyParentUri, replyRootUri, isRepost, repostedByHandle
  • Provenance: sourceType, sourceQuery, sourceUrl, provider

The stable postUri is the best deduplication key. Handles can change; DIDs and AT URIs are designed to remain stable. Counts are snapshots taken when the run executes.

Example result:

{
"recordType": "post",
"postUri": "at://did:plc:example/app.bsky.feed.post/3lxyz",
"postUrl": "https://bsky.app/profile/example.com/post/3lxyz",
"text": "A public Bluesky post about climate tech #energy",
"createdAt": "2026-07-15T11:00:00.000Z",
"authorDid": "did:plc:example",
"authorHandle": "example.com",
"likeCount": 42,
"repostCount": 8,
"replyCount": 5,
"quoteCount": 1,
"hashtags": ["#energy"],
"sourceType": "search",
"sourceQuery": "climate tech",
"provider": "bluesky-appview",
"scrapedAt": "2026-07-15T12:00:00.000Z"
}

Input examples

Search recent English posts with minimum engagement:

{
"queries": ["climate tech", "renewable energy"],
"sort": "latest",
"language": "en",
"minLikes": 10,
"maxResults": 100
}

Collect two public author feeds:

{
"handles": ["bsky.app", "apify.com"],
"authorFeedFilter": "posts_with_replies",
"maxResults": 50
}

Export a public conversation:

{
"postUrls": ["https://bsky.app/profile/example.com/post/3lxyz"],
"includeThreadReplies": true,
"threadDepth": 4,
"maxResults": 200
}

When every target field is empty, the Actor performs a small AI search so {} works as a health-check input. For production automation, always provide explicit targets.

API usage

Run the Actor from JavaScript with the official Apify client:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/bluesky-posts-scraper').call({
queries: ['open source AI'],
sort: 'latest',
maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python works the same way:

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("khadinakbar/bluesky-posts-scraper").call(run_input={
"handles": ["bsky.app"],
"maxResults": 50,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)

The default dataset contains posts. The default key-value store always receives OUTPUT and RUN_SUMMARY, including the terminal outcome, warnings, target counts, provider attempts, validation totals, and charged-event counts. Outcomes distinguish COMPLETE, PARTIAL, VALID_EMPTY, INVALID_INPUT, UPSTREAM_FAILED, and CONFIG_ERROR, making scheduled workflows easier to monitor accurately.

AI agents and MCP

Connect Apify to an MCP-compatible client and call this Actor as a focused Bluesky collection tool. A useful agent prompt is: “Search Bluesky for the latest 50 English posts about open-source AI, then summarize recurring product complaints using postUri as the citation key.” The compact, consistent record shape avoids making the model infer fields from raw protocol responses.

For recurring research, create an Apify Task with fixed input and let an agent trigger that task. Keep maxResults conservative, use engagement filters before downstream analysis, and retain sourceQuery or sourceUrl for traceability.

Reliability and data sources

Public Bluesky AppView endpoints are the primary source. The Actor uses bounded retries, respects rate-limit retry guidance, and switches between public AppView hosts when an endpoint is temporarily unavailable. Author feeds and direct posts can use a verified public-data provider fallback when native endpoints are exhausted; search remains native because the fallback does not expose equivalent search semantics. All providers are normalized and validated before a paid dataset write.

The Actor stops pagination on repeated cursors, deduplicates across every input target, persists progress during container migration, and stops accepting new work before the run timeout. A partial upstream failure is reported as PARTIAL when useful data was still returned, rather than being hidden as a complete run.

Responsible use

Collect only public data you are legally permitted to process. Follow Bluesky’s terms, applicable privacy and data-protection laws, intellectual-property rules, and any obligations that apply to your jurisdiction and use case. Do not use the Actor for harassment, surveillance, unlawful profiling, re-identification, or attempts to access non-public content. The Actor is an independent tool and is not affiliated with or endorsed by Bluesky Social PBC.

FAQ

Does this require a Bluesky account?
No. It collects public data without user credentials.

Why did a valid run return no items?
The search may have no matches, the post may no longer be public, or engagement filters may exclude all records. Check OUTPUT.outcome and RUN_SUMMARY; a successful empty collection is labeled VALID_EMPTY.

Are results returned in real time?
The Actor queries the current public index when run. latest favors recent search results, but Bluesky indexing and engagement counts can change after collection.

How are duplicates billed?
They are not. The Actor deduplicates by AT URI before the validated write-and-charge operation.

Can it collect an entire historical account archive?
It paginates the public author-feed endpoint until maxResults, the feed ends, a charge cap is reached, or the run approaches its timeout. Availability ultimately depends on the public upstream service.