2026-06-25
A simple tutorial based on Buttondown’s article “Send your next email newsletter from Terminal”.
Sending a newsletter from the terminal means creating, drafting, scheduling, or sending an email newsletter using command-line tools instead of clicking around in a web dashboard.
In simple terms:
You write your newsletter as text, send it to Buttondown’s API with a terminal command, and Buttondown turns it into a real newsletter email.
This is especially useful for developers, technical writers, open-source maintainers, and anyone who already works inside a code editor or terminal.
Buttondown is an email newsletter platform. It lets you write newsletters, manage subscribers, publish archives, and send emails to your list.
The interesting part is that Buttondown also has a REST API. That means you can control many newsletter actions with code, including:
Before starting, you need:
curl installed.Buttondown’s article notes that API access requires at least a Basic account.
Normally, you might write a newsletter in a web editor.
With this workflow, you write the newsletter as JSON:
{
"subject": "Hello, world!",
"body": "This is my first newsletter from the terminal.",
"status": "draft"
}
Then you send that JSON to Buttondown using curl.
Run this command in your terminal:
curl -s -X POST \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject": "Hello, world!", "body": "Yup, this is an email alright.", "status": "draft"}' \
"https://api.buttondown.com/v1/emails"
Replace YOUR_API_KEY with your real Buttondown API key.
This command creates a draft email in Buttondown.
It does not send the email immediately because the status is set to:
"status": "draft"
That is the safer option.
After the command runs, Buttondown returns a JSON response.
Inside that response, look for a preview or archive URL, such as:
https://buttondown.com/your-list-name/archive/hello-world/
Open that URL in your browser and check the email before sending it.
Do not skip this step. Sending broken formatting to your whole list is a dumb mistake and very easy to avoid.
For anything longer than one line, do not put the whole email directly inside the terminal command.
Create a file called email.json:
{
"subject": "Product Update: New Features This Week",
"status": "draft",
"body": "Hi everyone,\n\nThis week we shipped a few improvements:\n\n- Faster search\n- Better dashboard layout\n- Bug fixes in the login flow\n\nThanks for reading!"
}
Then send it with:
curl -s -X POST \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data @email.json \
"https://api.buttondown.com/v1/emails"
This is cleaner, easier to edit, and less likely to break.
Buttondown supports Markdown, so your email body can include formatting like:
# Weekly Update
Hello everyone,
This week we shipped:
- A new dashboard
- Better search
- Several bug fixes
Thanks for following the project.
Markdown is useful because it is readable as plain text but still becomes formatted content when published.
You have two basic options.
Upload your image somewhere else, then include it in Markdown:

Use this command:
curl -s -X POST \
-H "Authorization: Token YOUR_API_KEY" \
-F "image=@image.png" \
"https://api.buttondown.com/v1/images"
Buttondown returns an image URL.
Then place that URL inside your email body:

To schedule an email instead of creating only a draft, change the status to:
"status": "scheduled"
And add a publish date:
"publish_date": "2026-06-05T12:00:00Z"
Example email.json:
{
"subject": "Scheduled Product Update",
"status": "scheduled",
"publish_date": "2026-06-05T12:00:00Z",
"body": "This email was scheduled from the terminal."
}
Then run:
curl -s -X POST \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data @email.json \
"https://api.buttondown.com/v1/emails"
If you scheduled the wrong email, you can turn it back into a draft.
Use the email ID returned by Buttondown:
curl -s -X PATCH \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "draft"}' \
"https://api.buttondown.com/v1/emails/YOUR_EMAIL_ID"
Replace YOUR_EMAIL_ID with the real email ID.
If you are working on a software project, your Git commits can become a rough changelog.
Example:
git log --since="1 week ago" --pretty=format:"- %s"
This might produce:
- Fix login bug
- Add export button
- Improve dashboard performance
You can use that as the starting point for a developer newsletter.
But be careful: raw commit messages are usually bad for readers.
Bad:
- fix stuff
- update
- refactor auth
Better:
- Fixed a login issue that affected some users.
- Improved dashboard loading speed.
- Reorganized the authentication code to make future updates safer.
Automation helps, but it does not replace good writing.
Once the basic command works, you can wrap it in:
For example, a project could automatically create a draft newsletter every Friday using that week’s Git commits.
This does not mean you should automatically send everything. A better workflow is:
This workflow is useful because it keeps writing close to the development process.
Instead of thinking:
“I need to open a marketing tool and write an update.”
You think:
“I shipped something. I can turn the changelog into a newsletter right now.”
That makes communication faster and more consistent.
This is a good fit for:
This is not useful if:
The terminal can speed up the process. It cannot make boring content interesting by magic.
Sending a newsletter from the terminal means using Buttondown’s API to create, preview, schedule, or send emails with command-line tools.
The basic flow is:
curl.In one sentence:
This is newsletter publishing treated like code.