Notice (2023-08-16): This post is now outdated, as my website no longer uses Jekyll. Nearly all the features described in this post are no longer available on this site. I am leaving this up purely for archival purposes.

As part of my website revamp, I set up email updates for this blog. I used Buttondown, a free newsletter service. This is how I automated sending email updates from Jekyll.

Let’s be real: if sending email updates were a hassle, I wouldn’t do it. That’s why I chose Buttondown: it has an API that lets you programmatically send emails.

I did find it a bit difficult to start using the API, but that’s because I wasn’t very familiar with HTTP requests, and couldn’t figure out how to send emails with Python just by looking at the API documentation. I spent an afternoon with this Python requests tutorial and a Jupyter notebook. Once I got the hang of it, it was super easy.

In essence, all you need to do is:

  1. Sign up for a Buttondown account.

  2. Install1 requests:

$ pip install requests
  1. Run this tiny script, replacing the appropriate placeholders:
import requests
response = requests.post(
    "https://api.buttondown.email/v1/drafts",
    headers={"Authorization": "Token YOUR_API_KEY"},
    data={
        "subject": YOUR_EMAIL_SUBJECT,
        "body": YOUR_EMAIL_BODY
    })
print(response)

If all goes well, the API will return a 201 response, meaning a draft has been created on your Buttondown account. :) You can send the email outright by replacing https://api.buttondown.email/v1/drafts with https://api.buttondown.email/v1/emails.

Building off this, you can automatically populate the email subject and body from your site’s Atom feed entries. I set up a small Python script to do this – it is available here as a GitLab snippet.

As of now, I build my Jekyll site locally, so I run this script a few minutes after pushing updates. If I blogged more often, I’d put this in my crontab to run every night and send the latest post from the blog’s feed. You could also run the script as a post-commit git hook or a post-build Jekyll hook.


  1. Install Python and pip if you don’t have them already.