Social — entry 004 of 38

Bluesky

Verified Sep 2026

Bluesky is the decentralized social network built on the AT Protocol, where posts, follows, and identity live on portable Personal Data Servers instead of one company's database. Its public AppView at public.api.bsky.app exposes keyless, read-only XRPC methods such as app.bsky.actor.getProfile and app.bsky.feed.getAuthorFeed, so any client can pull public profiles and feeds without registering an app. Posting, following, or reading a signed-in user's private data instead requires an authenticated session against a Personal Data Server via an app password or OAuth, not a single global API key.

Bluesky's public AppView, public.api.bsky.app, exposes a partial keyless slice of its XRPC surface: profile, author-feed, thread, and follower lookups answer with no credentials at all, while others (timeline, search) require auth or are blocked outright. A live GET this run against app.bsky.actor.getProfile?actor=bsky.app returned genuine profile JSON for Bluesky's own account with no key of any kind.

at-protocoldecentralizedsocialfeedxrpc
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreeNo paid tier — free for the documented use case.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score94out of 100
Authentication25/25No authentication required
Pricing20/20Free to use
Docs20/20Machine-readable spec file bundled
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 94 on greatapis.com
<a href="https://greatapis.com/api/bluesky/"><img src="https://greatapis.com/badge/bluesky.svg" alt="Scored 94 on greatapis.com"></a>

Auth quickstart

  1. No API key, signup, or credit card required for the keyless subset — a live GET this run confirmed getProfile, getAuthorFeed, getPostThread, getFollowers, and resolveHandle all return 200 with zero credentials. Posting, following, or reading a signed-in user's private data instead needs an authenticated session against a Personal Data Server (app password or OAuth), which this keyless quickstart does not cover.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Endpoints

Servers
https://public.api.bsky.apphttps://{host}https://bsky.network
Auth
Bearer
app.bsky.actor7
GET/xrpc/app.bsky.actor.getPreferences
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.actor.getProfile
Parameters
NameInRequiredType
actorqueryyesstring
Responses
StatusDescriptionSchema
200OKapp.bsky.actor.defs.profileViewDetailed
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.actor.getProfiles
Parameters
NameInRequiredType
actorsqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.actor.getSuggestions
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.actor.putPreferences
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.actor.searchActors
Parameters
NameInRequiredType
qquerynostring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.actor.searchActorsTypeahead
Parameters
NameInRequiredType
qquerynostring
limitquerynointeger
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.ageassurance3
POST/xrpc/app.bsky.ageassurance.begin
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OKapp.bsky.ageassurance.defs.state
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.ageassurance.getConfig
Responses
StatusDescriptionSchema
200OKapp.bsky.ageassurance.defs.config
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.ageassurance.getState
Parameters
NameInRequiredType
regionCodequerynostring
countryCodequeryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.bookmark3
POST/xrpc/app.bsky.bookmark.createBookmark
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.bookmark.deleteBookmark
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.bookmark.getBookmarks
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.contact8
POST/xrpc/app.bsky.contact.dismissMatch
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.contact.getMatches
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.contact.getSyncStatus
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.contact.importContacts
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.contact.removeData
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.contact.sendNotification
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.contact.startPhoneVerification
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.contact.verifyPhone
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.draft4
POST/xrpc/app.bsky.draft.createDraft
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.draft.deleteDraft
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.draft.getDrafts
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.draft.updateDraft
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.feed18
GET/xrpc/app.bsky.feed.describeFeedGenerator
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getActorFeeds
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getActorLikes
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getAuthorFeed
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
filterquerynostring
includePinsquerynoboolean
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getFeed
Parameters
NameInRequiredType
feedqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getFeedGenerator
Parameters
NameInRequiredType
feedqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getFeedGenerators
Parameters
NameInRequiredType
feedsqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getFeedSkeleton
Parameters
NameInRequiredType
feedqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getLikes
Parameters
NameInRequiredType
cidquerynostring
uriqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getListFeed
Parameters
NameInRequiredType
listqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getPostThread
Parameters
NameInRequiredType
uriqueryyesstring
depthquerynointeger
parentHeightquerynointeger
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getPosts
Parameters
NameInRequiredType
urisqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getQuotes
Parameters
NameInRequiredType
cidquerynostring
uriqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getRepostedBy
Parameters
NameInRequiredType
cidquerynostring
uriqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getSuggestedFeeds
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.getTimeline
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
algorithmquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.feed.searchPosts
Parameters
NameInRequiredType
qqueryyesstring
tagquerynoarray
urlquerynostring
langquerynostring
sortquerynostring
limitquerynointeger
sincequerynostring
untilquerynostring
authorquerynostring
cursorquerynostring
domainquerynostring
mentionsquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.feed.sendInteractions
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.graph23
GET/xrpc/app.bsky.graph.getActorStarterPacks
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getBlocks
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getFollowers
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getFollows
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getKnownFollowers
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getList
Parameters
NameInRequiredType
listqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getListBlocks
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getListMutes
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getLists
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
purposesquerynoarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getListsWithMembership
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
purposesquerynoarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getMutes
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getRelationships
Parameters
NameInRequiredType
actorqueryyesstring
othersquerynoarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getStarterPack
Parameters
NameInRequiredType
starterPackqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getStarterPacks
Parameters
NameInRequiredType
urisqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getStarterPacksWithMembership
Parameters
NameInRequiredType
actorqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.getSuggestedFollowsByActor
Parameters
NameInRequiredType
actorqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.muteActor
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.muteActorList
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.muteThread
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.graph.searchStarterPacks
Parameters
NameInRequiredType
qqueryyesstring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.unmuteActor
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.unmuteActorList
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.graph.unmuteThread
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.labeler1
GET/xrpc/app.bsky.labeler.getServices
Parameters
NameInRequiredType
didsqueryyesarray
detailedquerynoboolean
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.notification10
GET/xrpc/app.bsky.notification.getPreferences
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.notification.getUnreadCount
Parameters
NameInRequiredType
seenAtquerynostring
priorityquerynoboolean
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.notification.listActivitySubscriptions
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.notification.listNotifications
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
seenAtquerynostring
reasonsquerynoarray
priorityquerynoboolean
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.putActivitySubscription
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.putPreferences
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.putPreferencesV2
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.registerPush
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.unregisterPush
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.notification.updateSeen
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
app.bsky.video3
GET/xrpc/app.bsky.video.getJobStatus
Parameters
NameInRequiredType
jobIdqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/app.bsky.video.getUploadLimits
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/app.bsky.video.uploadVideo
Request body

