Skip to content

Buttondown newsletter

mnml-msg-buttondown is a terminal browser for Buttondown. List drafts, browse sent newsletters with per-issue open + click stats, peek the scheduled queue, and manage subscribers. Runs standalone in any terminal.

┌─ buttondown ──────────────────────────────────────────────────────────┐
│ ▸1.drafts (3) 2.sent (47) 3.scheduled (1) 4.subscribers (1248+) │
└───────────────────────────────────────────────────────────────────────┘
┌─ drafts (3) ──────────────────┐ ┌─ detail ────────────────────────────┐
│ ▸ Issue #48 — half-baked │ │ Subject Issue #48 — half-baked │
│ Reply to last week │ │ Status draft │
│ Untitled scratch │ │ Created 2026-06-05T00:00:00Z │
│ │ │ Word count 812 │
└───────────────────────────────┘ └─────────────────────────────────────┘
1-9 tab · Enter open · y ID · p publish · X unsubscribe · r refresh · q quit
Terminal window
cargo install --git https://github.com/chris-mclennan/mnml-msg-buttondown mnml-msg-buttondown
mnml-msg-buttondown --install

Buttondown uses a single API key.

Terminal window
export BUTTONDOWN_API_KEY=... # Settings → Programming
mnml-msg-buttondown --check # verify env + config

The API key grants full newsletter access — read, schedule, delete subscribers. Treat like a password. The TUI never logs the key; --check shows length + last 4 chars only.

~/.config/mnml-msg-buttondown/config.toml (scaffolded first run):

refresh_interval_secs = 60
[[tabs]]
name = "drafts"
kind = "drafts"
[[tabs]]
name = "sent"
kind = "sent"
[[tabs]]
name = "scheduled"
kind = "scheduled"
[[tabs]]
name = "subscribers"
kind = "subscribers"
kindWhat it shows
draftsUnsent drafts. p schedules the focused draft 5 min from now (v0.2 will add a picker).
sentAlready-shipped emails with open / click counts when reported.
scheduledEmails queued for a future send.
subscribersEvery subscriber, color-coded by type. X unsubscribes the focused one.
ChordAction
1-9 / TabSwitch tabs
/ k, / j, PgUp / PgDn, g / GNavigate
Enter / oOpen in Buttondown web UI
yYank the focused item’s id
pPublish draft (drafts tab). PATCH /emails/{id}status=scheduled, publish_date=+5m. Confirms [y/n].
XUnsubscribe (subscribers tab). DELETE /subscribers/{id}. Confirms [y/n].
rRefresh active tab
q / Esc / Ctrl+CQuit
Terminal window
mnml-msg-buttondown
:term mnml-msg-buttondown

Or <leader>iB after mnml-msg-buttondown --install.

  • 4xx surfaces as buttondown: <detail> verbatim from Buttondown’s error body.
  • Buttondown allows ~600 req/min; TUI never auto-retries 429 — refresh manually with r.

v0.1 fetches page 1 only (Buttondown default is 100 per page). When more results exist, the tab badge shows (N+). Real pagination is v0.2.

github.com/chris-mclennan/mnml-msg-buttondown. MIT.