Bluesky Feed Posts Scraper avatar

Bluesky Feed Posts Scraper

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Bluesky Feed Posts Scraper

Bluesky Feed Posts Scraper

Collect public posts from Bluesky custom feeds and curated list feeds. Export text, authors, engagement, dates and media with cursor pagination.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

ScrapingMonkey

ScrapingMonkey

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Collect public publications from Bluesky custom feeds and curated list feeds. Bluesky Feed Posts Scraper accepts feed or list URLs and exports one post per row with text, authors, dates, engagement, media and source-feed context.

Start from a feed you already follow or a public list to create repeatable topic datasets, editorial samples and source-linked content archives.

At a glanceDetails
📥 InputAdd canonical bsky.app/profile/handle/feed/key or bsky.app/profile/handle/lists/key HTTPS URLs, or matching at:// feed or list URIs.
📤 OutputOne unique publication per source feed or list
📄 PaginationUp to 30 source items per requested page
🔐 Login requiredNo
⚡ ProcessingUp to 5 HTTP requests concurrently; up to 5 attempts for temporary failures
💾 DeliveryOne Apify dataset view with individual result rows, flattened object columns and complete nested JSON

What the Bluesky feed posts scraper collects 📰

The Actor recognizes custom feed and list-feed record types from your input and uses the corresponding public website request. Both sources produce the same post schema and the same dataset table.

Data can include:

  • Post identifiers, canonical link, text, publication and indexing dates
  • Visible engagement counts and author profiles
  • Images, video playlist and thumbnail links, quoted content and external link previews
  • Languages, hashtags, mentions, links and reply references
  • Source type, URI, URL, name, description and creator where exposed
  • Pinned and repost context supplied by the feed
SourceInputResultBest for
Custom feed inputA /feed/ URL or feed URIPosts selected by that feedTopic or discovery feed research
List inputA /lists/ URL or list URIPosts exposed by the list feedA selected account-group feed

How to collect feed posts from Bluesky 🚀

  1. Enter one or more supported inputs.
  2. Choose a mode if available and set the page count for each input.
  3. Start the Actor.
  4. Open the Posts dataset view and review individual result rows.
  5. Export the dataset or retrieve it from your application.
{
"inputList": [
"https://bsky.app/profile/bsky.app/feed/whats-hot"
],
"pagesPerFeed": 1
}

pagesPerFeed counts result pages independently for each feed or list. Each page requests up to 30 posts. Feed and list URLs can be mixed in one input list; the source type is detected from each record.

Bluesky feed posts output fields 📦

FieldTypeMeaning
inputstringOriginal submitted input, retained on success and failure.
statusstringsuccess or failed.
uristring or nullStable AT publication URI.
cidstring or nullContent identifier for this version of the post.
post_urlstring or nullCanonical URL of the returned publication.
textstring or nullPublication text.
created_atstring or nullCreation or publication time returned by the source.
indexed_atstring or nullTime the source indexed the record.
like_countinteger or nullVisible likes on the returned publication.
repost_countinteger or nullVisible repost count.
reply_countinteger or nullVisible reply count; replies themselves are not expanded.
quote_countinteger or nullVisible quote count.
bookmark_countinteger or nullBookmark count only when exposed.
authorobject or nullAuthor profile fields.
languagesarray or nullLanguage tags supplied in the post record.
hashtagsarray or nullHashtags extracted from record tags and facets.
mentioned_didsarray or nullMentioned account identifiers from text facets.
linksarray or nullLink targets from text facets.
reply_parent_uristring or nullDirect parent publication URI when this is a reply.
reply_root_uristring or nullRoot publication URI when this is a reply.
labelsarray or nullSource label values.
imagesarray or nullOrdered image metadata: fullsize and thumbnail URLs, alt text and dimensions.
videoobject or nullVideo playlist URL, thumbnail, content identifier, alt text and dimensions.
externalobject or nullExternal link preview URL, title, description and thumbnail.
quoteobject or nullEmbedded quoted-record reference, availability and exposed content.
is_pinnedboolean or nullWhether the feed response marks this entry as pinned.
is_repostboolean or nullWhether the feed entry is a repost.
reposted_atstring or nullFeed-entry repost time when supplied.
reposted_byobject or nullReposting profile when supplied by a feed entry.
source_typestring or nullWhether the source is a custom feed or list feed.
source_uristring or nullSource feed or list URI.
source_urlstring or nullCanonical source feed or list URL.
source_namestring or nullSource feed or list name.
source_descriptionstring or nullSource feed or list description.
source_creatorobject or nullSource creator profile when exposed.

