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 quitInstall
Section titled “Install”cargo install --git https://github.com/chris-mclennan/mnml-msg-buttondown mnml-msg-buttondownmnml-msg-buttondown --installButtondown uses a single API key.
export BUTTONDOWN_API_KEY=... # Settings → Programmingmnml-msg-buttondown --check # verify env + configThe 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
Section titled “Config”~/.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"Tab kinds
Section titled “Tab kinds”kind | What it shows |
|---|---|
drafts | Unsent drafts. p schedules the focused draft 5 min from now (v0.2 will add a picker). |
sent | Already-shipped emails with open / click counts when reported. |
scheduled | Emails queued for a future send. |
subscribers | Every subscriber, color-coded by type. X unsubscribes the focused one. |
| Chord | Action |
|---|---|
1-9 / Tab | Switch tabs |
↑ / k, ↓ / j, PgUp / PgDn, g / G | Navigate |
Enter / o | Open in Buttondown web UI |
y | Yank the focused item’s id |
p | Publish draft (drafts tab). PATCH /emails/{id} → status=scheduled, publish_date=+5m. Confirms [y/n]. |
X | Unsubscribe (subscribers tab). DELETE /subscribers/{id}. Confirms [y/n]. |
r | Refresh active tab |
q / Esc / Ctrl+C | Quit |
Two run modes
Section titled “Two run modes”Standalone
Section titled “Standalone”mnml-msg-buttondownHosted as a mnml Pty pane
Section titled “Hosted as a mnml Pty pane”:term mnml-msg-buttondownOr <leader>iB after mnml-msg-buttondown --install.
Errors + rate limits
Section titled “Errors + rate limits”- 4xx surfaces as
buttondown: <detail>verbatim from Buttondown’s error body. - Buttondown allows ~600 req/min; TUI never auto-retries
429— refresh manually withr.
Pagination
Section titled “Pagination”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.