Text Posts
Publish Bluesky posts through one REST call with length validation before sending.
Stop wrestling with the AT Protocol, session tokens, and rich-text facets. PostZen publishes to Bluesky through one simple endpoint - so you can focus on building your product.
No credit card required
import PostZen from '@postzen/node';
const postzen = new PostZen();
await postzen.posts.createPost({
body: {
content: 'Hello from Bluesky!',
publishNow: true,
platforms: [{
platform: 'bluesky',
accountId: 'your-bluesky-account-id',
}],
},
});WHY POSTZEN?
AT Protocol brings its own authentication, rate limits, media rules, and maintenance. PostZen replaces it with one predictable integration.

2.3M+ posts
2,000+ developersFEATURES
One complete API for Bluesky formats, controls, and scheduled publishing

Publish Bluesky posts through one REST call with length validation before sending.
Attach up to four images and preserve accessible alt text for every image.
Turn destination links into native preview cards without manually building embeds.
PostZen detects handles, hashtags, and links and creates clickable rich-text facets.
Send a Bluesky variant alongside X, LinkedIn, Threads, and other networks in one call.
Choose a future publish time or add Bluesky posts to your automatic queue.
Three steps to integrate the Bluesky Upload API

Sign up for PostZen and grab your API key from the dashboard.

Authorize your Bluesky account once. We manage OAuth, permissions, and publishing access for you.

POST to /v1/posts with Bluesky selected and your content or media. Done.
CODE EXAMPLE
One POST request to /v1/post — send a file or a public URL
const response = await fetch("https://api.postzen.dev/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer POSTZEN_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
platforms: [{ platform: "bluesky", accountId: "your-bluesky-account-id" }],
content: "Now publishing to Bluesky from PostZen 🦋",
mediaItems: [{ url: "https://cdn.example.com/launch-image.jpg", title: "Launch day dashboard" }],
scheduledFor: "2026-06-15T19:00:00Z",
tags: ["launch", "bluesky"]
})
});
const result = await response.json();
console.log("Scheduled successfully:", result.post._id);Still have questions?
No. Bluesky has no developer portal or API approval process. You connect with your Bluesky handle and an app password created in your Bluesky settings, and PostZen publishes through the AT Protocol for you.
In Bluesky, open Settings → Privacy and Security → App Passwords and create one. Add it to PostZen with your handle and you're connected - no OAuth flow to approve.
Bluesky allows 300 characters per post. PostZen validates length before publishing and warns if content is too long. Links, @mentions, and #hashtags become clickable rich-text facets automatically.
Not yet. PostZen supports text and up to 4 images with alt text per Bluesky post today. Video upload is on our roadmap.
Yes. App passwords are separate, revocable credentials that never expose your main Bluesky login. Revoke one in Bluesky settings anytime to disconnect PostZen, and the rest of your account is unaffected.
Yes. Set a scheduledFor timestamp and PostZen publishes at the exact time. You can also cross-post to X, Threads, LinkedIn, and other supported platforms in the same API call.
Join the 2,000+ developers who chose PostZen over building around disconnected platform tools. Same reliability, 10x less code.