Back to writing
DispatchDevelopment· Jul 10, 2026 · 2 min read

Writing Past the Free Tier

Buttondown's free plan blocks the two features that matter most for a newsletter — automation and custom CSS. About two hundred lines of Python in the publish workflow walked around both. The plan I am paying for is $0.

The newsletter you are reading went out automatically on a Friday morning, three minutes after the post went live on the site.

It is styled in the same broadsheet system as the rest of this journal — Newsreader at 19 pixels, vermilion link color, the same short centered rule between sections.

But I had to get Claude to figure out a workaround.

Buttondown’s free plan blocks two things. The first is RSS-to-email automation — the feature that watches a feed and sends each new post as an email when it appears. That is the entire reason most writers use Buttondown. The second is custom CSS — the feature that lets the email actually look like the website it came from. Both blocks surfaced as crisp 400-series errors during setup, complete with neat error codes and a link to upgrade.

These are not arbitrary blocks. They are precisely the two features that produce the most willingness to pay. A free-tier limit is a pricing experiment — vendors gate the features customers want most, because that is the line where the credit card comes out. I do not begrudge them the experiment.

I just had time, and Claude Max subscription.


Two Walls, One Script

The publish workflow on this site already runs on a cron. Every Friday morning at 14:30 UTC, it promotes the oldest draft from _drafts/ into _posts/, rewrites the date in the front matter, builds the site, and deploys to GitHub Pages. Adding a final step to that workflow that POSTs the same post to Buttondown’s API — bypassing the dashboard’s RSS-to-email feature entirely — was about thirty lines of YAML and one hundred and fifty lines of Python.

The Python script does the boring, necessary things. It reads the front matter for the title. It strips the Jekyll chrome that does not render in email — the marginalia asides, pull-quotes, custom deposition blocks. It rewrites relative links to absolute ones, because /2024/09/09/foo.html is meaningless in a Gmail tab. It converts kramdown footnotes into a numbered Notes section, because Buttondown’s Markdown renderer does not handle them natively.

It then renders to HTML and inlines the broadsheet styles per element. Inline styles are the workaround for the second wall — the same rules documented in bin/newsletter.css (the file the script would PATCH onto the newsletter object if the free plan would accept it), copied into a Python dict because the API returned css__not_allowed.

Inline styles are more reliable anyway. Outlook strips <style> blocks and ignores @import. Inline is the only form every email client honors without negotiation.


What This Costs

The whole pipeline cost an afternoon. The plan I am paying for is $0. The next plan up at Buttondown is $108 a year.

The math is not interesting on its own. What is interesting is that the same shape of math holds for a lot of SaaS product walls. The features that get gated are usually the features that someone with a couple of hours and access to an LLM can replicate against the public API. Vendors price for the median customer, not the curious one, and certainly not for the AI-enabled customer.

Whether to do that or to pay for the gate is a personal call. I happen to find the workaround slightly more enjoyable than the upgrade — the workaround leaves a small, well-documented Python file in the repo that does exactly what I need, and nothing else. The upgrade would have left a recurring line item.

If this dispatch arrived in your inbox, that script is what got it there.