CLI

CLI Quickstart

Install the official mailblastr CLI and send your first email from the terminal in three commands.

MailBlastr ships an official command-line tool. mailblastr-cli (5.0.0 on npm) installs a `mailblastr` command that covers the whole API — sends, domains, contacts, segments, topics, campaigns, templates, automations, webhooks, events, logs and polls. It wraps the official `mailblastr` Node.js SDK, so a CLI call and an SDK call hit exactly the same endpoints.

Every command prints the API response as JSON on stdout, which makes the CLI both the quickest way to try an endpoint by hand and a safe building block in scripts and CI.

Prerequisites

  • Node.js 18 or newermailblastr-cli declares engines.node: ">=18".
  • A MailBlastr API key — the mb_-prefixed secret you create in the dashboard.
  • A verified domain to send from.

1. Install the CLI

Install globally
npm install -g mailblastr-cli

# the package is mailblastr-cli; the command it installs is mailblastr
mailblastr --version
# 5.0.0

Rather not install anything? Run it straight from npm — name both the package and the binary, because they differ:

npx --package mailblastr-cli@5.0.0 mailblastr --version

--help works at every level: mailblastr --help lists the resource groups, mailblastr emails --help lists that group's subcommands, and mailblastr emails send --help lists every flag.

2. Authenticate

There is no login step. Every invocation that talks to the API resolves your key from the MAILBLASTR_API_KEY environment variable, or from --api-key on that command; with neither, the CLI exits 1 with a cli_error. The one exception is mailblastr webhooks verify, which checks a signature locally, makes no request, and therefore takes no key — passing --api-key to it fails with an unknown-option error. Export your key once so it stays out of your shell history, then prove it works:

export MAILBLASTR_API_KEY=mb_xxxxxxxxx

# any command exercises the key — this one lists your sending domains
mailblastr domains list

Pass --base-url (or set MAILBLASTR_BASE_URL) to point the CLI at a different API host.

Never paste a live key into a command you will commit or share — keep it in an environment variable or your CI secret store. Key lifecycle is dashboard-only (mailblastr api-keys list is the CLI's entire key surface), so a leaked key cannot mint, widen, or revoke another. See API keys.

3. Send your first email

Send from your verified domain to delivered@mailblastr.dev, the mailbox simulator: it is intercepted before the provider is contacted and synthesizes a delivery, so nothing reaches a real inbox. --to, --cc, --bcc and --reply-to are repeatable and also accept comma-separated values.

mailblastr emails send
mailblastr emails send \
  --from 'Acme <hello@yourdomain.com>' \
  --to delivered@mailblastr.dev \
  --subject 'Hello from the CLI' \
  --html '<p>Your first email 🎉</p>'

A successful send prints the new email id — the same body POST /emails returns:

{
  "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"
}
Use the simulator, not a documentation domain: example.com, example.net, example.org and anything under .test, .invalid, .localhost or .example are blocked outright and answer 422. Simulator sends still debit your quota per recipient, exactly like a real send.

4. See what happened

Read the email back by id for its current status and ordered event log, or list your recent sends:

mailblastr emails get 49a3999c-0ce1-4ea6-ab68-afcd6dc2e794
mailblastr emails list --limit 5
mailblastr emails list --status delivered --search invoice
emails get (trimmed)
{
  "object": "email",
  "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794",
  "from": "Acme <hello@yourdomain.com>",
  "to": ["delivered@mailblastr.dev"],
  "subject": "Hello from the CLI",
  "status": "delivered",
  "last_event": "delivered",
  "events": [
    { "type": "sent", "created_at": "2026-06-23T10:00:00.000Z" },
    { "type": "delivered", "created_at": "2026-06-23T10:00:04.512Z" }
  ]
}

Output and exit codes

Responses are pretty-printed JSON by default; --json switches to compact JSON for piping into jq. stdout stays JSON-only either way — a failure prints its error object to stderr and exits 1, so mailblastr … | jq never has to strip a diagnostic.

id=$(mailblastr emails send --json \
  --from 'Acme <hello@yourdomain.com>' \
  --to delivered@mailblastr.dev \
  --subject 'Hello from the CLI' \
  --text 'It works!' | jq -r '.id') || exit 1

The error object is always { statusCode, name, message }. Branch on name, never on message:

Where it came from`statusCode``name`
The API rejected the requestthe HTTP statusthe API's reason, e.g. validation_error, daily_quota_exceeded
The request never reached the API0network_error
The CLI rejected your flags before sendingnullcli_error
See the error reference for every name the API can return.

Beyond the first send

A few flags on emails send worth knowing early:

  • --text alongside (or instead of) --html, plus --preview-text for the inbox preheader.
  • --template-id or --template-alias with --variables '{"first_name":"Ada"}' to send a stored template.
  • --attachment ./invoice.pdf (read and base64-encoded locally) or --attachment-url (fetched server-side) — both repeatable, capped at 25 MB per file and 40 MB per message. See Attachments.
  • --idempotency-key order-12345 on emails send and emails batch so a retry cannot send twice. See Idempotency keys.
  • mailblastr emails batch --file ./batch.json to send up to 100 emails in one request. See Batch sending.

Scheduling uses --scheduled-at — an ISO 8601 timestamp or a phrase like in 1 min, up to 30 days ahead. A scheduled message skips the mailbox simulator, so schedule to a real address you control instead:

mailblastr emails send \
  --from 'Acme <hello@yourdomain.com>' \
  --to you@yourdomain.com \
  --subject 'Your weekly digest' \
  --html '<p>Here is what you missed.</p>' \
  --scheduled-at 2026-09-01T09:00:00Z

# reschedule or cancel while it is still pending
mailblastr emails update 49a3999c-0ce1-4ea6-ab68-afcd6dc2e794 --scheduled-at 'in 2 hours'
mailblastr emails cancel 49a3999c-0ce1-4ea6-ab68-afcd6dc2e794
Do not pair delivered@mailblastr.dev with --scheduled-at: the simulator only fires on an immediate send, so a scheduled message to it is treated as suppressed and rejected with 422. See Schedule emails.

Next steps

  • The full command surface, plus the equivalent curl cookbook: CLI.
  • Non-interactive patterns for agents and CI — stdin piping, batches, safe retries, webhook feedback loops: CLI for AI agents.
  • A typed client instead of a shell: the official SDKs for Node.js, Python, Go, Ruby, PHP, Rust, Java and .NET.
  • Every endpoint and field: the API reference.