← Back to all posts
2026-09-11 · MailAnvil Team

Build a CLI Email Sender with Node.js + MailAnvil

Sending emails from a terminal script is a common need for DevOps engineers, sysadmins, and backend developers. Whether you want deployment alerts, cron job failure notifications, or a quick way to test your email templates, a CLI tool saves time.

In this tutorial, you'll build a lightweight CLI email sender using Node.js and the MailAnvil API. The tool supports plain text and HTML, works in bash scripts, and takes about 20 lines of code.

Prerequisites

Project Setup

Create a new directory and initialize:

mkdir mailanvil-cli && cd mailanvil-cli
npm init -y

No external dependencies needed — we'll use Node's built-in fetch (available since Node 18).

The CLI Script

Create send-email.js:

#!/usr/bin/env node

const API_BASE = 'https://api.mailanvil.com/v1';
const API_KEY = process.env.MAILANVIL_API_KEY;

async function sendEmail({ to, subject, text, html }) {
  if (!API_KEY) {
    console.error('Error: MAILANVIL_API_KEY environment variable not set.');
    process.exit(1);
  }

  const body = {
    from: process.env.MAILANVIL_FROM || '[email protected]',
    to: [to],
    subject,
    text,
    html: html || text,
  };

  const res = await fetch(`${API_BASE}/send`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });

  const data = await res.json();

  if (!res.ok) {
    console.error(`Failed: ${data.error?.message || res.statusText}`);
    process.exit(1);
  }

  console.log(`Email queued. ID: ${data.id}`);
}

// Parse CLI arguments
const args = process.argv.slice(2);
const flags = {};
for (let i = 0; i < args.length; i += 2) {
  flags[args[i].replace(/^--/, '')] = args[i + 1];
}

if (!flags.to || !flags.subject) {
  console.log('Usage: node send-email.js --to [email protected] --subject "Subject" --text "Body"');
  console.log('Optional: --html "<h1>HTML body</h1>" --from "[email protected]"');
  process.exit(0);
}

sendEmail(flags);

Make it executable:

chmod +x send-email.js

Usage

Set your API key as an environment variable:

export MAILANVIL_API_KEY="your-api-key-here"
export MAILANVIL_FROM="[email protected]"

Send a plain text email:

node send-email.js \
  --to [email protected] \
  --subject "Deployment complete" \
  --text "v2.1.0 deployed to production at $(date)"

Send an HTML email:

node send-email.js \
  --to [email protected] \
  --subject "Invoice #1234" \
  --text "Your invoice is attached." \
  --html "<h1>Invoice #1234</h1><p>Total: Rp 149,000</p>"

Using in Bash Scripts

The real power is calling it from other scripts. Add it to a deployment script:

#!/bin/bash
set -e

# Deploy
echo "Deploying..."
./deploy.sh

# Notify team
node ~/mailanvil-cli/send-email.js \
  --to [email protected] \
  --subject "Deploy: $(git log --oneline -1)" \
  --text "Deployment succeeded at $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --from "[email protected]"

echo "Done."

Or use it in a cron job for failure alerts:

# In crontab — send alert if backup fails
0 3 * * * /usr/local/bin/backup.sh || \
  node /path/to/send-email.js \
    --to [email protected] \
    --subject "BACKUP FAILED" \
    --text "Nightly backup failed at $(date)" \
    --from "[email protected]"

Advanced: Read Body from File

For longer emails, pipe from a file:

// Add to send-email.js before sendEmail() call
if (flags.bodyFile) {
  const fs = await import('fs');
  flags.text = fs.readFileSync(flags.bodyFile, 'utf8');
}

Usage:

node send-email.js \
  --to [email protected] \
  --subject "Weekly report" \
  --body-file /tmp/report.txt

Error Handling

The MailAnvil API returns structured errors:

{
  "error": {
    "code": "UNVERIFIED_DOMAIN",
    "message": "Sending domain not verified"
  }
}

Common errors to handle:

Code Meaning Fix
UNVERIFIED_DOMAIN Domain DKIM not verified Verify in dashboard
SUPPRESSED Recipient is suppressed Check suppression list
RATE_LIMITED Too many requests Back off, check rate limits
UNAUTHORIZED Bad API key Check MAILANVIL_API_KEY

Why MailAnvil for CLI Tools

For Indonesian developers, MailAnvil has a few advantages for scripting:

Try MailAnvil free at mailanvil.com