Bluesky Post Search Scraper avatar

Bluesky Post Search Scraper

Pricing

from $3.50 / 1,000 bluesky post scrapeds

Go to Apify Store
Bluesky Post Search Scraper

Bluesky Post Search Scraper

Search public Bluesky posts by keyword, author, date, language, hashtag, mention, domain, or URL. Use for monitoring and research; not profiles, followers, feeds, or private data. Returns post text, author, time, engagement, media, and URL. 0.0035 USD/post + 0.00005 USD start; usage extra.

Pricing

from $3.50 / 1,000 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

a day ago

Last modified

Share

Search public Bluesky posts by keyword or phrase and export one structured post per dataset row. This Actor is built for brand monitoring, journalism, market research, social listening, and AI-agent workflows that need current post text, author identity, timestamps, engagement metrics, media, hashtags, mentions, and source URLs.

Use it when you need Bluesky's search index with optional author, date, language, hashtag, mention, linked-domain, or linked-URL filters. Do not use it for full user feeds, profiles, follower graphs, private data, or complete conversation threads.

What data does it return?

Field groupIncluded fields
PostpostUri, postCid, postUrl, text, createdAt, indexedAt
AuthorauthorDid, authorHandle, authorDisplayName, authorAvatarUrl
EngagementlikeCount, repostCount, replyCount, quoteCount, engagementCount
ConversationisReply, replyRootUri, replyParentUri, quotedPostUri
Rich textlangs, links, mentionedDids, tags, labels
MediaimageUrls, imageAltTexts, video URLs, external link-card fields
ProvenancesearchQuery, sort, rank, collectedAt, sourceEndpoint

Every optional field has a stable explicit null or empty-array value, making rows consistent for CSV exports, databases, and agents. OUTPUT and RUN_SUMMARY are also written on every terminal path.

Pricing

This Actor uses Pay per event + usage:

EventPrice
Actor start$0.00005 per run, scaled by memory
Bluesky post scraped$0.0035 per persisted post
Apify platform usageAdded separately by Apify

A 100-post run has at most $0.35005 in Actor event charges, plus Apify platform usage. Invalid input and valid-empty searches do not create per-post charges. A charge cap can stop persistence safely, and the final summaries disclose the actual post-event count.

Input

The only required field is searchQuery.

{
"searchQuery": "open source",
"sort": "latest",
"maxResults": 100,
"since": "2026-07-01",
"until": "2026-07-15",
"lang": "en",
"author": "",
"mentions": "",
"domain": "github.com",
"url": "",
"tags": ["opensource"],
"includeReplies": true
}

Bluesky defines the query field but leaves exact phrase, boolean, and faceting syntax implementation-specific; Lucene-style syntax is recommended by the AT Protocol lexicon. If Bluesky rejects a query, the Actor returns INVALID_INPUT with a simpler working example.

Important filter behavior

  • since is inclusive; until is exclusive.
  • Date filtering follows Bluesky's search timestamp, which may differ from a post's createdAt.
  • Multiple tags use AND matching and should not include #.
  • mentions matches structured rich-text mentions, not text that only resembles a handle.
  • includeReplies: false removes reply records after Bluesky returns the search page.
  • maxResults is capped at 100 because Bluesky's public search route currently rejects cursor continuation. Split larger research jobs with date, author, language, hashtag, or domain filters.

Output example

{
"searchQuery": "open source",
"sort": "latest",
"rank": 1,
"postUri": "at://did:plc:example/app.bsky.feed.post/3abc",
"postCid": "bafyreiexample",
"postUrl": "https://bsky.app/profile/alice.bsky.social/post/3abc",
"text": "A new open-source release is available today.",
"authorDid": "did:plc:example",
"authorHandle": "alice.bsky.social",
"authorDisplayName": "Alice",
"authorAvatarUrl": null,
"createdAt": "2026-07-15T10:00:00.000Z",
"indexedAt": "2026-07-15T10:00:01.000Z",
"langs": ["en"],
"likeCount": 42,
"repostCount": 7,
"replyCount": 5,
"quoteCount": 2,
"engagementCount": 56,
"isReply": false,
"replyRootUri": null,
"replyParentUri": null,
"links": ["https://example.com/release"],
"mentionedDids": [],
"tags": ["opensource"],
"labels": [],
"imageUrls": [],
"imageAltTexts": [],
"videoPlaylistUrl": null,
"videoThumbnailUrl": null,
"externalUrl": "https://example.com/release",
"externalTitle": "Release notes",
"externalDescription": "What's new in this version.",
"externalThumbUrl": null,
"quotedPostUri": null,
"collectedAt": "2026-07-15T11:00:00.000Z",
"sourceEndpoint": "https://api.bsky.app/xrpc/app.bsky.feed.searchPosts",
"_note": null
}

Run outcomes

OutcomeRun statusMeaning
COMPLETESucceededSearch finished and all valid rows were persisted
PARTIALSucceededUseful rows were saved before a charge cap or later failure
VALID_EMPTYSucceededValid search completed with no matching posts
INVALID_INPUTSucceededChange the input using the actionable message
UPSTREAM_FAILEDFailedBoth configured Bluesky AppView routes failed with no useful rows
CONFIG_ERRORFailedDeployment, schema, or storage behavior prevented useful output

API

Keep the Apify token in the Authorization header, never in a URL:

curl -X POST \
'https://api.apify.com/v2/acts/khadinakbar~search-bluesky-posts/runs?waitForFinish=300' \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"searchQuery":"open source","maxResults":25,"sort":"latest"}'

CLI

apify call khadinakbar/search-bluesky-posts \
--input='{"searchQuery":"open source","maxResults":25,"sort":"latest"}'

MCP and AI agents

Expose the Actor through Apify's hosted MCP server and call it with a focused query plus a bounded maxResults. The declared dataset schema gives agents stable post-level fields; use get-actor-output with the returned dataset ID to read or paginate the stored rows.

Reliability and limitations

  • Source: Bluesky's public app.bsky.feed.searchPosts AppView XRPC endpoint at api.bsky.app.
  • Authentication: none for the current api.bsky.app public read route.
  • Fallback: a second Bluesky-hosted public AppView hostname is attempted after bounded retries; third-party provider routes are not used because they do not currently offer equivalent Bluesky post search.
  • Search coverage, ranking, and hit counts are controlled by Bluesky. hitsTotal may be rounded or truncated. Public cursor requests currently return HTTP 403, so one run returns at most the first 100 matches; use narrower filters for additional coverage.
  • Deleted, blocked, labeled, or unindexed content may be absent. Engagement counts are point-in-time observations.
  • The Actor searches public posts only and does not bypass privacy controls, moderation, or access restrictions.

Use public Bluesky data in accordance with applicable law, the AT Protocol and Bluesky terms, and your own privacy and research obligations. Do not use this Actor for harassment, unlawful surveillance, discrimination, or attempts to identify private individuals. You are responsible for how collected data is stored, combined, and used.