Nested objects keep the following fields. They appear as flattened columns in the single Store view; arrays stay together in their parent row:

  • author: did, handle, display_name, profile_url, description, avatar_url, banner_url, pronouns, created_at, indexed_at, followers_count, following_count, posts_count, verified_status, trusted_verifier_status, labels.
  • images[]: fullsize_url, thumbnail_url, alt, width, height.
  • video: playlist_url, thumbnail_url, cid, alt, width, height.
  • external: url, title, description, thumbnail_url.
  • quote: uri, cid, post_url, text, created_at, author, available.
  • quote.author: did, handle, display_name, profile_url, description, avatar_url, banner_url, pronouns, created_at, indexed_at, followers_count, following_count, posts_count, verified_status, trusted_verifier_status, labels.
  • reposted_by: did, handle, display_name, profile_url, description, avatar_url, banner_url, pronouns, created_at, indexed_at, followers_count, following_count, posts_count, verified_status, trusted_verifier_status, labels.
  • source_creator: did, handle, display_name, profile_url, description, avatar_url, banner_url, pronouns, created_at, indexed_at, followers_count, following_count, posts_count, verified_status, trusted_verifier_status, labels.

The successful examples below use normalized public response data. Values are snapshots rather than promises of current content or counts; every top-level output key is included.

Complete representative successful result:

{
"input": "https://bsky.app/profile/bsky.app/feed/whats-hot",
"status": "success",
"source_type": "feed",
"source_uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot",
"source_url": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot",
"source_name": "Discover",
"source_description": "Trending content from your personal network",
"source_creator": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"profile_url": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur",
"labels": [],
"verified_status": "none",
"trusted_verifier_status": "valid",
"display_name": "Bluesky",
"description": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app",
"avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka",
"banner_url": null,
"pronouns": null,
"created_at": "2023-04-12T04:53:57.057Z",
"indexed_at": "2025-10-27T21:05:26.152Z",
"followers_count": null,
"following_count": null,
"posts_count": null
},
"uri": "at://did:plc:u2zs2typsklaohqmfyxiunvy/app.bsky.feed.post/3mv7syp7klc2z",
"cid": "bafyreidw47rbcsrsps3osliklpcvjhtdlbkpikpuvtq4u2hm6mls553feq",
"post_url": "https://bsky.app/profile/did:plc:u2zs2typsklaohqmfyxiunvy/post/3mv7syp7klc2z",
"text": "Fucketyfucketyfuckfuckfuck´ by Annie Taylor from PEG - the Profanity Embroidery Group, Whitstable, UK, known for their stitching and swearing #WomensArt #FridayFeeling",
"created_at": "2026-09-11T05:20:15.709Z",
"indexed_at": "2026-09-11T05:20:17.963Z",
"author": {
"did": "did:plc:u2zs2typsklaohqmfyxiunvy",
"handle": "womensartbluesky.bsky.social",
"profile_url": "https://bsky.app/profile/did:plc:u2zs2typsklaohqmfyxiunvy",
"labels": [],
"verified_status": null,
"trusted_verifier_status": null,
"display_name": null,
"description": null,
"avatar_url": "https://cdn.bsky.app/img/avatar/plain/did:plc:u2zs2typsklaohqmfyxiunvy/bafkreibjaljsx6h2jl264yss2bp3ji4zamzrvkskfhkz6hjni2ydietjvy",
"banner_url": null,
"pronouns": null,
"created_at": "2024-11-12T10:01:39.805Z",
"indexed_at": null,
"followers_count": null,
"following_count": null,
"posts_count": null
},
"languages": [
"en"
],
"hashtags": [
"WomensArt",
"FridayFeeling"
],
"mentioned_dids": [],
"links": [],
"labels": [],
"reply_parent_uri": null,
"reply_root_uri": null,
"is_pinned": false,
"is_repost": false,
"reposted_at": null,
"reposted_by": null,
"images": [
{
"fullsize_url": "https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:u2zs2typsklaohqmfyxiunvy/bafkreicmchueabpkrhi7hgfwb7oekjzhjivkbuayekovc7ppo2xc5jccke",
"thumbnail_url": "https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:u2zs2typsklaohqmfyxiunvy/bafkreicmchueabpkrhi7hgfwb7oekjzhjivkbuayekovc7ppo2xc5jccke",
"alt": "Embroidery featuring two perched cute blue birds among pink flowers surrounded by the embroidered text of the title",
"width": 879,
"height": 827
}
],
"video": null,
"external": null,
"quote": null,
"like_count": 613,
"repost_count": 139,
"reply_count": 5,
"quote_count": 8,
"bookmark_count": 21
}

