Sam Patterson

FULLSTACK DEVELOPER

Using Listmonk for my Newsletter because Substack has no API

Published: February 18, 2025
Last updated: March 11, 2025 at 12:31 AM

In Which I use Open Source Self Hosted Tools like a Good Boy

Summary

Substack has no API and doesn’t fit into my publishing flow, so I self-hosted a newsletter management tool called Listmonk. It wasn’t super easy, but with AI help I figured out how to setup up Listmonk and have it automatically publish using Github Actions and Amazon SES.

Background

I’ve committed to writing more lately, and as a result I want to make it easy for people to follow my work.

I went ahead and integrated RSS, JSON, and Atom feeds into this site, and then turned my attention to Substack.

Guess what I learned? Substack has no API. Seriously.

My Publishing Flow

Here’s the way my blog works: I write a post in markdown, inside Obsidian. I copy this file into my website’s git repo, run the front end locally to check that it looks good, fix anything, then commit and publish. My site’s host (Netlify) automatically rebuilds my site when my repo changes (including updating the RSS feed), and my site uses a library to display markdown properly.

This makes it very easy for me to publish - I don’t need to use a browser interface at all. I practically live in Obsidian, so writing then committing and publishing a markdown file is second nature, but I strongly dislike Wordpress / Medium / Substack or any tool where I’m writing in browser. It feels slow, and having all the editing / formatting options is a distraction.

Because Substack has no API, it isn’t possible for me to publish to my blog and then have it automatically post to my substack. I could give up my flow in order to use Substack, but I’m a bit too crotchety for that.

Listmonk

Fortunately for me, I’ve only just started my Substack and posted a single article - I have no followers yet, so I’m not locked into that platform. So naturally … let’s see what open source alternatives there are for managing newsletters, subscribers, and email campaigns.

I’m already using a service called Pikapods that offers cheap hosting of open source projects. I paid them $3 last month to host a Hoarder instance, so that I could clear up some of my browser tabs but not feel FOMO (I swear I’ll look at them eventually).

I browsed their selection apps, looking for a newsletter management tool, and they had one: Listmonk. I searched around and found they had a good reputation. Pikapods estimated it would cost me another $1.50 a month to host this instance, so I figured all it was really costing me was my time, and I added a pod.

Screenshot

After a couple of minutes to set things up, it gave me the admin URL to visit, and I set everything up.

It’s straightforward, there are users (like the admin), subscribers (like you, right?), lists (groups of subscribers), and campaigns (the email sends).

Setting that up was easy, but of course this isn’t an email host itself, it’s just managing the list and triggering the emails going out. In order to wire this up, I need to use an email host.

Amazon SES

My personal email is on the same domain as this site, so I’ve already used a custom DNS with my email provider. But I want to use the same domain for the newsletter, complicating things slightly.

With AI help I find that this isn’t a problem - I can create a subdomain that will be managed by a different provider. I chose Amazon Simple Email Service (SES). They’re cheap, well documented, and each time I use a new Amazon service I get to add it to my LinkedIn profile.

I had to jump through a few credential hoops, but eventually I was signed up. They displayed my DNS records I needed to add to my DNS provider in order for the email to work. After too much copying and pasting, I finished, and Amazon saw the connection almost instantly (I don’t miss the days of slow DNS updates).

I then got my SMTP credentials, and logged back into the Listmonk server. I entered them and sent a test email - failure.

Screenshot

Listmonk has a default “from” address that needs to change, and I didn’t notice it at first. I eventually fixed that and then it worked!

Automation with Github Actions

I’ve now got all the pieces to replace Substack - my own publishing platform (personal blog), a newsletter management tool (Listmonk), and an email provider (Amazon SES).

Listmonk is connected to SES, but how do I connect my blog to Listmonk? I’m going to use Github Actions and connect it via an API.

I look through the Listmonk docs and find out how to create an API for Github to use. I then put the API key, the URL for the server, and the username into my Github repo as secrets so that they can be accessed from the notify-subscribers.yml file which manages the Github Action.

Screenshot

I dumped the Listmonk API docs into Claude and asked to create an action to send out an email to my subscribers when it detects a new blog post has been added. However, I also added in frontmatter into my markdown template with a field for send_newsletter, which will let me determine with a boolean if an article I push should trigger an email or not.

Here’s the file, I won’t share it here but it makes detailed use of the Listmonk API to ensure it’s formatted correctly.

I also had it build a test file so that I could trigger a send to test the integration without spamming my subscribers (currently, me, but I want that functionality for the future).

All in all this was about three hours worth of work, including writing this post, and should cost me ~$2 a month. SES is free unless I have a lot of emails to send, which seems reasonable. We’ll see if needing to maintain Listmonk myself in the long term is better than Substack, and perhaps it has other features I’ll really miss (like comments or better exposure).

I’ll update down the road with my thoughts.