Posting to Bluesky Programmatically with the AT Protocol
Bluesky is built on the AT Protocol, and the official @atproto/api package makes posting straightforward.
Install
npm install @atproto/api Log in and post
import { AtpAgent, RichText } from '@atproto/api'; const agent = new AtpAgent({ service: 'https://bsky.social' }); await agent.login({ identifier: 'you.bsky.social', password: process.env.BSKY_APP_PASSWORD }); const rt = new RichText({ text: 'New post: https://mystite.com/my-article' }); await rt.detectFacets(agent); await agent.post({ text: rt.text, facets: rt.facets }); Tips
- Use an app password, not your main password.
- Posts are limited to 300 characters — share a teaser plus a link.
-
detectFacetsturns URLs and mentions into clickable links.

