Get Bluesky data with one API
The Bluesky API returns public social data from the AT Protocol network as clean JSON.
23 active endpoints. Every call is 1 credit.
- POST/bluesky/v1/profile
- POST/bluesky/v1/author_feed
- POST/bluesky/v1/search_actors
- POST/bluesky/v1/thread
- POST/bluesky/v1/post_detail
- POST/bluesky/v1/likes
- POST/bluesky/v1/reposts
- +16 more
What Bluesky endpoints does ReefAPI ship?
23 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Bluesky API
3 of 23 endpoints, ready to run
actor profile.
// Press "Try it" and this pane shows exactly what the // live site returned this second — including an empty // result, if that is the truth. No key, no account.
How the Bluesky API works
Bluesky is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 185 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
AT Protocol identifiers: DID, handle, at:// URI, rkey and CID
Bluesky has two names for an account and a URI for everything else, and the difference matters because one of them is permanent and the other is not. Every value below was returned by a live read of the bsky.app account and its pinned post on 2026-08-27.
| Identifier | Measured shape | What it is for |
|---|---|---|
| DID | did:plc:z72i7hdynmk6r22z27h6tvur | The account's permanent id. Store this, not the handle. The actor parameter accepts it, a handle, or a bsky.app/profile/... URL, and all three returned the identical profile |
| handle | bsky.app | A domain name the owner controls. It can be changed or reassigned, so it is a display value, not a key |
| post uri | at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l | The primary key for thread, likes, reposts, quotes and post_detail |
| rkey | 3l6oveex3ii2l | The last segment of the URI, and also the last segment of the bsky.app share URL, so you can rebuild the URI from a link plus the author DID |
| cid | bafyreicnt42y6vo6pfpvyro234ac4o6ijug6adwwrh7awflgrqlt4zibxq | A content hash of that exact version of the post. Optional on likes, reposts and quotes, where it skips a resolve step |
| cursor | 2026-08-21T18:45:43.613Z | Pagination on author_feed comes back as an ISO timestamp, not an opaque token. Pass it straight back as cursor |
| unknown handle | NOT_FOUND, retryable false | A handle that does not resolve is a hard error with detail.context app.bsky.actor.getProfile, not an empty result |
profile has two modes. One actor returns the profile object at the top level; up to 25 actors returns data.profiles[] with a count and meta.batch true. Note also that a post's author block is thinner than the profile action's output: description and indexed_at come back null inside a post even for accounts that have both.
What people build with Bluesky
The jobs this data is most often used for.
endpoints
credit per call
Social analytics call profile and author_feed to measure a handle's reach.
Brand monitoring uses search_actors and thread to track mentions.
Research uses likes and reposts to gauge engagement.
What Bluesky data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 185 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/bluesky/v1/profile \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"actor":"bsky.app"}'import requests
r = requests.post(
"https://api.reefapi.com/bluesky/v1/profile",
headers={"x-api-key": REEF_KEY},
json={
"actor": "bsky.app"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Bluesky.
Get a free key →Should I key my records on the Bluesky handle or the DID?▾
The DID. A handle is a domain the account owner controls and can change; the did:plc identifier never moves. On 2026-08-27, actor bsky.app and actor did:plc:z72i7hdynmk6r22z27h6tvur returned the same profile field for field, so you lose nothing by resolving to the DID once and storing that.
Why does author_feed return posts written by other accounts?▾
Because reposts are part of an author's feed. A live author_feed read for bsky.app returned three posts, one of which had author.handle pfrazee.com and author.did did:plc:ragtjsm2j2vknwkz3zp4oxrd. The filter parameter controls replies and media, not reposts, so if you only want the account's own writing, compare each post's author.did to the subject's DID and drop the ones that differ.
Which engagement counts come back on a post?▾
Five, all as integers on every post object: like_count, repost_count, reply_count, quote_count and bookmark_count. One measured post carried 5,144 likes, 1,224 reposts, 235 replies, 519 quotes and 288 bookmarks. bookmark_count is worth knowing about because the Bluesky web interface does not display it anywhere.
Why does thread return far fewer replies than reply_count claims?▾
reply_count is the post's lifetime counter and the tree is what the network will serve right now. A live thread call on the bsky.app pinned post returned reply_total 159 while the root post's own reply_count read 8,569. Deleted accounts, blocked authors and replies deeper than your depth setting all drop out of the tree but stay in the counter. Raise depth, which accepts 0 to 100, to recover the deeper levels; nothing will recover the deleted ones.
What does the verified field mean, and why is it sometimes null?▾
It is tri-state. jay.bsky.team returned verified true, the official bsky.app account returned false, and authors embedded inside a quoted post returned null. Null means the check was not evaluated in that context rather than that the account failed it, so treat only an explicit true as verification and never read null as false.
What is the associated block on a profile?▾
A count of the things that account publishes. bsky.app returned associated with feedgens 7, lists 17, starter_packs 14 and is_labeler false. Use it as a cheap check before spending a call: if feedgens is 0 there is no point calling actor_feeds, and is_labeler tells you whether the account issues moderation labels.
Can I look up several accounts in one call?▾
Yes. Pass actors with up to 25 handles or DIDs instead of a single actor, and the response shape changes to data.profiles[] plus a count, with meta.batch true. A measured two-actor batch returned both full profiles including followers_count, associated and pinned_post. pinned_post is an at:// URI when one is set and null when it is not.
What comes back for a handle that does not exist?▾
A clean failure, not an empty object. profile for a made-up handle returned ok false with error.code NOT_FOUND, retryable false, and detail.context app.bsky.actor.getProfile. Because retryable is false, do not put that call in a retry loop; the handle is simply not on the network.
What is the Bluesky API?▾
Bluesky API is a ReefAPI endpoint group for profiles, posts, followers and the social graph. It returns live JSON through POST requests under /bluesky/v1.
Is the Bluesky API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Bluesky calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Bluesky login or account?▾
No login to Bluesky is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Bluesky data?▾
The page example is captured from a live profile call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Bluesky API use?▾
Bluesky actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Bluesky from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call bluesky actions with the same key, credit pool and JSON envelope used by normal REST requests.
10 Social Media APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Bluesky, you are one call away from the rest of the category — no second contract, no second integration.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 184 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts.