Send an Email Newsletter from the Terminal

· PABLO'S DEVLOG


A simple tutorial based on Buttondown's article "Send your next email newsletter from Terminal".

What this means #

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.

What is Buttondown? #

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:

What you need #

Before starting, you need:

  1. A Buttondown account.
  2. API access enabled.
  3. Your Buttondown API key.
  4. A terminal.
  5. curl installed.
  6. Basic knowledge of JSON and Markdown.

Buttondown's article notes that API access requires at least a Basic account.

The basic idea #

Normally, you might write a newsletter in a web editor.

With this workflow, you write the newsletter as JSON:

1{
2  "subject": "Hello, world!",
3  "body": "This is my first newsletter from the terminal.",
4  "status": "draft"
5}

Then you send that JSON to Buttondown using curl.

Step 1: Create a simple draft newsletter #

Run this command in your terminal:

1curl -s -X POST \
2  -H "Authorization: Token YOUR_API_KEY" \
3  -H "Content-Type: application/json" \
4  -d '{"subject": "Hello, world!", "body": "Yup, this is an email alright.", "status": "draft"}' \
5  "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:

1"status": "draft"

That is the safer option.

Step 2: Preview the draft #

After the command runs, Buttondown returns a JSON response.

Inside that response, look for a preview or archive URL, such as:

1https://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.

Step 3: Use a separate JSON file #

For anything longer than one line, do not put the whole email directly inside the terminal command.

Create a file called email.json:

1{
2  "subject": "Product Update: New Features This Week",
3  "status": "draft",
4  "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!"
5}

Then send it with:

1curl -s -X POST \
2  -H "Authorization: Token YOUR_API_KEY" \
3  -H "Content-Type: application/json" \
4  --data @email.json \
5  "https://api.buttondown.com/v1/emails"

This is cleaner, easier to edit, and less likely to break.

Step 4: Write the body in Markdown #

Buttondown supports Markdown, so your email body can include formatting like:

 1# Weekly Update
 2
 3Hello everyone,
 4
 5This week we shipped:
 6
 7- A new dashboard
 8- Better search
 9- Several bug fixes
10
11Thanks for following the project.

Markdown is useful because it is readable as plain text but still becomes formatted content when published.

Step 5: Add an image #

You have two basic options.

Option A: Use an external image URL #

Upload your image somewhere else, then include it in Markdown:

1![Screenshot](https://example.com/screenshot.png)

Option B: Upload the image to Buttondown #

Use this command:

1curl -s -X POST \
2  -H "Authorization: Token YOUR_API_KEY" \
3  -F "image=@image.png" \
4  "https://api.buttondown.com/v1/images"

Buttondown returns an image URL.

Then place that URL inside your email body:

1![Screenshot](https://assets.buttondown.com/images/IMAGE_ID.png)

Step 6: Schedule the newsletter #

To schedule an email instead of creating only a draft, change the status to:

1"status": "scheduled"

And add a publish date:

1"publish_date": "2026-06-05T12:00:00Z"

Example email.json:

1{
2  "subject": "Scheduled Product Update",
3  "status": "scheduled",
4  "publish_date": "2026-06-05T12:00:00Z",
5  "body": "This email was scheduled from the terminal."
6}

Then run:

1curl -s -X POST \
2  -H "Authorization: Token YOUR_API_KEY" \
3  -H "Content-Type: application/json" \
4  --data @email.json \
5  "https://api.buttondown.com/v1/emails"

Step 7: Turn a scheduled email back into a draft #

If you scheduled the wrong email, you can turn it back into a draft.

Use the email ID returned by Buttondown:

1curl -s -X PATCH \
2  -H "Authorization: Token YOUR_API_KEY" \
3  -H "Content-Type: application/json" \
4  -d '{"status": "draft"}' \
5  "https://api.buttondown.com/v1/emails/YOUR_EMAIL_ID"

Replace YOUR_EMAIL_ID with the real email ID.

Step 8: Generate a newsletter from Git commits #

If you are working on a software project, your Git commits can become a rough changelog.

Example:

1git log --since="1 week ago" --pretty=format:"- %s"

This might produce:

1- Fix login bug
2- Add export button
3- 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:

1- fix stuff
2- update
3- refactor auth

Better:

1- Fixed a login issue that affected some users.
2- Improved dashboard loading speed.
3- Reorganized the authentication code to make future updates safer.

Automation helps, but it does not replace good writing.

Step 9: Automate the workflow #

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:

  1. Generate the draft automatically.
  2. Review and rewrite it manually.
  3. Preview the newsletter.
  4. Schedule or send it.

Why this is useful #

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.

When this is a good idea #

This is a good fit for:

When this is a bad idea #

This is not useful if:

The terminal can speed up the process. It cannot make boring content interesting by magic.

Simple summary #

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:

  1. Write the newsletter in Markdown or JSON.
  2. Send it to Buttondown with curl.
  3. Create it as a draft first.
  4. Preview it.
  5. Schedule or send it.
  6. Optionally automate the process with scripts or Git workflows.

In one sentence:

This is newsletter publishing treated like code.

References #

last updated: