Bluesky Scraper - Posts, Threads, Likes & Profiles avatar

Bluesky Scraper - Posts, Threads, Likes & Profiles

Pricing

from $0.46 / 1,000 posts

Go to Apify Store
Bluesky Scraper - Posts, Threads, Likes & Profiles

Bluesky Scraper - Posts, Threads, Likes & Profiles

Bluesky scraper: extract public posts from author feeds and threads, with text, date, likes, reposts, replies, quotes, hashtags, mentions, links and images. Optional author profiles. Public AT Protocol API, no login, flat JSON.

Pricing

from $0.46 / 1,000 posts

Rating

0.0

(0)

Developer

CrawlKit

CrawlKit

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Security

Limited permissions

Share

Extract public Bluesky posts as flat JSON rows: from the feeds of the accounts you choose, from threads (a post with its replies), or from a one-page search. Each row has the post text, date, like, repost, reply and quote counts, hashtags, mentions, links, images and reply references. Author profiles are optional.

What it does

  • Author feeds: give handles (bsky.app, @jay.bsky.team), profile URLs or DIDs. The Actor follows the feed's pagination cursor until maxItems posts per account or the end of the feed. Replies by the author are left out unless includeReplies is on; reposts are kept and flagged (isRepost, repostedBy) unless includeReposts is off.
  • Threads: give post URLs (https://bsky.app/profile/<handle>/post/<id>). The Actor returns the post, the posts above it in the thread (root first) and its replies, up to maxItems rows per thread.
  • Search: give a searchQuery. Bluesky serves only the first page of search results without login, so the search returns at most 25 posts (see Limitations).
  • Profiles (optional): with includeProfiles, one extra row per handle with followers, follows, post count, bio, avatar and creation date.
  • A post is returned once per run, even if several inputs lead to it. An invalid handle or URL is skipped and named in the run's status message; the run fails with an explicit message only when no post at all could be returned.
  • Uses the public Bluesky AppView API of the AT Protocol (public.api.bsky.app, api.bsky.app for search). No login, no API key, no browser, no proxy. Requests are sent one at a time; on HTTP 429 the Actor waits for the time the API asks for.

Input

ParameterTypeRequiredDefaultDescription
handlesarray of stringsOne of the three sources—Handles, profile URLs or DIDs. A name without a dot gets .bsky.social appended
postUrlsarray of stringsOne of the three sources—Post URLs or at:// URIs; each one gives its thread
searchQuerystringOne of the three sources—Full-text search, first page only (25 posts at most)
includeRepliesbooleanNofalseAuthor feeds: also return the author's replies to other posts
includeRepostsbooleanNotrueAuthor feeds: also return posts the author reposted
includeProfilesbooleanNofalseAlso return one profile row per handle
maxItemsintegerNo50Maximum posts per handle, per thread and for the search

Example:

{
"handles": ["bsky.app", "https://bsky.app/profile/pfrazee.com"],
"postUrls": ["https://bsky.app/profile/bsky.app/post/3mz4cvpstb22v"],
"includeProfiles": true,
"maxItems": 100
}

Output

One dataset row per post ("type": "post"). Real example (feed of bsky.app, run of 2 November 2026; this row is a repost by bsky.app of a post by avclub.com):

{
"type": "post",
"uri": "at://did:plc:kwxpje5qog6wwndagwbssatp/app.bsky.feed.post/3mviutosqmk2t",
"url": "https://bsky.app/profile/avclub.com/post/3mviutosqmk2t",
"cid": "bafyreigyzxfb3tynf6hus4cshhzcrwr7sht4vfp2l5phbbfephvn7bcd7a",
"authorHandle": "avclub.com",
"authorDisplayName": "The A.V. Club",
"authorDid": "did:plc:kwxpje5qog6wwndagwbssatp",
"text": "Less than 4 hours until the #Emmys kick off! You can keep up with all the commentary, winners, joy—and, let's face it, disappointment—via our Emmys Watch feed right here on @bsky.app. Pin it now so you don't miss a thing!\n\nbsky.app/profile/avcl...",
"createdAt": "2026-09-14T19:47:12.655Z",
"indexedAt": "2026-09-14T19:47:15.764Z",
"likeCount": 546,
"repostCount": 42,
"replyCount": 31,
"quoteCount": 4,
"langs": ["en"],
"replyParent": null,
"replyRoot": null,
"hashtags": ["Emmys"],
"mentions": ["bsky.app"],
"links": ["https://bsky.app/profile/avclub.com/feed/emmys-watch-r"],
"embedType": "images",
"images": [
{
"url": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:kwxpje5qog6wwndagwbssatp/bafkreicwxzp6lnqvuetiytyeanq3wynihsneq4qqdvv7bzhkrmw4nv36oy",
"alt": null
}
],
"videoUrl": null,
"externalUrl": null,
"externalTitle": null,
"quotedPostUri": null,
"isRepost": true,
"repostedBy": "bsky.app",
"source": "author:bsky.app",
"scrapedAt": "2026-11-02T22:24:50+00:00"
}
FieldNotes
uri, cidAT Protocol identifiers of the post; url is the same post on bsky.app
createdAtTime set by the author's app; indexedAt is when Bluesky indexed the post
hashtags, mentions, linksFrom the post's rich-text facets; links also contains the link card URL. Shortened links in text (bsky.app/profile/avcl...) are shown in full in links
embedTypeimages, video, external (link card), record (quote), recordWithMedia (quote with media), gallery, or null
imagesFull-size image URLs and alt texts (null when the author wrote none)
videoUrlHLS playlist (.m3u8) of an attached video
quotedPostUriat:// URI of the quoted post
replyParent, replyRootat:// URIs of the post replied to and of the first post of the thread; null for top-level posts
isRepost, repostedBySet when the row comes from a repost in an author feed; the author fields are those of the original post
sourceInput that produced the row: author:<handle>, thread:<url> or search:<query>

Profile rows ("type": "profile", only with includeProfiles) contain did, handle, url, displayName, description, followersCount, followsCount, postsCount, avatar, banner, createdAt, indexedAt and scrapedAt.

The dataset has two views: posts and profiles.

Pricing

Pay-per-event, no start fee: $0.77 per 1,000 posts (event POST) on the Apify Free plan, lower on paid plans. You only pay for results pushed to the dataset.

Apify planPrice per 1,000 posts
Free$0.77
Starter$0.65
Scale$0.58
Business$0.46
  • Additional event PROFILE (profile): $0.77 per 1,000 on the Free plan, $0.46 on Business. Charged only when that data is returned.

Set a maximum cost per run in the run options: the Actor stops cleanly when it is reached.

Limitations

  • Search returns at most 25 posts per run. Without login, Bluesky's search API serves the first page of results and refuses the next pages (HTTP 403). The Actor does not log in and does not split the search into date ranges to get around this. For more posts, scrape the authors' feeds or the threads.
  • Only public posts that the Bluesky AppView serves without login. Deleted posts and posts the AppView does not serve (blocked or removed by moderation) are not returned.
  • A thread is read in one request. For very large threads the AppView may not return every reply, and maxItems caps the rows per thread.
  • Counts (likes, reposts, replies, quotes, followers) are those of the moment of the run.
  • langs is what the author's app declared, and can be empty.
  • Likes, followers lists and direct messages are not included.