At a glance
Capabilities
An unsupported call returns501 resource.not_supported. Read the capabilities object on each comment instead of assuming (can_reply, can_delete, can_hide).
The capability matrix for every platform is on Supported platforms.
Connect an account
A Bluesky account connects in one request: you send its handle and an app password, and SocialAPI returns the connected account.1
Create an app password
Sign in to Bluesky in a browser and open App passwords in Settings. Click Add app password and name it, for example
socialapi. Never send your account password.2
Allow direct messages (optional)
Tick Allow access to your direct messages before you create the password if SocialAPI must read and send DMs. You can set this option only when you create the app password. To add DM access later, create a second app password with the option on and connect again with it.
3
Copy the password
Bluesky shows the app password once, in the form
xxxx-xxxx-xxxx-xxxx. Copy it.4
Connect the account
Send the handle as Response (HTTP 201):
metadata.identifier and the password as metadata.app_password:identifier is the account’s handle or its DID. Without brand_id in the request, SocialAPI creates a brand for the account. SocialAPI also sends account.connected to your webhook endpoints. A custom-domain handle works the same way.
A missing identifier or app_password returns 400 validation.field_required, with meta.field naming it. A handle Bluesky cannot resolve, or an app password Bluesky rejects, returns 400 validation.field_invalid.
Two-factor accounts
When the account has email two-factor authentication on, the first connect request returns400 platform.bluesky.auth_factor_required and Bluesky emails a confirmation code. Send the same request again with that code as metadata.auth_factor_token.
Disconnect and revoke
Disconnecting the account (DELETE /v1/accounts/{account_id}) deletes the app password from SocialAPI. Bluesky offers no way to revoke an app password from outside, so the password stays valid on Bluesky. To cut off access completely, delete the app password in Settings on Bluesky.
Direct messages
DMs work only with an app password that has direct message access. SocialAPI checks this when you connect. Without it, every DM call returns403 platform.bluesky.dm_scope_missing, and posts, comments, and mentions keep working. The fix is a new app password with Allow access to your direct messages on, then a new connect request. Reconnecting with the old password does not help.
You list conversations with GET /v1/inbox/conversations, read a conversation with GET /v1/inbox/conversations/{conversation_id}/messages, and reply with POST /v1/inbox/conversations/{conversation_id}/messages. The request fields are on Direct messages.
These rules are specific to Bluesky:
- Text only. A Bluesky message carries text. SocialAPI sends only the
textof a send request. It does not send attachments,buttons,quick_replies,cards, orlist_sections. - No
message_tag. Bluesky has no message tags:message_tagis ignored.
Comments and replies
You read the replies to a post withGET /v1/inbox/comments/{postId} and answer with the reply endpoints on Comments.
- One flat list. Bluesky returns a thread as a tree with no cursor. SocialAPI flattens it, the pagination object is always empty, and replies deeper than 6 levels below the post are not returned. A very large thread can be cut off.
- Hide, not delete. Only the author of the original post can hide a reply to it: another account gets
403 platform.bluesky.not_thread_owner. A thread holds at most 300 hidden replies: the 301st returns422 platform.bluesky.hidden_replies_full. A hidden reply is not removed: Bluesky no longer shows it by default. - Delete only your own replies.
platform.bluesky.not_own_recordis returned when you try to delete a reply from another account. - No likes and no private replies.
can_likeandcan_private_replyarefalseon every comment.
Mentions
GET /v1/accounts/{account_id}/mentions returns the posts that mention the account, from Bluesky’s mention notifications. It covers the whole account, not one post. You answer a mention with a reply to that post. See Mentions.
Webhook events
Bluesky sends SocialAPI no notification of its own, so there is nocomment.received or dm.received event: read comments and DMs with the inbox endpoints. Listing mentions with GET /v1/accounts/{id}/mentions sends a mention.received event for the listed items: see Mentions you list. Bluesky does emit the post.* events for posts you publish through SocialAPI, account.connected when you connect the account, account.disconnected when SocialAPI flags the account for reconnection, and account.updated when the account loses permissions you did not remove yourself. See Webhook events.
Limits
When Bluesky’s own limit is used up, the call fails with
429 platform.bluesky.rate_limit. Wait, then retry. GET /v1/accounts/{id}/limits returns the 2 write budgets.
Scopes
Bluesky has no OAuth scopes. An app password gives SocialAPI the access of the account itself, except direct messages, which need the option you tick when you create the password. SocialAPI uses it to publish posts, read and reply to comments and mentions, and read and send DMs. The account supports theposts.read, posts.write, comments.read, comments.write, messages.read, and messages.write permissions, which SocialAPI alone enforces.
Related
- Bluesky publishing: text, images, scheduling, and deleting posts
- Direct messages: the request fields for sending DMs
- Comments: reading, replying to, and hiding comments
- Platform apps: which app connects each platform
- Errors: every Bluesky error code
- Supported platforms: what each platform supports