Bluesky Scraper: Posts, Profiles, Followers & Mentions
Pricing
from $0.80 / 1,000 posts
Bluesky Scraper: Posts, Profiles, Followers & Mentions
Search Bluesky (bsky) posts by keyword, hashtag or account, e.g. product launches or #photography. Get likes, reposts, replies, profiles, author follower counts and new-mention alerts. $0.001 per post: 1,000 posts cost $1; $0.002 per profile. No login.
Pricing
from $0.80 / 1,000 posts
Rating
0.0
(0)
Developer
fortbrand
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
7 days ago
Last modified
Categories
Security
Limited permissionsShare
For brand monitoring teams, researchers, community managers and developers who need public Bluesky posts with author context. Search topics such as product launches, open source software or #photography, follow known accounts, load specific posts and inspect public profiles without a Bluesky login.
About $0.001 per post and $0.002 per requested profile. Twenty posts cost about $0.02; 1,000 delivered posts cost about $1. Author follower counts are included in the post price. A small platform start charge of $0.00005 also applies. Bronze receives 5% off, Silver 10% off and Gold 20% off the row prices. There is no separate charge for the summary, duplicate records, empty results or restricted accounts.
Anonymous search has a source limit: one page of up to 100 candidate posts per query. Replies, language filters and visibility exclusions can reduce the number delivered. Author feeds and public custom feeds support normal pagination. This tool does not promise a complete search archive or the entire social graph.
What you get
| Record | Included information | Useful for |
|---|---|---|
| Post | Text, original timestamp, stable AT URI, CID, author handle and public follower count | Topic monitoring and warehouse joins |
| Engagement | Separate likes, reposts, replies and quotes | Comparing current response to content |
| Rich text | Structured links, hashtags and mentioned account DIDs | Finding shared domains and linked discussions |
| Media | Image URLs and alt text, video playlist when supplied, external card metadata | Content analysis and editorial review |
| Conversation | Reply parent, root URI, quoted-post URI and optional reply sample | Reading public discussion context |
| Profile | Description, follower/following/post counts, account creation time, avatar and banner | Reviewing a known public account |
| Watch | Suppression of records already delivered for a stable watch ID | Repeated collection with fewer duplicate charges |
| Summary | Delivered totals, authors, top hashtags, engagement, exclusions and coverage notes | Checking whether the run covered the requested job |
Missing source values stay null. No email, telephone, private messaging or identity enrichment service is used.
Start in three steps
- Enter one or more
searchTerms, or supplyhandlesfor an author feed. OptionalstartUrlsaccept public post, profile, search or custom-feed links. - Set
maxItems, the maximum total number of paid rows across the whole run. Start with 20 and leave reply expansion off for a first look. - Start the Actor and open its dataset. Export JSON, CSV or Excel, and read the free
SUMMARYrecord for exclusions and source limits.
The tested default returned 20 posts in 5.3 seconds on 29 October 2026. Reply expansion, many sources, watch history and source response times affect duration.
{"searchTerms": ["bluesky"],"sort": "latest","maxItems": 20,"includeReplies": false}
Choose the right source
searchTerms discover posts using Bluesky search syntax. Use keywords, hashtags, quoted phrases, from:bsky.app and inline since: / until: dates. Date bounds intersect with date inputs. For dated account searches, include a keyword or use handles. Queries that the public API rejects produce free source notes. Inputs are deduplicated; matchedTerms lists queries that actually returned a record in the inspected pages.
handles collect an account's own posts. The Actor excludes records present solely because the account reposted somebody else. Set includeReplies to include its reply posts as well. Follower enrichment is included, but this input does not create an additional paid profile row.
A profile URL in startUrls returns one profile row only. A post URL returns that post, with optional reply expansion. A custom-feed URL reads the public feed in its supplied order. A search URL uses the query from its q parameter. Plain URL strings and objects containing url are both accepted. AT URIs for posts and feed generators are accepted too.
{"handles": ["bsky.app", "nature.com"],"maxItems": 50,"includeReplies": false}
{"startUrls": ["https://bsky.app/profile/bsky.app",{"url": "https://bsky.app/profile/nature.com"}],"maxItems": 2}
Input reference
| Input | Default | Meaning |
|---|---|---|
searchTerms | bluesky in the prefill | Array of keywords or native search queries |
handles | Empty | Array of account handles or DIDs whose own posts to collect |
startUrls | Empty | Optional public post, profile, search or feed links |
sort | latest | latest or top, for search results only |
since | Unset | Inclusive date or timestamp boundary for posts |
until | Unset | Exclusive date or timestamp boundary for posts |
language | Unset | Language code such as en, de or pt-BR |
maxItems | 20 | Global paid-row cap, from 1 to 10,000 |
includeReplies | false | Allow reply posts and expand selected roots |
maxRepliesPerPost | 5 | Maximum replies inspected per root, from 0 to 100 |
onlyNewSinceLastRun | false | Enable delivery history for this watch |
watchId | default | Stable monitoring name using letters, digits, underscores or hyphens |
proxyConfiguration | No proxy | Optional supported Apify or custom proxy configuration |
Dates without a time mean midnight UTC. For all of 28 October, use since: "2026-10-28" and until: "2026-10-29". Post timestamps are checked locally as well as using available search filters. The source search index can use a sorting timestamp different from the original post timestamp, so a filtered search is not an archival completeness guarantee. Date and language filters apply to posts, not profile rows.
Post fields
Selected fields from a real 29 October 2026 run:
{"verdict": "2,979 likes, 325 reposts, 193 replies; 35,430,011 author followers.","type": "post","uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3myx7vphq3s2j","text": "getting our Halloween decorations set up","createdAt": "2026-10-28T16:58:02.827Z","authorHandle": "bsky.app","authorFollowers": 35430011,"likes": 2979,"reposts": 325,"replies": 193,"quotes": 110,"isNewSinceLastRun": null,"url": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/post/3myx7vphq3s2j"}
| Field | Description |
|---|---|
type | post |
uri, cid, url | Stable record identity, content identifier and public link |
text, createdAt, indexedAt, observedAt | Source text, original time, indexing time and collection time |
authorDid, authorHandle, authorDisplayName | Public author identity supplied by the source |
authorFollowers, authorFollowing, authorPosts | Public author counts from profile enrichment |
authorCreatedAt, authorAvatar, authorEnriched | Extra author context and enrichment status |
likes, reposts, replies, quotes | Separate source counts at collection time |
engagement | Sum of the four counts when all four are available |
language | Source language-code array |
links, hashtags, mentions | Structured rich-text facets; mentions contain DIDs |
images, video, external | Available image metadata, video view and external card |
isReply, replyTo, replyRoot | Conversation relationships |
quoteUri, quoteUrl | Referenced quoted record, without copying its content |
matchedTerms, sourceInputs | Observed query matches and collection provenance |
sourcePostUri | Root selected for optional reply expansion, otherwise null |
isNewSinceLastRun | true for newly delivered watch rows; null when watches are off |
labels | Public source labels attached to the post |
Profile rows contain type, did, handle, displayName, description, followers, following, posts, createdAt and url, plus available avatar, banner, labels, verification and observation time. A profile lookup is not proof of a person's identity or control of another website.
The dataset includes free note and SUMMARY rows. Filter by type before importing. ## Monitor mentions every day
Save a task with a narrow query, enable onlyNewSinceLastRun and keep the same watchId on each scheduled run. The first run delivers qualifying records and establishes the history. Later runs suppress records that this watch has already delivered. A post found through two inputs is still delivered and charged only once within the run.
{"searchTerms": ["from:bsky.app"],"sort": "latest","maxItems": 20,"onlyNewSinceLastRun": true,"watchId": "official-updates"}
Run a watch sequentially. Do not overlap scheduled runs using the same watch ID. An unfinished run blocks reuse of that watch so its pending delivery is not silently repeated. Resume the original run or use a different ID for an independent history. History records delivery, rather than every post that existed between schedules. If a query produces more than a public search page between runs, some posts may be missed. Run narrower queries frequently enough for the topic, or monitor known author feeds. Engagement changes on an old post do not make it a new record; switch watches off to take repeated engagement snapshots.
Pricing examples
| Delivered records | Standard row price |
|---|---|
| 20 posts | $0.02 |
| 100 posts | $0.10 |
| 1,000 posts across eligible sources | $1.00 |
| 20 requested profiles | $0.04 |
| 100 posts and 10 profiles | $0.12 |
Add the small start charge, then apply the relevant row discount. Replies cost the same as posts. maxItems includes replies and requested profiles, so reply expansion does not exceed that global row cap. Your maximum total charge is also respected: the Actor stops cleanly when the remaining budget cannot cover another eligible row. A record is saved before its corresponding row charge is made. Empty results, failures and note rows have no post or profile charge.
Use with AI agents (MCP)
Connect your agent to https://mcp.apify.com. Ask it to inspect the input schema and pricing, then request: “Collect 20 public Bluesky posts about open source software with author follower counts, separate repost and quote counts, links and hashtags.” ## API and integrations
Use an Apify token from your environment; no Bluesky token is needed.
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('vant47/bluesky-posts-profiles-scraper').call({searchTerms: ['open source'], maxItems: 20, sort: 'latest'});const { items } = await client.dataset(run.defaultDatasetId).listItems();const posts = items.filter(row => row.type === 'post');
The REST endpoint is POST https://api.apify.com/v2/acts/vant47~bluesky-posts-profiles-scraper/runs, using an Authorization bearer header and a JSON input body. Poll the returned run ID, then fetch defaultDatasetId. The SUMMARY record is also available in the default key-value store.
Schedules, Make, Zapier and n8n can trigger tasks and consume webhooks. Upsert by type plus uri or did; preserve observedAt for snapshot comparisons.
Limits and FAQ
Does it collect follower lists? No. “Followers” refers to public follower counts in posts and profiles. This Actor does not enumerate follower or following identities.
Does it require login or solve access challenges? No. It uses standard signed-out AppView requests. It does not log in, solve challenges or bypass denied search pagination. Accounts and posts carrying !no-unauthenticated are excluded, including during author enrichment.
Can it collect every reply? No. Reply expansion is a bounded sample of the thread returned by the source, with a maximum depth of six and your per-root cap. Deleted, blocked, restricted and unavailable replies are omitted. The global row limit can stop expansion sooner.
Why did I receive fewer rows? Search boundaries, filters, delivery history, source availability and budget can reduce output. Read the summary before increasing the limit.
Are counts live? They are source snapshots taken during the run. AppView caching and indexing can lag the website, and counters can change between collection and inspection. The website can display combined repost-and-quote totals, while this output keeps them separate.
Does a reboot duplicate data or charges? Saved dataset rows act as the delivery ledger. On restart the Actor reconciles platform charge counts and acknowledged receipts before continuing. Duplicate inputs are free; an ambiguous billing state stops further delivery instead of guessing.
What happens if a source is unavailable? Permitted transient retries are paced, rate-limit advice is honoured, and unavailable data produces free notes. Partial results stay available. Check status, notes, sources and exclusions in the summary before treating a run as complete.