Bluesky Scraper | $0.50/1K | Posts & Engagement avatar

Bluesky Scraper | $0.50/1K | Posts & Engagement

Pricing

from $0.40 / 1,000 useful bluesky posts

Go to Apify Store
Bluesky Scraper | $0.50/1K | Posts & Engagement

Bluesky Scraper | $0.50/1K | Posts & Engagement

Collect public Bluesky author feeds and keyword searches with text, dates, engagement and media metadata. Latest search uses overlapping time windows, URI deduplication and bound continuation. No complete archive guarantee.

Pricing

from $0.40 / 1,000 useful bluesky posts

Rating

0.0

(0)

Developer

Apivault Labs

Apivault Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Bluesky Scraper — Public Search, Author Posts & Engagement

Bluesky public post collection illustration

Concept illustration, not actual post content or live product UI.

Turn public Bluesky posts into structured JSON or a CSV table: original text, author identity, source dates, observed engagement and available media links. Use it for a small brand-mention sample, an author's public posting history, or research datasets that retain the original post URI.

Private development candidate. Initial pricing has owner approval; publication requires exact-build review. Private QA is not a public Store release. Public source access can change. The Actor does not log in, solve challenges, rotate proxies or retrieve private content.

Start with an author feed

{
"mode": "author",
"actor": "bsky.app",
"maxPosts": 5,
"maxPages": 2,
"pageSize": 10
}

Supply a Bluesky handle or DID. This mode reads the public author feed, rather than searching for mentions of that person. Replies are included by default; repost entries are excluded. A two-page local source probe returned ten distinct posts, but that is not proof of unlimited archive access.

Search public posts

{
"mode": "search",
"query": "python",
"sort": "latest",
"maxPosts": 5,
"pageSize": 10
}

Search uses Bluesky's public AppView search endpoint. Latest search now defaults to overlapping time windows using the supported until filter. Each following window overlaps the oldest source creation timestamp by one second; URI deduplication prevents a repeated result event. A local proof covered three windows each for two keywords. This is a bounded sample of a live search index, not a complete historical export. Native cursor requests returned403; they remain an explicit optional mode, without automatic retries or a silent fallback after an error. A source error retains useful rows and diagnostics. top uses native cursor mode and may therefore return403 on continuation. Time windows require latest. The Actor does not calculate a popularity score.

Useful recipes

GoalSettings
Public author samplemode=author, actor=bsky.app
Original standalone postsincludeReplies=false, includeReposts=false
Include repost entriesincludeReposts=true; still deduplicates original URI
Brand/keyword mention samplemode=search with your query
Only posts with an observed reaction thresholdminLikes=10; unknown counts fail a positive threshold
Resume a bounded collectionCopy CONTINUATION.resumeInput unchanged

These are input recipes, not claims of five published Tasks. Saved Tasks, if created during QA, remain private until separately published and read back. The source index is live: cursor pagination cannot guarantee a stable historical snapshot or completeness.

What each row means

FieldsMeaning
uri, cid, postId, postUrlOriginal at:// post identity, content ID when present and public link
textSource post text; an image/video-only post may have empty text
authorOriginal author's DID, handle and display name; not the person who reposted
createdAtAuthor-supplied creation timestamp, if present
indexedAtAppView indexing timestamp, separately named
observedAtTime our collector observed the row
likeCount, repostCount, replyCount, quoteCountExposed nonnegative counters; unavailable values remain null
languages, hashtags, linksDeclared record languages and rich-text facet metadata
images, video, externalAvailable embed metadata and source links; no media files downloaded
parentUri, rootUri, quotedUriExposed references; no thread tree or quoted-post enrichment
isRepost, repostedByFeed repost context; original URI remains the deduplication key

Counts and links are observations, not guarantees of current engagement, availability or ownership. The Actor does not infer sentiment, author location, contact information, follower lists or demographic attributes. It does not fetch the external links contained in posts. The same original post returned more than once becomes one Dataset row per run.

Inputs and bounds

