Bluesky API
The Bluesky API returns public social data from the AT Protocol network as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary profile endpoint returns a handle's DID, display name, description, follower, follows and posts counts and avatar, and you can pull an author_feed, search actors, a thread, post_detail, likes and reposts. It is built for social analytics and brand monitoring that need Bluesky data without a scraper. One ReefAPI key, one shared credit pool, the standard envelope.
Real request and response JSON
Captured from the indexed primary action, profile, on .
{
"method": "POST",
"url": "https://api.reefapi.com/bluesky/v1/profile",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"actor": "bsky.app"
}
}{
"ok": true,
"meta": {
"api": "bluesky",
"endpoint": "profile",
"mode": "live",
"latency_ms": 1389,
"record_count": 1,
"bytes": 1054,
"cache_hit": false,
"completeness_pct": 100
},
"data": {
"did": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"display_name": "Bluesky",
"description": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: [redacted-email]",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka",
"banner": "https://cdn.bsky.app/img/banner/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreichzyovokfzmymz36p5jibbjrhsur6n7hjnzxrpbt5jaydp2szvna",
"followers_count": 34151861,
"follows_count": 11,
"posts_count": 802,
"created_at": "[redacted-phone]T04:53:57.057Z",
"indexed_at": "[redacted-phone]T21:05:26.152Z",
"labels": [],
"verified": false,
"pinned_post": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l",
"associated": {
"feedgens": 7,
"lists": 16,
"starter_packs": 13,
"is_labeler": false
},
"url": "https://bsky.app/profile/bsky.app"
}
}What the Bluesky API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| profile | actor profile: did/handle/displayName/desc/followers/follows/posts counts/avatar/banner/labels (+ batch via 'actors' <=25). Requires actor OR actors (engine-enforced; required_params=() so the actors-only batch isn't rejected by the gateway literal-key validator). | Ops teams call profile to get actor profile. | actor, actors |
| author_feed | an actor's posts (full record+embed+counts), cursor-paginated; filter=posts_no_replies|posts_with_replies|posts_with_media|posts_and_author_threads | Developer tools call author_feed to get an actor's posts (full record+embed+counts), cursor-paginated; filter=posts_no_replies|posts_…. | actor, limit, filter, cursor |
| search_actors | search users by name/handle/bio (cursor); typeahead=true for fast suggest | Validation workflows call search_actors to search users by name/handle/bio (cursor); typeahead=true for fast suggest. | q, limit, cursor, typeahead |
| thread | a post + its reply tree (recursive) + parent | Data-quality teams call thread to get a post + its reply tree (recursive) + parent. | uri, depth, parent_height |
| post_detail | hydrate one or more posts by at:// URI (<=25): record/embed/like+repost+reply+quote counts | Ops teams call post_detail to get hydrate one or more posts by at:// URI (<=25). | uris |
| likes | actors who liked a post (cursor); cid auto-used if given | Developer tools call likes to get actors who liked a post (cursor); cid auto-used if given. | uri, cid, limit, cursor |
| reposts | actors who reposted a post (cursor) | Validation workflows call reposts to get actors who reposted a post (cursor). | uri, cid, limit, cursor |
| followers | actors following the subject (cursor) | Data-quality teams call followers to get actors following the subject (cursor). | actor, limit, cursor |
| follows | actors the subject follows (cursor) | Ops teams call follows to get actors the subject follows (cursor). | actor, limit, cursor |
| quotes | Accounts/posts that QUOTE a given post (quote-posts), cursor-paginated. The other half of a post's engagement alongside likes and reposts. | Developer tools call quotes to get accounts/posts that QUOTE a given post (quote-posts), cursor-paginated. | uri, cid, limit, cursor |
| suggested_follows | Accounts suggested from a given account — Bluesky's 'who to follow next' / similar-accounts set. Not paginated (a fixed suggestion set, ~10-50 actors). | Validation workflows call suggested_follows to get accounts suggested from a given account. | actor, limit |
| lists | The curated/moderation lists an account CREATED (user-curated lists + mute/block mod-lists), cursor-paginated. | Data-quality teams call lists to get the curated/moderation lists an account CREATED (user-curated lists + mute/block mod-lists),…. | actor, limit, cursor |
| list | A single list's metadata plus its MEMBERS (the accounts on the list), members cursor-paginated. | Ops teams call list to get a single list's metadata plus its MEMBERS (the accounts on the list), members cursor-paginated.. | list, limit, cursor |
| list_feed | The feed of posts authored by the members of a list (a list used as a custom timeline), cursor-paginated. | Developer tools call list_feed to get the feed of posts authored by the members of a list (a list used as a custom timeline), curso…. | list, limit, cursor |
| actor_feeds | The custom feed generators an account CREATED (its published feeds), cursor-paginated. | Validation workflows call actor_feeds to get the custom feed generators an account CREATED (its published feeds), cursor-paginated.. | actor, limit, cursor |
| feed_generator | One custom feed generator's metadata plus its live online/valid status (is the feed service up). | Data-quality teams call feed_generator to get one custom feed generator's metadata plus its live online/valid status (is the feed service up).. | feed |
| popular_feeds | Discover popular custom feed generators — pass `q` to search feeds by name/topic, or omit for the platform-wide popular list. Cursor-paginated. | Ops teams call popular_feeds to discover popular custom feed generators. | q, limit, cursor |
| get_feed | The posts served BY a custom feed generator (e.g. a Discover/What's-Hot/topic feed) by its at:// URI, cursor-paginated. Public — no account required. | Developer tools call get_feed to get the posts served BY a custom feed generator (e.g. | feed, limit, cursor |
| starter_packs | The starter packs an account CREATED (shareable onboarding bundles of accounts + feeds), cursor-paginated. | Validation workflows call starter_packs to get the starter packs an account CREATED (shareable onboarding bundles of accounts + feeds), curs…. | actor, limit, cursor |
| starter_pack | One starter pack's full detail: its underlying list, sample member profiles and any bundled feeds. | Data-quality teams call starter_pack to get one starter pack's full detail. | starter_pack |
| search_posts | Search Bluesky posts by keyword or hashtag — filter by sort order, date range, author, language, domain or tag. Requires an app-password; returns a clear error if none is configured. | Ops teams call search_posts to search Bluesky posts by keyword or hashtag. | q, sort, limit, cursor, since, ... |
| get_actor_likes | posts an actor liked (authed; the AppView serves the authenticated account's own likes). Defaults to the logged-in handle. | Developer tools call get_actor_likes to get posts an actor liked (authed; the AppView serves the authenticated account's own likes). | actor, limit, cursor |
| timeline | the authenticated account's home timeline (authed) | Validation workflows call timeline to get the authenticated account's home timeline (authed). | limit, cursor, algorithm |
Call profile from your stack
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"])const res = await fetch("https://api.reefapi.com/bluesky/v1/profile", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"actor": "bsky.app"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.bluesky.profile with {"actor":"bsky.app"}.Who uses this API and why
- 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.
Questions developers ask before integrating
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.
Is the Bluesky API a Bluesky scraper?
It is the managed alternative to a DIY Bluesky scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same profiles, posts, followers and the social graph back as clean JSON.
Why does my Bluesky scraper keep getting blocked?
Most Bluesky scrapers break on anti-bot defenses, rate limits and IP bans that need rotating residential proxies and browser fingerprinting to clear. ReefAPI handles all of that for you — no proxies, no captchas, no maintenance — and returns live JSON. Blocked or failed calls are free.