Bluesky Scraper: Posts, Profiles, Followers and Feeds avatar

Bluesky Scraper: Posts, Profiles, Followers and Feeds

Pricing

$1.00 / 1,000 results

Go to Apify Store
Bluesky Scraper: Posts, Profiles, Followers and Feeds

Bluesky Scraper: Posts, Profiles, Followers and Feeds

Scrape Bluesky without a login: user posts, keyword search, profiles, followers and follows, full reply threads, likers and reposters, and custom or list feeds. Clean typed records with engagement counts, hashtags, mentions, links and image alt text, from the official public AT Protocol API.

Pricing

$1.00 / 1,000 results

Rating

0.0

(0)

Developer

Angad Jangir

Angad Jangir

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Security

Limited permissions

Share

Bluesky Scraper: posts, profiles, followers, threads, likers and feeds

Scrape Bluesky without a login or an account. Get a user's posts, search posts by keyword or hashtag, read profiles, followers and follows, download a full reply thread, list who liked or reposted a post, and read any custom feed or list. Every record comes back in one clean, typed shape with engagement counts, hashtags, mentions, links, image URLs with alt text, reply and quote links, and ISO dates.

The data comes from Bluesky's own public AT Protocol API (the AppView at public.api.bsky.app), the same open API that Bluesky apps use, so it is complete, fast and stable. No cookies, no browser, no app password.

Who uses it

  • Social listening and brand monitoring: track mentions of a brand, product or hashtag on Bluesky every hour.
  • Researchers and journalists: collect posts, threads and follower graphs for studies of public discourse.
  • Marketers and growth teams: find influencers by topic, read their follower counts, and see who engages with competitors' posts.
  • Data and AI teams: build training and evaluation sets from public posts with language tags and image alt text.
  • AI agents: call the Actor as a tool through the Apify MCP server ("what is bsky.app posting this week?").

Modes

ModeInputWhat you get
User postshandles, DIDs or profile URLsThe user's posts, newest first. Options: replies, reposts, pinned post, only media, date range, keyword filter. The user's follower counts are added to every post for free.
Search postssearch termsPosts matching each term (Bluesky search syntax: #tag, from:handle, "exact phrase", domain:, mentions:), newest or top, optional language and date range.
Profileshandles, DIDs or profile URLsFull profile: bio, follower, following and post counts, avatar, banner, labels, verification, pinned post.
Search profilessearch termsAccounts matching a name or bio keyword, with full counts.
Followers / Followshandles, DIDs or profile URLsEveryone who follows the user, or everyone the user follows, with full profile counts.
Post threadpost URLsThe post, its parents up to the root, and the whole reply tree, flattened. threadDepth is 0 for the post, 1 for direct replies, 2 for replies to those, and negative for parents.
Post engagementpost URLsAccounts that liked the post (with the time of the like), accounts that reposted it, and posts that quote it.
Custom feedfeed URLs, list URLs or at:// URIsPosts from any custom feed (for example Discover) or any list feed.

Why this one

  • 9 modes in one Actor, including threads, likers, reposters, quotes, follows and list feeds.
  • Typed, flat records: counts are numbers, dates are ISO, missing values are null, and every post has the same columns, so CSV and Excel exports just work.
  • Rich post fields: hashtags, mentions (handle and DID), every link, images (full size, thumbnail, alt text, size), video playlist, external link card, quoted post, reply parent and thread root.
  • Reliable: official API only, polite pacing, automatic back-off on HTTP 429 and server errors, cursor pagination, and a per-input SUMMARY so you see exactly what each input returned.
  • Fair limits: Max records is shared evenly across your inputs, so ten users get ten fair slices instead of the first user taking everything. Share that an input cannot use (an account with few posts, a bad handle) goes to the inputs that have more.
  • Respects user choices (see below).

Accounts that opted out are skipped

Bluesky posts are public by the protocol's design, but every user can turn on "Discourage apps from showing my account to logged-out users". That sets the !no-unauthenticated label on their account. This Actor honours it everywhere: profiles and posts from accounts with this label are never saved (in search results, feeds, threads, likers, followers, everything). The SUMMARY record counts how many were skipped (skippedOptOut). You are not charged for skipped records.

Example inputs

Latest 100 posts from two accounts, with replies, from the last 30 days:

{
"mode": "userPosts",
"users": ["bsky.app", "https://bsky.app/profile/nytimes.com"],
"includeReplies": true,
"since": "30 days",
"maxItems": 100
}

Search two hashtags in English, top results:

{
"mode": "searchPosts",
"searchQueries": ["#ai", "#climate"],
"searchSort": "top",
"searchLanguage": "en",
"maxItems": 200
}

Full reply tree of a post:

{
"mode": "postThread",
"postUrls": ["https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l"],
"maxItems": 1000
}

Who liked and reposted a post, with follower counts:

{
"mode": "postEngagement",
"postUrls": ["https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l"],
"engagementTypes": ["likes", "reposts"],
"maxItems": 500
}

First 1,000 followers of an account:

{ "mode": "followers", "users": ["jay.bsky.team"], "maxItems": 1000 }

Posts about "election" from the Discover feed and a list:

{
"mode": "customFeed",
"feeds": ["https://bsky.app/profile/bsky.app/feed/whats-hot", "https://bsky.app/profile/bsky.app/lists/3lvpca43j5z26"],
"keywords": ["election"],
"maxItems": 100
}

Output

Each record has recordType "post" or "profile". A real post record (search for #astronomy, top):

{
"recordType": "post",
"uri": "at://did:plc:btzjjptgouva43ko4ip5pl67/app.bsky.feed.post/3mzkg6k7w5kyn",
"cid": "bafyreicmjujpigfficrt5jcscyikg2nyo3hkrlnqxotc5s7fdkjn4zpome",
"rkey": "3mzkg6k7w5kyn",
"url": "https://bsky.app/profile/apod.shinyakato.dev/post/3mzkg6k7w5kyn",
"text": "🔭 Enceladus in Silhouette\n\nCredit: Cassini Imaging Team, SSI, JPL, ESA, NASA\n\nap261105",
"createdAt": "2026-11-05T08:10:56.806Z",
"indexedAt": "2026-11-05T08:10:58.381Z",
"authorDid": "did:plc:btzjjptgouva43ko4ip5pl67",
"authorHandle": "apod.shinyakato.dev",
"authorDisplayName": "Astronomy Picture of the Day 🪐",
"authorAvatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:btzjjptgouva43ko4ip5pl67/bafkreidjotrof5t65mz3ba7ayzfsqgjri76cyvbzh2iowspte6ppcej3pa",
"authorFollowersCount": null,
"authorFollowsCount": null,
"authorPostsCount": null,
"authorVerified": false,
"authorLabels": [],
"replyCount": 0,
"repostCount": 27,
"likeCount": 73,
"quoteCount": 0,
"bookmarkCount": 5,
"langs": [],
"hashtags": ["nasa", "apod", "science", "astronomy", "APOD-261105"],
"mentions": [],
"links": ["https://ciclops.org/", "https://www.spacescience.org/", "https://www.jpl.nasa.gov/", "https://www.esa.int/", "https://www.nasa.gov/", "https://science.nasa.gov/apod/?date=261105"],
"images": [
{
"url": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:btzjjptgouva43ko4ip5pl67/bafkreigreamyuydczuxsppvv2phkz3iprae7rntc6n4444asx6rhkjo6ii",
"thumb": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:btzjjptgouva43ko4ip5pl67/bafkreigreamyuydczuxsppvv2phkz3iprae7rntc6n4444asx6rhkjo6ii",
"alt": "Saturn moon Enceladus in silhouette",
"width": null,
"height": null
}
],
"video": null,
"externalLink": null,
"embedType": "images",
"quotedPostUri": null,
"quotedPostUrl": null,
"quotedPostText": null,
"quotedPostAuthorHandle": null,
"isReply": false,
"replyTo": null,
"replyToUrl": null,
"rootUri": null,
"isRepost": false,
"repostedByHandle": null,
"repostedAt": null,
"isPinned": false,
"labels": [],
"threadDepth": null,
"source": "searchPosts",
"input": "#astronomy",
"scrapedAt": "2026-11-05T15:49:14.920Z"
}

A real profile record (a liker from Post engagement):

{
"recordType": "profile",
"did": "did:plc:rhqbtzvxl3yt7dbhgy77jqws",
"handle": "nb1shadowfan.bsky.social",
"url": "https://bsky.app/profile/nb1shadowfan.bsky.social",
"displayName": "Ash",
"description": null,
"pronouns": null,
"website": null,
"followersCount": 7,
"followsCount": 46,
"postsCount": 0,
"createdAt": "2025-01-30T19:49:41.344Z",
"indexedAt": "2026-03-05T18:53:53.551Z",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:rhqbtzvxl3yt7dbhgy77jqws/bafkreid6eh4azz7h6u7gufgwke6rusnddrrgdtu7xj2johgeff6jsw66zy",
"banner": "https://cdn.bsky.app/img/banner/plain/did:plc:rhqbtzvxl3yt7dbhgy77jqws/bafkreih5bbni6e5nxt7iworirqkibp2sautq7ojfea47kzeaynrcc7fe6u",
"labels": [],
"isVerified": false,
"isLabeler": false,
"listsCount": 0,
"feedsCount": 0,
"starterPacksCount": 0,
"pinnedPostUri": null,
"relation": "like",
"relatedTo": "at://did:plc:qjeavhlw222ppsre4rscd3n2/app.bsky.feed.post/3mzj2fyriss2n",
"relatedAt": "2026-11-05T15:33:16.452Z",
"source": "postEngagement:likes",
"input": "https://bsky.app/profile/rose.bsky.team/post/3mzj2fyriss2n",
"scrapedAt": "2026-11-05T15:46:40.484Z"
}
FieldWhat it is
uri, cid, rkey, urlAT Protocol identifiers and the bsky.app link
text, langs, createdAt, indexedAtPost text, language tags set by the author, ISO times
author*DID, handle, display name, avatar, verification, labels; follower, following and post counts in User posts mode (always) or with Add author follower counts (any mode)
replyCount, repostCount, likeCount, quoteCount, bookmarkCountEngagement counts at scrape time
hashtags, mentions, linksFrom the post's rich-text facets and tags; links also include the link-card URL
images, video, externalLink, embedTypeMedia and embeds (images, video, external, quote, quoteWithMedia)
quotedPost*The quoted post's URI, URL, text and author
isReply, replyTo, replyToUrl, rootUriReply parent and thread root
isRepost, repostedByHandle, repostedAt, isPinnedFeed context in User posts and feeds
threadDepthPosition in a Post thread
Profile relation, relatedTo, relatedAtfollower, follow, like, repost, search or profile; the account or post it relates to; the time of the like

The run's SUMMARY record (key-value store) lists every input with records saved, items scanned, accounts skipped for opting out, and a clear error for any input that failed (for example a handle that does not exist).

Pricing

You pay per record saved to the dataset. Records removed by your filters and accounts skipped for opting out cost nothing. Max records is a hard cap, so you always know the most a run can cost.

Limits

  • Search returns up to 100 posts per search term. Bluesky serves only the first page of search results to logged-out clients and refuses further pages without a login. This Actor never logs in, so for more posts add more specific terms (per hashtag, per language, from: a user, or narrower date ranges with Posted since/until). If Bluesky ever closes logged-out search completely, the Actor automatically falls back to matching your term against the public Discover feed and says so in the run log and SUMMARY.
  • Custom feeds are ranked by their creator, not by date, so Posted since filters them but cannot stop paging early. A feed is read until Max records or a safety cap of scanned posts.
  • Very large threads are capped by Bluesky. For a post with thousands of replies, the public API serves a few hundred of them (for example about 760 posts for a post with 8,700 replies), always including the reply chains below each reply it serves. Threads of normal size come back complete.
  • Counts are a snapshot at scrape time.
  • Deleted posts, blocked threads and accounts that opted out of logged-out viewing are not returned.

Schedules, webhooks and integrations

  • Monitoring: save your input as a Task and add a Schedule (for example every hour, with Posted since 2 hours) to track a hashtag, a brand or a set of accounts.
  • Google Sheets, Slack, email, Zapier, Make, n8n: connect them in the Integrations tab to send each run's records where you need them.
  • Webhooks: get a call when a run finishes and fetch the dataset from the API.
  • MCP / AI agents: the Actor works as a tool in the Apify MCP server, so an agent can read posts, threads and profiles as structured data.

FAQ

Is this legal and clean? The Actor reads only public data from Bluesky's official public API, which Bluesky documents for unauthenticated use; its robots.txt says "Crawling the public parts of the API is allowed". It does not log in, use anyone's account or app password, solve captchas or get around any protection. It paces requests well under Bluesky's published rate limits and backs off when asked (HTTP 429). It honours each user's !no-unauthenticated choice. You are responsible for how you use the data, including privacy laws such as GDPR when you store personal data.

Do I need a Bluesky account or app password? No.

What can I paste as a user? A handle (bsky.app, @jay.bsky.team), a custom-domain handle (nytimes.com), a DID (did:plc:...) or any bsky.app profile or post URL. A bare name like alice is read as alice.bsky.social.

Why did a user return nothing? The handle may not exist (see SUMMARY), the account may have opted out of logged-out viewing, or your date and keyword filters removed everything.

Why are there fewer search results than Max records? See Limits: logged-out search gives up to 100 posts per term. Add more terms.

Something broke or a field is missing? Open an issue on the Actor's Issues tab and it will be fixed quickly.

More Actors by angadseth