yeetpostyeetpost

How to sendfrom

Follow these steps to connect Bluesky post, send from TypeScript, and track delivery.

Bluesky speaks the AT Protocol, so there is no OAuth dance to sit through. You create an app password in your own Bluesky settings, paste it into yeetpost with your handle, and delete it whenever you like: every session made from that password dies with it, and your account password is never involved. In plain TypeScript this is a few lines in any Node process: a worker, a one-off script or a deploy step that already knows what to say.

What Bluesky takes

How you connectAn app password from Bluesky Settings, App Passwords, plus your handle
Connection slugbluesky for the first account, then a slug built from the handle
Text limit300 graphemes, so a multi-codepoint emoji counts once
ImagesUp to 4 per post, 1 MB each, png, jpeg, gif or webp
Alt textYes, sent with each image
ThreadsYes, up to 24 replies under the head post
First commentNo, LinkedIn only
SchedulingYes
Permalinkhttps://bsky.app/profile/<handle>/post/<record key>
Per-post feeNone
1

Connect your platform

Connect your Bluesky account to yeetpost with an app password, never your account password:

  1. In Bluesky, open Settings, then App Passwords, and create one
  2. Go to app.yeetpost.com
  3. Click Add connection and select Bluesky
  4. Paste your handle (you.bsky.social) and the app password (xxxx-xxxx-xxxx-xxxx)
  5. Running your own PDS? Open On your own server? Set the service URL and give the host. It has to be https, and the default is https://bsky.social

The account is identified by its DID, not by the handle, so renaming your handle later does not break the connection.

Paste your connection slug here and we'll auto-fill it into the code examples below.

2

Get your API key

Get your API key from the yeetpost dashboard:

  1. Go to app.yeetpost.com/app/settings
  2. Copy your API key

Paste your API key here and we'll auto-fill it into the code examples below.

3

Send your post

Install the yeetpost package:

npm install yeetpost

Export your API key so the process can read it:

export YEETPOST_API_KEY=<your-api-key>

Send a post:

import { yeetpost } from "yeetpost"; await yeetpost({ connection: "<your-connection-slug>", text: "Hello from yeetpost!", });

To post to several connections in one call, use the JSON endpoint. It answers with one result per connection and accepts an Idempotency-Key, so a retry cannot double-post:

const response = await fetch("https://api.yeetpost.com/api/v2/posts", { method: "POST", headers: { "x-api-key": process.env.YEETPOST_API_KEY!, "content-type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ text: "Hello from yeetpost!", connectionSlugs: ["<your-connection-slug>"], }), }); const { results } = await response.json(); for (const result of results) { console.log(result.connectionSlug, result.status, result.url); }

Read each result.status rather than the HTTP status alone: one connection can fail while the rest go out.

4

Track your posts

Monitor all your posts from the yeetpost dashboard:

  1. Go to the Feed tab in the yeetpost dashboard
  2. View all posts sent via yeetpost, including status and timestamps
5

Review the security checklist

Review the Security Checklist to ensure your implementation is secure.

When a Bluesky post is refused

Each of these fails only the Bluesky item. Every other connection on the same request still goes out. The full vocabulary is in the errors reference.

CodeStatusWhen
invalid_request400Text over 300 graphemes, in the post or in any thread segment
media_unsupported400More than 4 images, or an image over 1 MB
shape_unsupported400A firstComment was given. Bluesky has no first comment
unauthorized401The app password was revoked. Create a new one and reconnect
platform_rejected422The server said no, for example a duplicate post
internal_server_error500Our fault. Quote the req_id when you report it

Bluesky FAQ

Do I need my Bluesky account password?

No, and you should not use it. An app password only posts. You create it under Settings, App Passwords, and you can revoke it at any time without touching your account.

Why is my emoji-heavy Bluesky post accepted when it looks longer than 300?

The limit is graphemes, not code points. A flag or a skin-tone emoji is several code points and one grapheme, so it counts once. The check runs before anything is published.

My thread came back sent but only two replies are there. Why?

Bluesky cannot delete a half-published thread on our behalf, so a refused reply stops the chain and leaves what already went out standing. Read threadCount in the result instead of assuming the whole thread landed.

Does an image over 1 MB fail the whole post?

No. Only the Bluesky item comes back failed with media_unsupported. Every other connection named in the same request still goes out.

Does the yeetpost package work outside Node?

It is a thin wrapper over the same HTTP endpoint, so anywhere you have fetch and can keep a secret it works. Do not run it in a browser bundle: the key would be readable by anyone loading the page.

Related guides

Related resources

Copy this guide (with your values) for use with LLMs or sharing with colleagues.