Skip to content

Bluesky API

Postproxy publishes feed posts and post chains to Bluesky over the AT Protocol, and supports text direct messages through the Bluesky chat service.

Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.

Platform IDbluesky
Formatspost (default)
Character limit300 (graphemes)
MediaOptional
PlacementsNone
CommentsNo
Direct messagesYes — text only
Post chainsYes

Bluesky has no custom parameters — pass an empty object (or omit it).

MediaMax sizeFormatsCountDuration
Image1 MBjpg, png, webp, gif4
Video50 MBmp4, mov11 s – 60 s
  • Text-only posts are allowed; media is optional.
  • Images and video cannot be mixed.
  • The 1 MB per-image limit is strict — compress images before uploading.
Terminal window
# Simple post
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Shipping a new feature today 🚀 https://example.com/launch" },
"profiles": ["prof_abc123"],
"media": ["https://example.com/image.jpg"],
"platforms": { "bluesky": {} }
}'

Bluesky supports thread conversations. Pass a thread array of follow-up posts; each child can carry its own media.

Terminal window
# A 2-post thread
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "1/ Quick thread on what we shipped 🧵" },
"profiles": ["prof_abc123"],
"thread": [
{ "body": "2/ Faster sync and a new webhook.", "media": ["https://example.com/shot.jpg"] }
]
}'

Not currently exposed through the Comments API.

Bluesky DMs go through the AT Protocol chat service and are supported through the Direct Messages API, with some limits relative to the Meta networks.

CapabilitySupported
Send / receive textYes
AttachmentsNo
ReactionsNo
Edit outbound messageNo
Delivery / read receiptsNo
Archive (mute) chatYes
Inbound deliveryPoller (~5 min)
  • No webhooks for inbound. A per-profile poller runs every ~5 minutes; new inbound messages still fire message.received, with up to ~5 minutes of latency.
  • No messaging window, but the recipient must have DMs enabled and allow messages from you, or the send fails with a Bluesky-side error.
  • Archive = mute — archive / unarchive map to muteConvo / unmuteConvo.
  • Start a chat with the recipient’s DID as participant_external_id.
Terminal window
# Create or find a chat by DID
curl -X POST "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "participant_external_id": "did:plc:abcdefghijklmnopqrstuvwx" }'
Terminal window
# Send a text message (Bluesky is text-only)
curl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Thanks for following! Anything we can help with?" }'
Terminal window
# Archive (mute) / unarchive a chat
curl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/archive" \
-H "Authorization: Bearer YOUR_API_KEY"
curl -X DELETE "https://api.postproxy.dev/api/chats/chat_abc123/archive" \
-H "Authorization: Bearer YOUR_API_KEY"

Subscribe with the Webhooks API:

Terminal window
curl -X POST "https://api.postproxy.dev/api/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/postproxy",
"events": ["platform_post.published", "message.received"]
}'

Events relevant to Bluesky:

EventWhen
post.processedA post is ready to publish
platform_post.publishedA post was published to the platform
platform_post.failedA post failed to publish (retries exhausted)
platform_post.failed_waiting_for_retryA publish attempt failed; will retry
platform_post.insightsNew analytics snapshot
message.receivedInbound DM (via the ~5 min poller)
message.sentAn outbound DM was accepted by the platform
message.failed_waiting_for_retryAn outbound DM failed; will retry
message.failedAn outbound DM failed permanently
profile.connected / .disconnectedConnection state changed
profile.statsNew profile stats snapshot
media.failedA media attachment failed to process

Bluesky does not expose delivery/read receipts, reactions, edits, or deletion events.

  • The character limit is counted in graphemes — emoji and combining sequences count as one character.
  • Images are capped at 1 MB each; plan to compress.