[↑] CodeOutbox← home

CodeOutbox docs

Email marketing that lives in your codebase: paste a form, write newsletters in Markdown, and send from the CLI, the API, or your coding agent. We run our own mail servers, so deliverability is handled.

Quickstart

  1. Sign in at demo.codeoutbox.com/signup — passwordless; you'll get an API key.
  2. Create a list (dashboard "+ Create list", or the API below).
  3. Embed the form on your site (dashboard "Copy embed").
  4. Send a Markdown newsletter with co send.

The CLI talks to the API; configure it once:

export CO_URL=https://demo.codeoutbox.com
export CO_TOKEN=co_live_...   # your API key

Capture subscribers

Every list has a form endpoint. Drop this anywhere — it works with no JavaScript (native POST → double opt-in):

<form action="https://demo.codeoutbox.com/f/<public_id>" method="POST">
  <input type="email" name="email" required placeholder="you@example.com">
  <button type="submit">Subscribe</button>
</form>

Or scaffold a styled, JS-enhanced version:

npx codeoutbox form --id <public_id> --base https://demo.codeoutbox.com

Submissions get a confirmation email (double opt-in). Unsubscribes and one-click List-Unsubscribe are handled for you.

Write & send

A campaign is Markdown with frontmatter, kept in your repo:

---
subject: Launch day 🚀
group: newsletter
preheader: We shipped.
---

Hi there 👋

We just **launched**. [Read the post](https://example.com/post).
co send launch.md          # dry run: recipients + spam-lint
co send launch.md --live   # actually send

Add send_at: 2026-07-01T09:00:00Z to the frontmatter to schedule it.

CLI reference

CommandWhat it does
co send <file> [--live]Preview or send a campaign
co sync [file]Reconcile lists from codeoutbox.json
co domains add|verify|listAuthenticate a sending domain
co brand show|setPer-tenant email branding
co webhooks add|list|rmEvent webhooks
co upgrade <plan> [--annual]Stripe checkout
co warmupIP warmup status
co token createMint an API key

API

REST + Bearer auth (your API key). Base: https://demo.codeoutbox.com.

# create a list
curl -X POST $CO_URL/v1/groups -H "Authorization: Bearer $CO_TOKEN" \
  -H 'Content-Type: application/json' -d '{"slug":"news","name":"News"}'

# add a (consented) subscriber
curl -X POST $CO_URL/v1/groups/news/subscribers -H "Authorization: Bearer $CO_TOKEN" \
  -H 'Content-Type: application/json' -d '{"email":"a@example.com","confirmed":true}'

# send
curl -X POST $CO_URL/v1/broadcasts -H "Authorization: Bearer $CO_TOKEN" \
  -H 'Content-Type: application/json' -d '{"source":"","confirm":true}'

Other endpoints: /v1/usage, /v1/broadcasts (list + stats), /v1/domains, /v1/webhooks, /v1/account (brand), /v1/billing/checkout.

Domain authentication

By default you send from our shared, authenticated domain. To send from your own domain (and remove limits), authenticate it:

co domains add news.yourdomain.com   # prints SPF / DKIM / DMARC records
# publish those TXT records in your DNS, then:
co domains verify news.yourdomain.com

Once verified, broadcasts send from noreply@news.yourdomain.com, DKIM-signed with your own key. You can also do this from the dashboard "Sending domains" card.

Event webhooks

Get subscriber events POSTed to your app:

co webhooks add https://your-app.com/hook --events subscriber.confirmed,subscriber.bounced

Events: subscriber.confirmed subscriber.unsubscribed subscriber.bounced subscriber.complained. Each request is signed:

X-CO-Event: subscriber.confirmed
X-CO-Signature: t=<unix>,v1=<hex>
# verify: v1 == HMAC-SHA256(secret, `${t}.${rawBody}`)

Branding

Tenant email wears your brand, not ours. It auto-derives from your verified domain; override anytime:

co brand set --name "Acme" --color "#2E7D32" --logo https://acme.com/logo.png

Scheduling

Add send_at (ISO 8601, UTC) to the campaign frontmatter and co send --live queues it; a durable worker delivers it at the scheduled time:

---
subject: Weekly digest
group: newsletter
send_at: 2026-07-01T09:00:00Z
---

Coding agent (MCP)

CodeOutbox ships an MCP server, so an AI coding assistant can create lists, add subscribers, and send broadcasts (confirm-gated) for you — "set up my newsletter and send the launch" in one prompt.