Bluesky

Bluesky API: Post

How to publish a post to Bluesky via API using an app password.

Quick answer

Connect the Bluesky account with POST /api/profiles/connect (platform: bluesky) — the account holder enters their handle and an app password on PostGate's hosted page, never their main password — then publish with a single POST /api/posts naming the connected profile. Posts are capped at 300 graphemes, up to 4 images at 1 MB each, and no video yet.

Posting to Bluesky through the PostGate API looks like every other platform from the outside — one POST /api/posts request, one connected profile ID. What's different is what happens underneath: Bluesky runs on the AT Protocol, and the account you connect authenticates with an app password, not an OAuth redirect like Instagram, LinkedIn, or TikTok.

This page covers the single-request mechanics. For the full connect-to-confirm walkthrough, see How to Post to Bluesky via API.

01

Why is this one account a password, not an OAuth token?

Every other network in PostGate's catalog authorizes through an OAuth redirect: the customer leaves your product, approves a scoped grant on the provider's own page, and comes back with a token PostGate stores. Bluesky doesn't have that flow for third-party publishing tools in the same shape. Instead, the account holder generates an app password from Bluesky's own settings — a credential scoped to API access that can be revoked independently of the account's main login.

PostGate's hosted connection page collects that app password directly and exchanges it for a session behind the scenes; your product never touches or stores it. The account's main password should never be entered anywhere except bsky.app itself.

02

Connect the Bluesky account

Create a hosted connection URL and send the customer to it. On the hosted page they enter their handle and app password — PostGate never sees the main account credential.
Create connection URLPostGate API
curl -X POST https://postgate.studio/api/profiles/connect \
  -H "Authorization: Bearer $POSTGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "bluesky",
    "profile_group_id": "grp_acme123",
    "return_url": "https://app.example.com/settings/social"
  }'
03

Publish a post

Once connected, publishing is the same envelope as any other platform: post.body, a target list of profiles, and optional media. Bluesky posts are capped at 300 graphemes, so keep the copy short if you're also fanning it out to platforms with a longer limit.
Publish nowPostGate API
curl -X POST "https://postgate.studio/api/posts?profile_group_id=grp_acme123" \
  -H "Authorization: Bearer $POSTGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: bsky-launch-001" \
  -d '{
    "post": { "body": "Launch day. 🚀" },
    "profiles": ["pro_bluesky123"]
  }'
04

What comes back?

The response includes a targets entry for the Bluesky profile with delivery status, the underlying record identifiers, and — once published — a permalink you can store or show to the customer. Poll GET /api/posts/{id} or subscribe to a webhook instead of blocking on the initial call.
05

Which limits actually bite?

300 graphemes of text, up to 4 images, no video yet (Bluesky's own video support hasn't reached this API), and a 1 MB per-image cap. Links and hashtags in the body become clickable automatically; @mentions resolve when the handle is real. See Bluesky Image Upload API for the media side of this in detail.

Frequently asked questions

Does Bluesky use OAuth for third-party posting tools?

Not in the same shape as Instagram, LinkedIn, or TikTok. The account holder generates an app password from Bluesky’s own settings — a credential scoped to API access that can be revoked independently of the main login. PostGate’s hosted connection page collects that app password and exchanges it for a session behind the scenes; your product never touches it, and the main password should never be entered anywhere except bsky.app itself.

What is the character limit for a Bluesky post?

Bluesky posts are capped at 300 graphemes. If you are fanning the same body out to platforms with longer limits, keep the copy short enough to fit Bluesky’s cap, or the Bluesky target will fail while the others publish.

Can I post video to Bluesky through the API?

Not yet — Bluesky’s own video support hasn’t reached this API. The media limits that apply today: up to 4 images per post, with a 1 MB per-image cap. Links and hashtags in the body become clickable automatically, and @mentions resolve when the handle is real.

How do I confirm a Bluesky post actually published?

The response includes a targets entry for the Bluesky profile with delivery status, the underlying record identifiers, and — once published — a permalink you can store or show to the customer. Poll GET /api/posts/{id} or subscribe to a webhook instead of blocking on the initial call.

Build it with PostGate

One API for every social platform your customers care about — sandboxed, documented, and ready today.

Start building Read the docs