BYTETOOLS

Bluesky Public API

Free Bluesky public API with no key: profiles, posts, followers and feeds from the AT Protocol network. No authentication for public data. Tested example.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-19

What is the Bluesky Public API?

The Bluesky public API is a free, key-free interface to public AT Protocol data — user profiles, posts, follower counts and feeds — available without authentication through the public AppView endpoint.

Bluesky exposes public data through public.api.bsky.app with no authentication at all, which is unusual among modern social platforms. Profiles, post threads, follower lists and feeds are all readable anonymously.

Identity works differently here and is worth understanding: every account has a permanent DID (decentralised identifier) alongside its changeable handle. Store the DID, not the handle — users can change handles or move providers, and the DID is what stays stable.

Quick facts

Base URL
https://public.api.bsky.app/xrpc
Authentication
Public AppView endpoints need no auth. Posting and reading private data require an authenticated session.
Rate limit
Roughly 3,000 requests per 5 minutes per IP on the public AppView.
Pricing
Free and open protocol.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the Bluesky Public API

Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.

1. Fetch a public Bluesky profile

GET https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=bsky.app

curl
curl 'https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=bsky.app'
JavaScript (fetch)
const res = await fetch("https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=bsky.app");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=bsky.app", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200
{
  "did": "did:plc:z72i7hdynmk6r22z27h6tvur",
  "handle": "bsky.app",
  "displayName": "Bluesky",
  "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka",
  "associated": {
    "lists": 17,
    "feedgens": 7,
    "starterPacks": 14,
    "labeler": false,
    "chat": {
      "allowIncoming": "none"
    },
    "activitySubscription": {
      "allowSubscriptions": "followers"
    }
  },
  "labels": [],
  "createdAt": "2023-04-12T04:53:57.057Z",
  "verification": {
    "verifications": [],
    "verifiedStatus": "none",
    "trustedVerifierStatus": "valid"
  },
  "description": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: support@bsky.app",
  "indexedAt": "2025-10-27T21:05:26.152Z",
  "banner": "https://cdn.bsky.app/img/banner/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreichzyovokfzmymz36p5jibbjrhsur6n7hjnzxrpbt5jaydp2szvna",
  "followersCount": 34585239,
  "followsCount": 11,
  "postsCount": 808,
  "pinnedPost": {
    "cid": "bafyreicnt42y6vo6pfpvyro234ac4o6ijug6adwwrh7awflgrqlt4zibxq",
    "uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l"
  }
}

Parameters

ParameterTypeRequiredDescription
actorstringRequiredHandle or DID of the account. bsky.app
app.bsky.actor.getProfilepathOptionalProfile endpoint. app.bsky.actor.getProfile
app.bsky.feed.getAuthorFeedpathOptionalA user's posts. app.bsky.feed.getAuthorFeed
limitintegerOptionalResults per page on feed endpoints. 50
cursorstringOptionalPagination cursor from the previous response. abc123

Response fields

didstring
Permanent decentralised identifier — store this, not the handle.
handlestring
Current handle, which the user can change.
displayNamestring
Display name.
avatar / bannerstring
Profile image URLs.
followersCount / followsCount / postsCountinteger
Public engagement counts.
descriptionstring
Profile bio.

What you can build with the Bluesky Public API

  • Display Bluesky follower counts or a post feed on a website
  • Build a read-only Bluesky client or embed
  • Monitor public posts mentioning a topic
  • Analyse the AT Protocol social graph

Common errors and how to fix them

400 InvalidRequest

Missing the `actor` parameter or a malformed handle.

Fix: Pass a full handle including domain, e.g. bsky.app, or a DID.

Handle no longer resolves

The user changed their handle.

Fix: Store and query by DID, which never changes, rather than the handle.

429

Rate limit exceeded.

Fix: Public AppView allows roughly 3,000 requests per 5 minutes per IP; add caching.

Bluesky Public API — frequently asked questions

Does the Bluesky API need authentication?

Not for public data. The public AppView at public.api.bsky.app serves profiles, posts and feeds with no key. Posting or reading private data requires a session.

What is a DID and why does it matter?

A decentralised identifier — the account's permanent id. Handles can be changed by the user, so always store and query by DID for anything persistent.

Can I post to Bluesky through this API?

Not through the public endpoint. Writing requires creating an authenticated session against the user's PDS with an app password.

What is the AT Protocol?

The open protocol underlying Bluesky. It separates identity, data storage and the application view, which is why public reads can be served without any account.

Tools that pair with this API

Bluesky Public API is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.