video/mp4 (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.admin15
POST/xrpc/com.atproto.admin.deleteAccount
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.disableAccountInvites
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.disableInviteCodes
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.enableAccountInvites
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.admin.getAccountInfo
Parameters
NameInRequiredType
didqueryyesstring
Responses
StatusDescriptionSchema
200OKcom.atproto.admin.defs.accountView
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.admin.getAccountInfos
Parameters
NameInRequiredType
didsqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.admin.getInviteCodes
Parameters
NameInRequiredType
sortquerynostring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.admin.getSubjectStatus
Parameters
NameInRequiredType
didquerynostring
uriquerynostring
blobquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.admin.searchAccounts
Parameters
NameInRequiredType
emailquerynostring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.sendEmail
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.updateAccountEmail
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.updateAccountHandle
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.updateAccountPassword
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.updateAccountSigningKey
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.admin.updateSubjectStatus
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.identity7
GET/xrpc/com.atproto.identity.getRecommendedDidCredentials
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.identity.refreshIdentity
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OKcom.atproto.identity.defs.identityInfo
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.identity.requestPlcOperationSignature
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.identity.resolveHandle
Parameters
NameInRequiredType
handlequeryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.identity.signPlcOperation
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.identity.submitPlcOperation
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.identity.updateHandle
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.label1
GET/xrpc/com.atproto.label.queryLabels
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
sourcesquerynoarray
uriPatternsqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.moderation1
POST/xrpc/com.atproto.moderation.createReport
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.repo10
POST/xrpc/com.atproto.repo.applyWrites
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.repo.createRecord
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.repo.deleteRecord
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.repo.describeRepo
Parameters
NameInRequiredType
repoqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.repo.getRecord
Parameters
NameInRequiredType
cidquerynostring
repoqueryyesstring
rkeyqueryyesstring
collectionqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.repo.importRepo
Request body

application/vnd.ipld.car (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.repo.listMissingBlobs
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.repo.listRecords
Parameters
NameInRequiredType
repoqueryyesstring
limitquerynointeger
cursorquerynostring
reversequerynoboolean
collectionqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.repo.putRecord
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.repo.uploadBlob
Request body

*/* (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.server25
POST/xrpc/com.atproto.server.activateAccount
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.checkAccountStatus
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.confirmEmail
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.createAccount
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.createAppPassword
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OKcom.atproto.server.createAppPassword.appPassword
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.createInviteCode
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.createInviteCodes
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.createSession
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.deactivateAccount
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.deleteAccount
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.deleteSession
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.describeServer
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.getAccountInviteCodes
Parameters
NameInRequiredType
includeUsedquerynoboolean
createAvailablequerynoboolean
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.getServiceAuth
Parameters
NameInRequiredType
audqueryyesstring
expquerynointeger
lxmquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.getSession
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.server.listAppPasswords
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.refreshSession
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.requestAccountDelete
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.requestEmailConfirmation
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.requestEmailUpdate
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.requestPasswordReset
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.reserveSigningKey
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.resetPassword
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.revokeAppPassword
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.server.updateEmail
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
com.atproto.sync13
GET/xrpc/com.atproto.sync.getBlob
Parameters
NameInRequiredType
cidqueryyesstring
didqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getBlocks
Parameters
NameInRequiredType
didqueryyesstring
cidsqueryyesarray
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getHostStatus
Parameters
NameInRequiredType
hostnamequeryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getLatestCommit
Parameters
NameInRequiredType
didqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getRecord
Parameters
NameInRequiredType
didqueryyesstring
rkeyqueryyesstring
collectionqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getRepo
Parameters
NameInRequiredType
didqueryyesstring
sincequerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.getRepoStatus
Parameters
NameInRequiredType
didqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.listBlobs
Parameters
NameInRequiredType
didqueryyesstring
limitquerynointeger
sincequerynostring
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.listHosts
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.listRepos
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
GET/xrpc/com.atproto.sync.listReposByCollection
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
collectionqueryyesstring
Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.sync.notifyOfUpdate
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—
POST/xrpc/com.atproto.sync.requestCrawl
Request body

application/json (required)

Responses
StatusDescriptionSchema
200OK—
400Bad Request—
401Unauthorized—

Try it

Developer reference

Base URLhttps://public.api.bsky.app/xrpc
Rate limit

3,000 requests per 5 minutes per IP overall; content-creation additionally capped at 5,000 points/hour and 35,000 points/day per account

Key endpoints
  • GET/xrpc/app.bsky.actor.getProfile
  • GET/xrpc/app.bsky.feed.getAuthorFeed
  • GET/xrpc/app.bsky.feed.getPostThread

Gotchas & limits

  • app.bsky.feed.searchPosts — deliberately left out of this API's heroEndpoints for exactly this reason — returns HTTP 403 with an HTML error page, not XRPC JSON: a live GET this run against ?q=test returned content-type: text/html and a body opening <html><head><title>403 Forbidden</title>... (a CDN edge block page). A client that assumes every XRPC failure is parseable JSON breaks here.
  • app.bsky.feed.getTimeline requires an authenticated session and is not keyless — a live GET this run returned HTTP 401 with genuine XRPC JSON {"error":"AuthMissing","message":"Authentication Required"}. Contrast with searchPosts's HTML 403 above: two different failure shapes for two different kinds of "you can't do this here".
  • Errors are not RESTful: an unknown handle is 400, not 404 — a live GET this run against getProfile?actor= a nonexistent handle returned HTTP 400 {"error":"InvalidRequest","message":"Profile not found"}. A missing required param is also 400 and names the key: a live GET with no actor at all returned {"error":"InvalidRequest","message":"Invalid app.bsky.actor.getProfile params: Missing required key \"actor\""}.
  • limit over the max is a 400 that names the ceiling — a live GET this run against getAuthorFeed?actor=bsky.app&limit=101 returned HTTP 400 {"error":"InvalidRequest","message":"Invalid app.bsky.feed.getAuthorFeed params: integer too big (maximum 100, got 101)"}.
  • getAuthorFeed items are not all authored by the requested actor — a live GET this run against getAuthorFeed?actor=bsky.app returned a first feed item whose post.author.handle was paretooptimizer.bsky.social, not bsky.app, carrying a sibling reason.$type: "app.bsky.feed.defs#reasonRepost". Reading feed[].post.author as "the requested actor" is wrong whenever reason is present — it means a repost.
  • An unimplemented XRPC method returns HTTP 501 {"error":"MethodNotImplemented","message":"Method Not Implemented"} — a live GET this run against a made-up method name confirmed it, distinct from the 400s above (bad params) and the 403/401s above (blocked/unauthenticated).

Availability

Uptime100%
Median latency165 ms
Last checkUp · 400 · Sep 2026

16 checks since Sep 2026. A person runs this check by hand, not an automated monitor.

Changelog

Spec version
Tracked paths152
  • Sep 2026gained an OpenAPI spec

Tracking since Sep 2026. See every tracked change ↗ ·Subscribe with RSS ↗