Bluesky API: posting reference
Bluesky is supported via the AT Protocol. OmniSocials posts to the specific account that completed OAuth: you enter your handle and sign in on Bluesky, with no app password to create. Both bsky.social and self-hosted PDS accounts work, and so do custom-domain handles.
For an overview and use cases, see Bluesky API.
Channel ID: bluesky
Supported content types
| Type | Supported |
|---|---|
| Feed post | ✅ |
| Story | - |
| Reel | - |
Minimal example
Terminal
Platform-specific options
| Field | Type | Description |
|---|---|---|
bluesky.thread_parts | array | Publish as a chained thread instead of a single post. See Posting threads. |
Posting threads
To publish a thread (a reply chain), pass bluesky.thread_parts. Each part becomes its own post, chained as a reply to the previous one.
JSON
Rules:
- 2 to 25 parts. For a single post, omit
thread_partsand usecontent.bluesky(orcontent.default) instead. - Each
textis required, non-empty, and ≤ 300 graphemes. Parts that exceed the limit are rejected with a400. media_urlsis optional per part: one video or up to 10 images per part (5 or more post as a gallery). A part without media gets its own link card when its text has a link.- Links, @mentions, and #hashtags are auto-detected and made clickable via AT Protocol rich-text facets; no manual markup needed.
Link cards
A post with a link in its text and no media gets a link card for the first link, built from the page's Open Graph data: title, description and the page's Open Graph image as the thumbnail. You don't need to pass anything extra. A post with media shows the media instead of a card. A page without Open Graph data gets no card, and a card that can't be built never fails the post.
Media requirements
| Media | Requirement |
|---|---|
| Image | JPEG, PNG, or WebP. Max 2 MB per image after compression (see below). Up to 10 per post: 1 to 4 post as an image grid, 5 to 10 as a gallery. |
| Video | MP4 or MOV, up to 10 minutes, max 300 MB. One per post. |
Bluesky's servers reject image blobs over 2 MB. You do not need to pre-compress: OmniSocials automatically compresses oversized images down to fit the 2 MB cap at upload time, so you can pass images up to 10 MB and let the API handle it.
Video uploads need a verified email address on the Bluesky account (bsky.app, Settings, Account), and Bluesky sets a daily video upload limit per account. Images keep their real aspect ratio in the post.
Bluesky does not support mixing images and video in the same post: attach images only, or a single video. Mixed media returns a 400 validation_error at create/schedule time.
Alt text. Bluesky renders per-image alt text natively. Pass it by using an object entry instead of a bare string: { "url": "https://example.com/bike.jpg", "alt": "A red bicycle leaning against a brick wall" } in media_urls (or { "id": "...", "alt": "..." } in media_ids, including per-part thread media; max 1500 characters). It is sent as the image/video embed's alt.
Character limit
Bluesky enforces a 300 grapheme limit per post (emoji count as 1 grapheme, not their UTF-8 byte length). OmniSocials counts graphemes correctly when validating.
Limitations
- Links, mentions, and hashtags are made clickable automatically (via rich-text facets); you do not need to add any markup
- Bluesky does not expose post scheduling as a first-class concept. Scheduled OmniSocials posts are held on our side and published at the scheduled time.
- Polls are not supported on Bluesky
- Bluesky replies and mentions are not part of the Social Inbox