The Bluesky scheduling API

Create a Bluesky post with one HTTP call. It joins the same queue the dashboard uses, retries on failure, and reports back what actually went out.

Publish to Bluesky

# POST a text-and-media post to your connected Bluesky channel
curl -X POST https://api.postwharf.com/v1/posts \
  -H "Authorization: Bearer $POSTWHARF_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Shipping today.",
    "channels": ["ch_your_bluesky_channel"],
    "media": ["med_optional"]
  }'

Schedule it instead

curl -X POST https://api.postwharf.com/v1/posts \
  -H "Authorization: Bearer $POSTWHARF_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Tuesday drop","channels":["ch_your_bluesky_channel"],"publish_at":"2026-09-01T09:00:00Z"}'

Find your Bluesky channel id

curl https://api.postwharf.com/v1/channels \
  -H "Authorization: Bearer $POSTWHARF_KEY"

Each connected account is a channel. The one you want has "platform": "bluesky".

Check what happened

curl https://api.postwharf.com/v1/posts/post_xxx \
  -H "Authorization: Bearer $POSTWHARF_KEY"

The response carries one delivery per channel with its status, the live URL once published, and the error text if it failed. Deliveries are re-checked after publishing, so a Bluesky post removed later stops reporting as live.

What Bluesky accepts

300 characters, counting one post. Up to 4 images per post, and no video. Images over 1 MB are refused before the post is queued.

Read from the table the API enforces, so a post over 300 is refused when you create it rather than truncated on the way to Bluesky.

Worth knowing about Bluesky

Connects in about a minute — no app review or audit.

Every other network

Instagram · TikTok · X · LinkedIn · YouTube · Facebook · Threads · Pinterest · Reddit · Telegram · Discord · Snapchat · WordPress