Bluesky Posts Scraper avatar

Bluesky Posts Scraper

Pricing

from $2.29 / 1,000 post scrapeds

Go to Apify Store
Bluesky Posts Scraper

Bluesky Posts Scraper

Search Bluesky for posts by keyword. Filter by sort order, date range, and language. Get post text, author, images, links, and engagement counts. Export JSON, CSV, Excel.

Pricing

from $2.29 / 1,000 post scrapeds

Rating

0.0

(0)

Developer

ParseBird

ParseBird

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Bluesky Posts Scraper

The Bluesky Posts Scraper searches Bluesky for posts matching one or more keywords and returns post text, author details, images, external links, and engagement counts — no login or API key required.

Search any keyword, sort by latest or top engagement, filter by date range and language, and get clean, structured post data ready for social listening, trend tracking, or research.

Copy to your AI assistant

Use the Apify Actor "parsebird/bluesky-posts-scraper" (Bluesky Posts Scraper) via the ApifyClient: client.actor("parsebird/bluesky-posts-scraper").call(run_input={"queries": ["bluesky", "decentralized social media"], "limit": 100, "sort": "latest", "lang": "en"}) — inputs are queries (array of keywords — required), limit (integer, max posts per query, default 5), sort ("latest" or "top", default "latest"), since / until (date or ISO 8601 timestamp), lang (language code, e.g. en, de), and proxyConfiguration (optional — Bluesky's public API has no bot protection); output items contain id, authorId, authorName, authorUsername, authorAvatar, text, images, link, primaryImage, createdAt, langs, replyCount, repostCount, likeCount, url, and searchTerm; full API spec at https://apify.com/parsebird/bluesky-posts-scraper/api and get an API token at https://console.apify.com/account/integrations.

What does the Bluesky Posts Scraper do?

Bluesky is the fastest-growing decentralized alternative to X/Twitter, built on the AT Protocol. The Bluesky Posts Scraper searches Bluesky's public post index the same way the in-app search does, and returns the results as structured data:

  • 🔍 Search by keyword or phrase — run multiple queries in a single job
  • 📊 Sort by latest (newest first) or top (most engagement)
  • 📅 Filter by date range with since and until
  • 🌐 Filter by post language (e.g. en, de, ja)
  • 🖼️ Extracts images, external link cards, and a convenience primaryImage for the post's lead visual
  • 💬 Returns like, repost, and reply counts alongside full author details (name, handle, DID, avatar)
  • ⚡ No login, API key, or proxy required — Bluesky's public search API is open

Input parameters

ParameterTypeRequiredDefaultDescription
queriesarrayYesKeywords or phrases to search for.
limitintegerNo5Maximum number of posts to scrape per query.
sortstringNolatestSorting order: latest or top.
sincestringNoOnly return posts created on or after this date.
untilstringNoOnly return posts created on or before this date.
langstringNoFilter posts by language code, e.g. en, de.
proxyConfigurationobjectNooffApify Proxy settings — optional, only useful under heavy rate limiting.
{
"queries": ["bluesky", "decentralized social media"],
"limit": 100,
"sort": "latest",
"lang": "en"
}

Output example

{
"id": "bafyreibqjfx2ejvxkd3okjtodoyqvoyk7wuberwonsakdjv4yahp2lrn4a",
"authorId": "did:plc:pc2aiklrpzwgsiq3fuohbui4",
"authorName": "Keri Warbis",
"authorUsername": "keriwarbis.bsky.social",
"authorAvatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:pc2aiklrpzwgsiq3fuohbui4/bafkreihgejbtckxrsgrba7ckx6mlsofe6nzvs4t2m54y2in6edcp65tlne@jpeg",
"text": "Bit sunburnt from yesterday's stint in the garden.\n\nBit hungover from Eurovision.\n\nAnother day of sun and entertaining ahead.\n\nSunday roast at The Grand will be happening to round of the day.",
"images": [
{
"thumb": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:pc2aiklrpzwgsiq3fuohbui4/bafkreiejc6jc4z47urksbwn7owoyyi4o46ufi362e52bscl4bsjrj4izyq@jpeg",
"fullsize": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:pc2aiklrpzwgsiq3fuohbui4/bafkreiejc6jc4z47urksbwn7owoyyi4o46ufi362e52bscl4bsjrj4izyq@jpeg",
"alt": "",
"aspectRatio": { "height": 820, "width": 828 }
}
],
"link": null,
"primaryImage": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:pc2aiklrpzwgsiq3fuohbui4/bafkreiejc6jc4z47urksbwn7owoyyi4o46ufi362e52bscl4bsjrj4izyq@jpeg",
"createdAt": "2024-05-12T08:36:29.345Z",
"langs": ["en"],
"replyCount": 0,
"repostCount": 0,
"likeCount": 0,
"url": "https://bsky.app/profile/keriwarbis.bsky.social/post/3kxkwdhu77o23",
"searchTerm": "bluesky"
}
FieldDescription
idThe post's record key (its unique ID within the author's repo)
authorIdThe author's DID (decentralized identifier)
authorName / authorUsernameThe author's display name and @handle
authorAvatarURL of the author's avatar image
textThe post's text content
imagesArray of attached images (thumb, fullsize, alt, aspectRatio)
linkURL of an attached external link card, if any
primaryImageA single representative image URL for the post (first image, or a link/video thumbnail)
createdAtWhen the post was created
langsLanguage codes the author tagged the post with
replyCount / repostCount / likeCountEngagement counts at scrape time
urlThe post's bsky.app URL
searchTermWhich of your input queries returned this post

