How publishing works
Postwright publishes for you — so it needs a destination to publish to. This is the most important page to read before buying Pro. It lays out exactly where your blog can go, what works out of the box, and what takes extra work.

The model: destinations you own
Postwright is self-hosted and local-first. It runs on your machine, drafts your posts, and then hands each one to a publisher — a small adapter that knows how to deliver a post to one kind of destination. Postwright ships these publisher types, and each brand you run is pointed at one of them:
- WordPress — publishes through WordPress’s REST API with an application password. Updates only the posts it published, with tags, category, and featured image.
- Ghost — publishes through Ghost’s Admin API with a custom integration’s key (Ghost(Pro) Starter has no custom integrations; you need the Publisher plan or above, or a self-hosted Ghost).
- Beehiiv — publishes web posts, sent to no inbox, through Beehiiv’s API. Beehiiv lets only publications on its Pro or Enterprise plan create posts through its API, so this needs one of those plans.
- Git — writes the post as Markdown/MDX into a repo, commits it, pushes, and waits for your host to deploy. The primary, zero-config path.
- Folder — writes the post into an output directory for a static-site generator (Astro, Hugo, Jekyll, Eleventy, Next.js) that you build and deploy yourself.
- Webhook — sends the rendered post as a signed
POSTto any endpoint you run. This is how a CMS like WordPress connects: your site receives the payload and creates the post. - None — drafts stay in Postwright for you to copy out by hand.
The common thread: the destination is something you own and can point Postwright at. There is no Postwright-hosted blog in the middle.
Blog destinations at a glance
| Destination | Support | What’s involved |
|---|---|---|
| Self-hosted site (Git repo → GitHub → Vercel) | Works out of the box | Point Postwright at your repo checkout and its public URL. Commit → push → deploy → done. This is the reference stack below. |
| Static-site folder (Astro, Hugo, Jekyll, Eleventy…) | Works out of the box | Postwright writes Markdown into your content folder; you build and deploy the site with your own tooling. |
| WordPress | Some setup | Built-in publisher. Create an application password in WordPress (the site needs https, and the user needs the Author, Editor, or Administrator role), enter it with your site address in Settings, and use Test connection. No plugin to build. |
| Ghost | Some setup | Built-in publisher. Add a custom integration named Postwright in Ghost and paste its Admin API key. Needs a Ghost plan with custom integrations, or a self-hosted Ghost. A Ghost brand can also send newsletter issues through Ghost. |
| Beehiiv | Some setup | Built-in publisher, but Beehiiv only allows post creation through its API on its Pro or Enterprise plan. Posts are made as web posts that go to no inbox, checked as drafts before they are published. A Beehiiv brand can also send newsletter issues by Beehiiv email. |
| Any other CMS | Some setup | Use the webhook publisher: build a small endpoint (or plugin) that receives the signed post and creates it. |
| DEV and Hashnode (cross-posts) | Some setup | Not a blog destination: an extra copy of each post, canonical to your blog. See below. Hashnode’s API needs Hashnode Pro on your publication. |
| Go High Level | Custom work | No integration. In theory it could receive the webhook, but you’d be building and maintaining that yourself — plan on real effort. |
| Substack | Not supported | Posts are not supported. As of October 2026, Substack still has no publishing API or import hook Postwright can target — there’s nothing to plug into. Postwright never posts to Substack. For Substack Notes, it drafts the Note for you to post by hand (see the Social platforms page). |
The reference stack (works out of the box)
This is the exact stack Postwright was built and run on. If you set it up this way, blog publishing works with zero custom code:
- GitHub — a repo that holds your site and its blog content (Markdown/MDX). Postwright commits each post here.
- Vercel — connected to that repo, so every push to
maindeploys automatically. Postwright pushes, Vercel builds, your post goes live. (Netlify or any push-to-deploy host works the same way.) - Resend — for the newsletter side, a verified sending domain for your emails. (Mailgun is also supported, and a brand whose list lives in Kit, Mailchimp, Ghost, or Beehiiv can send through that platform instead.)
A static-site generator (the reference is Next.js with MDX; Astro, Hugo, Jekyll, and Eleventy all work) turns that content into your live site. You own every piece — the repo, the deploy, the domain, the subscriber list.
What actually happens when you publish (Git path)
- Postwright writes
your-post.mdxand a hero image into your repo’s content folder. - It commits just that post’s files (nothing unrelated) with a message like
publish: Your Title. - If pushing is enabled, it runs
git push origin main, which triggers your host’s deploy. - It then polls the post’s live URL until the page responds — so a newsletter that links to the post never goes out pointing at a page that isn’t live yet.
If a commit or push fails, Postwright surfaces the failure instead of recording a phantom success — you always know the real state.
Cross-posting to DEV and Hashnode (Pro)
A brand can also publish each blog post on DEV and on a Hashnode publication. Once the blog post is live (a few minutes after it), Postwright publishes the post on DEV or Hashnode as written, with its canonical address set to your blog post so search engines credit your blog. Each post is cross-posted at most once.
- DEV: save a DEV API key in Settings, Brand, then use Test connection.
- Hashnode: enter your publication and a personal access token. Hashnode’s API needs Hashnode Pro on that publication for every request; without it, Test says so and cross-posts fail.
- A post’s
channels:list decides for that post. Edits made after the cross-post aren’t sent.
Back-links on the blog (Pro)
Turn on Back-links on the blog in Settings, Brand (off by default). Once all of a post’s social posts are settled, Postwright adds one line to the end of the live blog post, such as “Discuss this on LinkedIn · Threads · Bluesky”, linking each one that went out with a public address. It never names a newsletter, a failed or skipped post, or a Slack or Discord message, and it rewrites the line only when the links change.
Back-links work on git, folder, WordPress, and Ghost destinations. They are not available for a webhook or Beehiiv, because Postwright can’t change one line of a post there without overwriting what was edited.
Where this leaves you
If you already run (or are happy to run) a self-hosted site on GitHub + Vercel, everything just works. WordPress, Ghost, and Beehiiv connect with a key and a test, no engineering needed. If you live entirely on Substack, Pro isn’t the tool for your blog. If you’re on another CMS, budget a little engineering time for the webhook bridge — then it’s automatic from there.