Bluesky Scraper — (No Login)
Pricing
from $3.00 / 1,000 results
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
Maintained by CommunityActor 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
| # | Mode | What you get | Needs |
|---|---|---|---|
| 1 | profiles | Display name, bio, followers/following/posts counts, verification, avatar, banner, join date, pinned post | handles |
| 2 | posts | Author timeline with likes, reposts, replies, quotes, images, video, links, hashtags, mentions | handles |
| 3 | followers | Everyone following an account, with full profile metadata | handles |
| 4 | following | Everyone an account follows | handles |
| 5 | searchPeople | Accounts matching a keyword | searchQuery |
| 6 | searchPosts | Posts matching a keyword, with date/language/sort filters | searchQuery |
| 7 | postUrls | Specific posts from their bsky.app links (handle → DID resolved automatically) | urls |
| 8 | thread | Full conversation: ancestors above the post and a nested reply tree below | urls |
| 9 | lists | Public lists and, optionally, every member | handles or urls |
| 10 | starterPacks | Starter packs, their join counts, feeds and members | handles or urls |
| 11 | feeds | Custom feed generators and the posts they currently serve | handles 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
| Field | Type | Default | Notes |
|---|---|---|---|
mode | enum | profiles | One of the 11 modes above |
handles | array | ["bsky.app"] | Handles, DIDs or profile URLs |
searchQuery | string | — | Supports Bluesky search syntax: from:handle, "exact phrase", #hashtag |
searchSort | enum | latest | latest or top (mode 6) |
searchSince / searchUntil | string | — | YYYY-MM-DD date bounds (mode 6) |
searchLanguage | string | — | Two-letter code, e.g. fr (mode 6) |
urls | array | — | Post / list / feed / starter-pack links or at:// URIs |
maxItems | integer | 50 | Total cap. 0 means unlimited |
maxItemsPerSource | integer | — | Sub-cap so one large account can't eat the budget |
includeReplies | boolean | true | Modes 2 and 6 |
includeReposts | boolean | true | Mode 2 |
includeListMembers | boolean | true | Modes 9 and 10 |
threadDepth | integer | 6 | Reply levels to walk down (mode 8) |
threadParentHeight | integer | 10 | Parent posts to fetch above the target (mode 8) |
exportCsv | boolean | true | Also write OUTPUT.csv |
proxyConfiguration | object | off | Not 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.
| Job | Items | Cost |
|---|---|---|
| One profile | 1 | $0.003 |
| 1,000 posts from an account | 1,000 | $3.00 |
| 10,000 followers | 10,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 AppViewpython3 -m pytest tests/ -v# Live check against the real API (no credentials required)python3 tests/live_smoke.py# Run the Actor locallyapify run --input='{"mode":"profiles","handles":["bsky.app"]}'
Project structure
.actor/actor.json Actor manifestinput_schema.json Input form definitiondataset_schema.json Dataset views in the Apify UIpay_per_event.json Pay-per-event tariffsrc/__main__.py Entry point (python -m src)main.py Orchestration, batching, charging, CSV exportconfig.py Input normalisation and validationbsky_client.py AT Protocol client (retries, pagination, DID cache)handlers.py One handler per scraping modetransformers.py Raw AT Proto views -> flat output recordsparsers.py URL/AT-URI parsing, richtext facets, embedscsv_export.py Nested JSON -> CSV flatteningtests/test_offline.py Unit + mode teststest_actor_e2e.py Full Actor run through the Apify SDKlive_smoke.py Real-API smoke testDockerfilerequirements.txt