Bluesky Scraper —  (No Login) avatar

Bluesky Scraper — (No Login)

Pricing

from $3.00 / 1,000 results

Go to Apify Store
Bluesky Scraper —  (No Login)

Bluesky Scraper — (No Login)

Scrape public Bluesky data via the AT Protocol: profiles, posts, followers, following, search, threads, lists, starter packs and custom feeds. No account or app password required.

Pricing

from $3.00 / 1,000 results

Rating

0.0

(0)

Developer

DataPulse Lab

DataPulse Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Categories

Share

Bluesky Scraper — Profiles, Posts, Followers & More (No Login)

Extract public data from Bluesky through the official AT Protocol AppView — without an account, an app password, or a session token.

Most Bluesky scrapers ask you to hand over your own credentials, which puts your account at risk of rate limits or suspension. This one talks to public.api.bsky.app, the read-only endpoint Bluesky serves to anonymous clients. Nothing to log in with, nothing to leak.


11 scraping modes

#ModeWhat you getNeeds
1profilesDisplay name, bio, followers/following/posts counts, verification, avatar, banner, join date, pinned posthandles
2postsAuthor timeline with likes, reposts, replies, quotes, images, video, links, hashtags, mentionshandles
3followersEveryone following an account, with full profile metadatahandles
4followingEveryone an account followshandles
5searchPeopleAccounts matching a keywordsearchQuery
6searchPostsPosts matching a keyword, with date/language/sort filterssearchQuery
7postUrlsSpecific posts from their bsky.app links (handle → DID resolved automatically)urls
8threadFull conversation: ancestors above the post and a nested reply tree belowurls
9listsPublic lists and, optionally, every memberhandles or urls
10starterPacksStarter packs, their join counts, feeds and membershandles or urls
11feedsCustom feed generators and the posts they currently servehandles or urls

Every run also produces a flattened CSV export (OUTPUT.csv in the run's key-value store) alongside the JSON dataset.


Quick start

Press Start with the default input — it scrapes the @bsky.app profile and finishes in seconds.

Then adapt one of these:

// Latest 200 posts from an account
{ "mode": "posts", "handles": ["bsky.app"], "maxItems": 200 }
// Followers of several accounts, capped per account
{ "mode": "followers", "handles": ["bsky.app", "jay.bsky.team"],
"maxItems": 5000, "maxItemsPerSource": 2500 }
// French posts about a topic, most engaged first
{ "mode": "searchPosts", "searchQuery": "intelligence artificielle",
"searchSort": "top", "searchLanguage": "fr", "maxItems": 500 }
// An entire conversation under one post
{ "mode": "thread",
"urls": ["https://bsky.app/profile/bsky.app/post/3lkxyzabc123"],
"threadDepth": 10 }

Handles are flexible: bsky.app, @bsky.app, did:plc:z72i7… and https://bsky.app/profile/bsky.app all work.


Input reference

FieldTypeDefaultNotes
modeenumprofilesOne of the 11 modes above
handlesarray["bsky.app"]Handles, DIDs or profile URLs
searchQuerystringSupports Bluesky search syntax: from:handle, "exact phrase", #hashtag
searchSortenumlatestlatest or top (mode 6)
searchSince / searchUntilstringYYYY-MM-DD date bounds (mode 6)
searchLanguagestringTwo-letter code, e.g. fr (mode 6)
urlsarrayPost / list / feed / starter-pack links or at:// URIs
maxItemsinteger50Total cap. 0 means unlimited
maxItemsPerSourceintegerSub-cap so one large account can't eat the budget
includeRepliesbooleantrueModes 2 and 6
includeRepostsbooleantrueMode 2
includeListMembersbooleantrueModes 9 and 10
threadDepthinteger6Reply levels to walk down (mode 8)
threadParentHeightinteger10Parent posts to fetch above the target (mode 8)
exportCsvbooleantrueAlso write OUTPUT.csv
proxyConfigurationobjectoffNot needed — the public API has no IP restrictions

Output samples

Profile

{
"type": "profile",
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"displayName": "Bluesky",
"description": "Official Bluesky account.",
"followersCount": 4512003,
"followsCount": 42,
"postsCount": 1337,
"createdAt": "2023-04-12T04:53:57.057Z",
"isVerified": true,
"avatar": "https://cdn.bsky.app/img/avatar/plain/…@jpeg",
"banner": "https://cdn.bsky.app/img/banner/plain/…@jpeg",
"profileUrl": "https://bsky.app/profile/bsky.app"
}

Post

{
"type": "post",
"uri": "at://did:plc:z72i7…/app.bsky.feed.post/3lkxyzabc123",
"url": "https://bsky.app/profile/bsky.app/post/3lkxyzabc123",
"text": "Big update shipping today #bluesky #atproto",
"createdAt": "2026-05-01T12:00:00.000Z",
"authorHandle": "bsky.app",
"likeCount": 5231,
"repostCount": 940,
"replyCount": 128,
"quoteCount": 77,
"engagementTotal": 6376,
"hashtags": ["bluesky", "atproto"],
"mentions": [{ "did": "did:plc:…", "handle": "alice.bsky.social" }],
"links": ["https://bsky.social/about"],
"images": [{ "url": "…", "alt": "Screenshot", "width": 1200, "height": 675 }],
"isReply": false,
"isRepost": false,
"isQuotePost": false
}

In thread mode each item carries depth, parentUri and a nested replies array, so you can work with the flat list or rebuild the tree.


Pricing

Pay per result — $0.003 per item. You pay only for records actually delivered to your dataset. No monthly platform fee on top, no charge for failed runs.

JobItemsCost
One profile1$0.003
1,000 posts from an account1,000$3.00
10,000 followers10,000$30.00

Set maxItems to keep any run inside a known budget.


Notes & limits

  • Public data only. Anything requiring a session — DMs, notifications, your own feed, blocked/muted lists — is out of scope by design.
  • Custom feeds (mode 11). Feed metadata always works anonymously. A few third-party generators refuse unauthenticated reads; when that happens the Actor still returns the generator record and logs a warning instead of failing.
  • Deleted or suspended accounts are skipped with a warning rather than aborting the run.
  • Rate limits are handled with retry-after-aware backoff. The public API is generous; a proxy is rarely necessary.
  • Please respect Bluesky's Terms of Service and applicable data-protection law (GDPR included) when scraping personal data.

Local development

pip install -r requirements.txt
# Offline suite: 56 tests, all 11 modes against a mocked AppView
python3 -m pytest tests/ -v
# Live check against the real API (no credentials required)
python3 tests/live_smoke.py
# Run the Actor locally
apify run --input='{"mode":"profiles","handles":["bsky.app"]}'

Project structure

.actor/
actor.json Actor manifest
input_schema.json Input form definition
dataset_schema.json Dataset views in the Apify UI
pay_per_event.json Pay-per-event tariff
src/
__main__.py Entry point (python -m src)
main.py Orchestration, batching, charging, CSV export
config.py Input normalisation and validation
bsky_client.py AT Protocol client (retries, pagination, DID cache)
handlers.py One handler per scraping mode
transformers.py Raw AT Proto views -> flat output records
parsers.py URL/AT-URI parsing, richtext facets, embeds
csv_export.py Nested JSON -> CSV flattening
tests/
test_offline.py Unit + mode tests
test_actor_e2e.py Full Actor run through the Apify SDK
live_smoke.py Real-API smoke test
Dockerfile
requirements.txt