> ## Documentation Index
> Fetch the complete documentation index at: https://kavenio.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bluesky Posting API Documentation | Kavenio Docs

> Connect Bluesky accounts and publish text, images, GIFs, videos, link cards, and reply-chain threads. Review App Passwords, PDS sessions, limits, and errors.

Kavenio publishes to Bluesky through connected Bluesky accounts. Use
`bluesky` as the platform value in post payloads.

Bluesky connections use a Bluesky identifier and App Password. The App Password
is accepted only when connecting the account and is never returned by the API.

For a product-level overview, see the
[Bluesky posting API](https://kavenio.com/platforms/bluesky) page.

## Quick Reference

| Capability       | Support                                                 |
| ---------------- | ------------------------------------------------------- |
| Platform key     | `bluesky`                                               |
| Text post        | Supported                                               |
| Image upload     | Up to 4 JPEG, PNG, WebP, or GIF items                   |
| Video upload     | 1 MP4 video                                             |
| Thread           | `threadItems` reply chain                               |
| Rich text facets | URLs, hashtags, and resolvable mentions                 |
| Link preview     | Automatic first URL or explicit external metadata       |
| Delete/unpublish | AT Protocol record deletion                             |
| Native edit      | Not supported; delete/repost instead                    |
| Post analytics   | Likes, comments/replies, reposts, and quotes            |
| Comments         | List replies, reply, delete owned replies, like, unlike |
| DMs              | Text-only conversations and messages                    |
| DM attachments   | Not supported                                           |

## Connect

Connect a Bluesky account with the credentials endpoint:

```json theme={null}
{
  "profileId": "customer_user_123",
  "identifier": "creator.bsky.social",
  "appPassword": "xxxx-xxxx-xxxx-xxxx",
  "pdsUrl": "https://bsky.social"
}
```

Kavenio verifies the App Password through `com.atproto.server.createSession`,
stores the credential encrypted, reuses the access session for publishing, and
rotates encrypted access and refresh JWTs when required. App Password login is
used only when a refresh session is unavailable or rejected. Custom PDS values
must be public HTTPS origins, and the authenticated DID must match the connected
account. Connected Bluesky accounts expose `post` and `dm` permissions in
account metadata.

Kavenio's current connection flow uses App Passwords rather than AT Protocol
OAuth.

## Create A Post

Create a normal Bluesky post through the shared posts API:

```json theme={null}
{
  "profileId": "customer_user_123",
  "content": "Shipping a product update today.",
  "platforms": [
    {
      "platform": "bluesky",
      "accountId": "acc_123"
    }
  ],
  "publishNow": true
}
```

```bash theme={null}
kavenio posts create \
  --profile-id customer_user_123 \
  --content "Shipping a product update today." \
  --publish-now \
  --platform bluesky:acc_123
```

## Media

Kavenio downloads public media URLs at publish time, validates them, uploads
them to Bluesky, and attaches the returned AT Protocol blob references.

Supported media groups:

| Media group     | Limit               |
| --------------- | ------------------- |
| Images and GIFs | Up to 4 items       |
| Video           | Exactly 1 MP4 video |

Images and GIFs cannot be mixed with video. Images and GIFs must be 2 MB
or smaller, enforced as the current 2,000,000-byte `app.bsky.embed.images`
lexicon limit when size metadata or fetched media bytes are available. Video
must be MP4, 100 MB or smaller, and 180 seconds or shorter when duration
metadata is supplied.

```json theme={null}
{
  "content": "New dashboard preview.",
  "mediaItems": [
    {
      "type": "image",
      "url": "https://cdn.example.com/dashboard.png",
      "mimeType": "image/png",
      "size": 532000,
      "altText": "Dashboard preview"
    }
  ],
  "platforms": [
    {
      "platform": "bluesky",
      "accountId": "acc_123"
    }
  ],
  "publishNow": true
}
```

## Threads

Use `platformSpecificData.threadItems` to publish a Bluesky reply chain. When
`threadItems` is present, top-level `content` is Kavenio display/search
metadata; `threadItems[0]` becomes the Bluesky root post and each later item
replies to the previous item using provider URI/CID references from the publish
response.

Durable post targets use deterministic AT Protocol record keys. If publishing
is interrupted after one thread item succeeds, a worker retry updates the same
records rather than creating a duplicate root post.

Put media on individual thread items. Bluesky thread publishing does not
support top-level `mediaItems`.

```json theme={null}
{
  "content": "Launch thread",
  "platforms": [
    {
      "platform": "bluesky",
      "accountId": "acc_123",
      "platformSpecificData": {
        "threadItems": [
          {
            "content": "Launch notes, part 1."
          },
          {
            "content": "Part 2 with a screenshot.",
            "mediaItems": [
              {
                "type": "image",
                "url": "https://cdn.example.com/screenshot.png",
                "mimeType": "image/png"
              }
            ]
          }
        ]
      }
    }
  ],
  "publishNow": true
}
```

## Facets And Link Previews

Bluesky posts include rich text facets for URLs, hashtags, and mentions that
can be resolved to DIDs.

Kavenio can create a Bluesky external link card from the first detected URL.
Disable automatic cards with `disableLinkPreview`, or provide explicit link
metadata:

```json theme={null}
{
  "content": "Read this: https://example.com/article",
  "platforms": [
    {
      "platform": "bluesky",
      "accountId": "acc_123",
      "platformSpecificData": {
        "externalUrl": "https://example.com/article",
        "externalTitle": "Article title",
        "externalDescription": "Article summary",
        "externalThumbUrl": "https://cdn.example.com/thumb.jpg"
      }
    }
  ],
  "publishNow": true
}
```

Link previews cannot be combined with media or thread posts.

## Delete And Edit

Published Bluesky targets can be unpublished through AT Protocol
`com.atproto.repo.deleteRecord`. Thread unpublish deletes stored thread records
from the last reply back to the root record.

Native in-place edit is not supported. Delete/repost is the supported path for
changing published Bluesky content.

## Analytics

Use the shared post analytics endpoint for a published Bluesky target:

```http theme={null}
GET /v1/posts/{postId}/analytics?targetId={targetId}
```

The result includes likes, comments/replies, reposts, and quotes. Impressions,
reach, clicks, and views are returned as `null` and listed in
`unsupportedMetrics`.

Successful on-demand analytics reads are persisted as historical snapshots.
The scheduled `social_accounts.metadata_refresh_due` job also refreshes
analytics snapshots for connected Bluesky accounts.

## Comments

Use the shared post comments API for Bluesky replies:

```http theme={null}
GET /v1/posts/{postId}/comments?targetId={targetId}
POST /v1/posts/{postId}/comments/reply
DELETE /v1/posts/{postId}/comments
POST /v1/posts/{postId}/comments/like
POST /v1/posts/{postId}/comments/unlike
```

Reply creation uses the root and parent AT URI/CID pair returned by the
comments endpoint. Deleting a Bluesky comment is limited to records authored by
the connected account DID. Liking a comment returns a like record URI; pass
that URI to the unlike endpoint.

## Direct Messages

Kavenio exposes account-scoped text-only Bluesky DM APIs:

```http theme={null}
GET /v1/accounts/{accountId}/bluesky-conversations
GET /v1/accounts/{accountId}/bluesky-conversations/{conversationId}/messages
POST /v1/accounts/{accountId}/bluesky-conversations/{conversationId}/messages
POST /v1/accounts/{accountId}/bluesky-conversations/{conversationId}/read
POST /v1/accounts/{accountId}/bluesky-conversations/{conversationId}/archive
```

DM calls use a fresh app-password session access JWT against the Bluesky Chat
API. Attachments are rejected before provider calls with
`Bluesky DM attachments are not implemented.`

Conversation listing accepts the Bluesky Chat filters `kind`, `lockStatus`,
`readState`, and `status` when the connected account is eligible for the Chat
API. The CLI exposes the same text-only surface through
`accounts bluesky-conversations`, `accounts bluesky-messages`,
`accounts bluesky-message-send`, `accounts bluesky-conversation-read`, and
`accounts bluesky-conversation-archive`.

Archiving uses the official Bluesky Chat `chat.bsky.convo.leaveConvo`
operation. Kavenio does not expose a separate unarchive endpoint because the
current provider API does not provide one.

Live Chat API behavior can still depend on Bluesky account and App Password
eligibility. If provider auth rejects a connected account, reconnect the
account with a valid App Password.

## Unsupported

Kavenio does not support Bluesky native in-place edit, DM attachments, persisted
DM sync, lists, starter packs, custom feeds, profile pinning, impressions,
reach, clicks, views, or arbitrary provider proxy calls.

## Official Bluesky API References

* [Bluesky API quickstart](https://docs.bsky.app/docs/get-started)
* [Creating posts, replies, images, and link cards](https://docs.bsky.app/docs/tutorials/creating-a-post)
* [API hosts and authentication](https://docs.bsky.app/docs/advanced-guides/api-directory)
* [Uploading video](https://docs.bsky.app/docs/tutorials/video)