Complete failed dataset item:

{
"input": " ",
"status": "failed",
"uri": null,
"cid": null,
"post_url": null,
"text": null,
"created_at": null,
"indexed_at": null,
"like_count": null,
"repost_count": null,
"reply_count": null,
"quote_count": null,
"bookmark_count": null,
"author": null,
"languages": null,
"hashtags": null,
"mentioned_dids": null,
"links": null,
"reply_parent_uri": null,
"reply_root_uri": null,
"labels": null,
"images": null,
"video": null,
"external": null,
"quote": null,
"is_pinned": null,
"is_repost": null,
"reposted_at": null,
"reposted_by": null,
"source_type": null,
"source_uri": null,
"source_url": null,
"source_name": null,
"source_description": null,
"source_creator": null
}

Each failed row preserves input, uses status: failed, and sets every other top-level field to null. The reason is written to the run log. Successful rows may contain null optional fields or empty arrays when the source does not supply a value. The dataset is not split into separate tables for media, authors, modes or failures.

Input and pagination settings ⚙️

ParameterTypeRequiredDefaultRules
inputListarray of stringsYesNoneAdd canonical bsky.app/profile/handle/feed/key or bsky.app/profile/handle/lists/key HTTPS URLs, or matching at:// feed or list URIs.
pagesPerFeedintegerNo1Number of result pages to attempt per input. Each page requests up to 30 items; actual public rows can be fewer. Bootstrap requests do not count as pages. Stops when the cursor ends or repeats. Minimum 1.

Accept https://bsky.app/profile/ACCOUNT/feed/KEY and https://bsky.app/profile/ACCOUNT/lists/KEY, or at:// URIs using app.bsky.feed.generator or app.bsky.graph.list. A home-page URL, profile URL, starter-pack URL or keyword is not a feed input.

For supported website URLs, use the exact https://bsky.app host and canonical path without a query string or fragment. URLs from other hosts and unsupported record types are rejected. Handles are normalized; duplicate normalized inputs in the same mode are processed once. Different source inputs retain their own results, while repeated record identifiers within one input’s pagination are removed.

The first result request counts as page 1; resolving a handle or validating source metadata does not consume a result page. Pagination stops at the requested page count, a missing cursor or a repeated cursor. A short, empty or fully filtered page can still continue when it includes a usable next cursor. No exact result total is guaranteed.

Bluesky feed posts use cases 🎯

Topic-feed research

Collect a selected custom feed and inspect returned text, authors and media. Treat its selection as the feed operator’s result set rather than a complete topic archive.

Editorial source monitoring

Use public list feeds to collect posts from a selected account group. Preserve source metadata while combining outputs in an editorial database.

Feed comparisons

Submit several feed or list inputs and compare their returned publications using post URIs. A post found in two source feeds stays associated with both sources.

Pricing and saved-result behavior 💰

See the Actor’s Pricing tab for the active charging model and current rate. Store settings are separate from this local implementation, so this README does not state an unverified fixed price or runtime.