Download results in JSON, CSV, Excel, HTML, or XML directly from the Apify Console, or pull them via the Dataset API / Apify SDK.

How to use the Bluesky Posts Scraper

  1. Open the Bluesky Posts Scraper on the Apify Store, or call it via the API below.
  2. Enter one or more search keywords, and optionally set a limit, sort order, date range, or language filter.
  3. Run the Actor and download the dataset as JSON, CSV, or Excel — or read it straight from your own code.

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("parsebird/bluesky-posts-scraper").call(run_input={
"queries": ["bluesky", "decentralized social media"],
"limit": 100,
"sort": "latest",
"lang": "en",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["authorUsername"], item["text"][:80])

JavaScript (Node.js):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('parsebird/bluesky-posts-scraper').call({
queries: ['bluesky', 'decentralized social media'],
limit: 100,
sort: 'latest',
lang: 'en',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Use cases

  • Social listening — track what people are saying about a brand, product, or topic on Bluesky
  • Trend research — pull the top-engagement posts for a keyword over a date range
  • Academic and market research — build datasets of public discourse on a subject
  • Content curation — surface the best recent posts on a topic for a newsletter or feed
  • Competitive monitoring — watch how a keyword or hashtag is trending relative to competitors

How it works

  1. Sends each query to Bluesky's public app.bsky.feed.searchPosts endpoint, with your sort, since, until, and lang filters applied server-side.
  2. Paginates automatically (100 posts per page) until your requested limit is reached or Bluesky has no more matches.
  3. Flattens each post into a clean record: author details, text, images, external link, and engagement counts.
  4. Pushes one row per post to the dataset.

How much does it cost to scrape Bluesky posts?

This Actor uses Pay-Per-Event pricing — you pay per post returned.

EventPrice per eventPrice per 1,000 posts
post-scraped$0.00299$2.99

A post-scraped event fires once for every post pushed to the dataset. Scraping 1,000 posts across any number of queries costs about $2.99. Apify's free monthly platform usage credits apply to this Actor like any other.

FAQ

Do I need a Bluesky account or API key? No. This Actor uses Bluesky's public, unauthenticated AppView API — the same data anyone can see by searching on bsky.app.

Why did my run return fewer posts than my limit? Bluesky applies bursty rate limiting to its search endpoint, especially on deep pagination. This Actor retries automatically with backoff, but a very large limit on a single query may still return fewer posts than requested if Bluesky throttles the run. Splitting a very large request across a scheduled run, or spacing out queries, usually helps.

What format should since and until be in? Either a plain date (2026-01-01) or a full ISO 8601 timestamp (2026-01-01T00:00:00Z). Plain dates are treated as the start/end of that day.

Does this include replies and reposts that match my keyword? It returns whatever Bluesky's search index returns for your query — this is typically top-level posts and replies whose text matches, not reposts (which have no text of their own).

Can I schedule this to run automatically? Yes — use Apify Schedules to re-run your queries daily, weekly, or on any interval, and pair it with webhooks or the Google Sheets, Slack, Zapier, or Make integrations to route the results.

Can I access this via API? Yes — every Actor on Apify has a full REST API, plus native clients for Python and JavaScript. See the code samples above.

Need profiles, follower lists, or comment threads instead of just search? See the Bluesky Scraper below — it covers author feeds, profiles, followers/follows, and comment threads in addition to search.

Yes. This Actor only reads posts that are already public on Bluesky's own search index — the same data any visitor can see without logging in. That said, always respect Bluesky's terms of service and applicable data-protection law for how you subsequently use any personal data in the results. See Apify's blog post on the legality of web scraping for a broader overview.