InputDefaultBehavior
modesearchsearch or author
queryRequired in searchUp to500characters; source search syntax
actorRequired in authorHandle or DID, not an arbitrary URL
sortlatestlatest or top; search route only
searchPaginationtime_windows for latest searchOverlapping until windows; cursor for top/author. No complete archive guarantee
since / untilUnsetISO timestamps with timezone; search only, not a full archive guarantee
langUnsetLanguage code forwarded to search; author mode rejects this filter
maxPosts201–10,000 delivered posts; synthetic bound, not a bulk benchmark
maxPages51–1,000 requests; errors stop rather than retry
pageSize251–100 source entries per request
maxRunSeconds12030–1,800seconds; allowance for an in-flight request
requestDelayMs500250–10,000ms between sequential pages
includeRepliestrueFilter reply posts; does not collect replies to a post
includeRepostsfalseFilter author-feed repost entries
minLikes0Minimum known like count; unknown passes only0
startCursorUnsetSource cursor; use full continuation input
excludeUrisEmptyUp to20,000 known post URIs; affects delivery, not source page fetching

Unsupported fields and invalid combinations fail before source requests. This protects against silently ignoring a date/language filter in author mode.

Continuation, errors and coverage

After a result, time or page limit, open the CONTINUATION record and copy resumeInput into the next run. It contains the mode, query/author, source cursor, filters and already delivered URIs. If the run stops midway through a page, the next run intentionally replays that page and excludes previously delivered posts, so an unprocessed tail is not silently skipped. Keep the same query and ordering. Time-window continuation also binds the original date filters, language, page size and pagination mode; changing these fields is rejected before source requests. You can change result/page/time limits. A saturated timestamp boundary stops with SEARCH_WINDOW_STALLED rather than jumping over a tied group. If the source has more posts at that boundary than a page can expose, coverage remains incomplete. Source creation timestamps are author-supplied and can differ from source indexing/sort timestamps, another reason that time windows cannot establish complete coverage.

A source-exhausted response has resumeInput: null. This only means no next cursor was returned; it does not prove a complete public or historical archive. A429/403 response, invalid API shape, repeated cursor or stalled time-window boundary is a diagnostic rather than a successful empty collection. Errors after useful posts retain those rows and report partial coverage. Errors with no useful posts fail visibly. A legitimately empty search or filter result can succeed with zero rows.

SUMMARY distinguishes fetched entries, useful delivered posts, filtered entries, duplicates, invalid entries, pages and stop reason. ERRORS contains sanitized failure codes. No API credentials are accepted or required by this MVP. After a crash, reconcile the actual Dataset before continuation because a recent successful write may precede the latest saved checkpoint. Do not interpret missing posts as deletions or an incomplete query as a complete monitoring baseline.

Cost and integrations

The owner-approved initial result tariff is $0.50 per1,000 useful posts on the Free tier and $0.40 per1,000 on paid plans, with no Actor startup fee. Apify compute, storage and transfer are paid separately by the user. Failed source requests can consume platform resources even when no post result is charged. A maximum Actor charge caps event fees, not all separate platform usage. Use page and time limits too. The code distinguishes an accepted free Dataset write from a rejected positive-price PPE event; live billing and budget checks must pass on the exact candidate before release.

Export the Dataset as JSON, CSV or Excel through Apify. JSON preserves nested author/embed fields; the overview table offers common columns. An authorized API client can start the Actor and read its defaultDatasetId using Apify's Python client or JavaScript client. A generic n8n HTTP/Apify workflow can use the same input recipes. A dedicated Bluesky npm node, PyPI package or custom MCP server is not verified or advertised.

FAQ

Does it include private posts or require a session cookie? No. The MVP only requests public AppView endpoints and accepts no session secrets.

Will it collect every matching post or all of an author's history? No completeness guarantee is made. Source indexing, cursor behavior, filters and errors limit coverage. The supported numeric cap does not establish live access to that many posts.

Are replies a full discussion tree? No. includeReplies controls whether reply posts already in the search/feed are retained. Parent/root fields are references, not fetched thread data.

Will a repost create duplicate charges for the same original post? The original URI deduplicates output within a run and across a continuation exclusion list. Separate independent runs are separate observations. Duplicates and filtered entries do not become result events.

Can I monitor deletions or engagement growth? You can collect timestamped observations, but the Actor does not implement lifecycle classification, deletion detection or notifications. A missing post in a limited response cannot establish deletion.