Under dataset-item pricing:

  • Every unique record saved as success is one result for that source input. Nested author, media or profile fields do not become separate rows.
  • An invalid or unavailable input, an exhausted temporary failure, or an input with no publicly available results within its page budget can save one failed row.
  • Automatic retry attempts do not create extra dataset rows by themselves.
  • A normal empty continuation after earlier successes creates no extra result row.
  • More requested pages can produce more saved rows. Check the active listing for how saved failed rows are billed; they are not assumed to be free.

The final total depends on source availability, duplicate removal and the chosen page budget. Start with a small run and check its actual usage before selecting a larger budget.

Bluesky feed posts API 🔌

Replace $ACTOR_ID with the identifier from this Actor’s API tab and $APIFY_TOKEN with your Apify token.

curl -X POST "https://api.apify.com/v2/acts/$ACTOR_ID/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"inputList":["https://bsky.app/profile/bsky.app/feed/whats-hot"],"pagesPerFeed":1}'

Retrieve the default dataset through the Apify API or download JSON, CSV, Excel, XML and other formats available in the Console. Schedules, completion webhooks and Apify integrations can connect results to Google Sheets, Make, Zapier, n8n, cloud storage or your own backend. These are platform connection options, not integrations preconfigured by this Actor.

Reliability, retries, and public-data limits ⚠️

The Actor uses pure HTTP collection with up to five requests concurrently. It does not launch a browser. Invalid syntax and confirmed missing, removed or inaccessible targets stop without unnecessary retries. Temporary network and proxy failures, timeouts, blocks, malformed responses, throttling and server errors are retried up to five total attempts.

Earlier successful pages remain saved if a later page fails. If no publicly available rows are found before the source ends or the selected page budget is reached, one failed row records that input; this does not mean the underlying account or collection necessarily does not exist. A later empty page after successes is normal exhaustion. A later request that exhausts retries can append a failed row while preserving earlier results.

Bluesky controls public availability and returned fields. Objects restricted from unauthenticated viewing are excluded; a restricted target produces a failed row. Deleted, suspended, unavailable or otherwise restricted records may be missing. Optional counts are not inferred from an incomplete sample, and media links may change or expire.

Custom feed operators control selection, ranking, availability and whether anonymous access works. A feed can return fewer posts, change order or go offline. A list-feed input returns posts, not list members. The Actor does not search arbitrary post keywords.

Three consecutive result pages were verified for every paginated mode in HTTP runs of the packaged Actor on September 11, 2026. These checks demonstrate working continuation on the tested sources and do not guarantee future source availability.

One invalid string inside an otherwise valid input list does not stop other inputs. A configuration that fails the input schema logs an input warning and exits without starting requests: for example, a list containing a number instead of a string, an unsupported mode or an invalid page-count type. Infrastructure failures such as startup errors, unavailable dataset storage or an unrecoverable result-save error can still stop the whole run. Result-save failures are not retried as fresh scraping requests.

Frequently asked questions ❓

Can I mix feeds and lists?

Yes. The Actor identifies each input’s record type and stores all resulting publications in the same dataset view.

Does a list input export the list members?

No. It returns the publications in that list’s feed. Starter-pack member export is available in Bluesky Starter Pack Scraper.

Can I search posts by keyword?

No. Supply an existing feed or list URL. The Actor does not offer unrestricted post search.

Does it require Bluesky login or cookies?

No Bluesky login, password, session cookie or account token is accepted or required. The Actor uses HTTP requests used by the public website and respects restrictions on unauthenticated access.

What happens to invalid or unavailable inputs?

Invalid individual inputs are saved as failed rows without an HTTP request. Confirmed missing, removed or restricted targets also become failed rows without unnecessary retries. Temporary failures are retried up to five total attempts. Other inputs and already saved pages remain available.

Can I export results or automate collection?

Yes. Use the Apify dataset to download JSON, CSV, Excel, XML or other supported formats, or retrieve records through its API. Apify schedules and webhooks can connect repeated runs to your own workflow.

For a reproducible problem, open an issue in the Actor’s Issues tab. Include the run ID, approximate time, mode if relevant, page count, safe public input, expected result and actual result. Do not share access tokens, proxy credentials or other secrets.

Use public data responsibly and follow applicable privacy, copyright, contractual and platform requirements before storing, combining or redistributing collected information.