Last updated: September 2026

Can I cross-post to Bluesky if I self-host my own PDS?

Yes, and the mechanism that makes it work is the same one that makes the connection safe: atproto OAuth resolves your personal data server from your handle. Nothing is hardcoded to bsky.social, so an account on a server you run connects exactly like any other.

The catch is not on your side. Almost no third-party tool handles this, and the reason is worth understanding before you spend an evening debugging one.

What actually happens when you connect

1

You type your handle

That is the only thing the tool needs. Not a server address, not a credential.

2

The handle resolves to your server

Your domain answers for the handle, and the flow follows it wherever it points.

3

You sign in on your own server

The password never passes through the tool, because the tool is not showing the form.

4

The tool receives a scoped grant

It can create posts and upload images. You can revoke that grant without touching anything else.

Handle resolution is the whole trick

Because step two is a lookup rather than a constant, self-hosting is not a special case that has to be supported. It is what falls out of doing the flow correctly. A tool that resolves your handle already works with your server without anyone having tested it against yours.

Why most tools break here

The common implementation takes a handle and an App Password, then creates a session against a host chosen at build time. For an account on the default server that works and nobody notices the assumption. For everyone else it fails, sometimes with an error that says nothing useful about the real cause.

This is the same design decision covered in whether you have to give a scheduling tool your Bluesky password, and self-hosting is where its cost becomes obvious rather than theoretical. An App Password flow has no reason to ask where your account lives, so it does not, so it guesses.

Ten-second test before you sign up for anything

Start the connect flow and watch the address bar. OAuth sends you to your own server and back. If you never leave the tool and it wants a string generated in Bluesky settings, the host it will talk to is whatever the developer typed, and your server is unlikely to be it.

Once connected, nothing else is different

Posting is the same call regardless of where the account lives. Your handle can be your own domain, the post is created in your repository on your server, and the X half of a cross-post is untouched by any of this.

bash
curl -X POST https://opentweet.io/api/v1/posts \
  -H "Authorization: Bearer ot_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Posted from an account on my own server.",
    "platforms": ["x", "bluesky"],
    "publish_now": true
  }'

The same limits apply wherever the account is hosted: 300 characters, up to 4 images at 2MB each with alt text, threads yes, video no, and no analytics read back from Bluesky. A post too long for Bluesky is skipped there with the reason recorded and still publishes on X. The parameter reference is in the cross-posting docs.

Costs are unchanged too. Publishing to Bluesky is free on any server, so the entire bill for a cross-posting setup is the X side, as worked through in what cross-posting costs.

7-day free trial. Cancel anytime.

Frequently asked questions

Can I cross-post to Bluesky if I self-host my own PDS?

Yes. atproto OAuth resolves your personal data server from your handle, so an account on a server you run connects the same way as one on bsky.social. Nothing in the flow assumes a single host, and your handle can be your own domain.

Why do so many tools fail with a self-hosted PDS?

Because they take an App Password and a handle and then talk to a host they picked at build time. That works for accounts on the default server and quietly fails for everyone else. It is not a policy against self-hosting, it is a shortcut in the auth implementation.

Do I need to register my server with anyone?

No. There is no directory to be listed in, no API key to apply for and no approval step, because Bluesky issues no keys at all. Your server answers for your handle, and the OAuth flow follows it there.

Does a custom domain handle work?

Yes. Handle resolution is the mechanism the whole flow is built on, so a handle on your own domain is the normal case rather than an edge case. You type the handle, you land on your own server to sign in, and you come back with a scoped grant.

Are the posting limits different on my own server?

Treat them as the same. OpenTweet applies the same rules wherever the account lives: 300 characters per post, up to 4 images at 2MB each with alt text, and threads. Video does not publish to Bluesky and no analytics are read back, on any server.

How do I check whether a tool really supports my PDS?

Start the connect flow and watch where you sign in. If you type only your handle and the tool sends you to your own server for the password, it is doing OAuth and it will work. If the sign-in form lives inside the tool and asks for an App Password, the host it talks to is whatever it hardcoded.

Your server, your handle, one draft

atproto OAuth resolves wherever your account lives. X in the same call, flat $11.99 a month.

7-day free trial. Cancel anytime.