← 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 || 'noreply@yourdomain.com',
    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 user@example.com --subject "Subject" --text "Body"');
  console.log('Optional: --html "<h1>HTML body</h1>" --from "sender@domain.com"');
  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="alerts@yourdomain.com"

Send a plain text email:

node send-email.js \
  --to team@yourcompany.com \
  --subject "Deployment complete" \
  --text "v2.1.0 deployed to production at $(date)"

Send an HTML email:

node send-email.js \
  --to user@example.com \
  --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 team@company.com \
  --subject "Deploy: $(git log --oneline -1)" \
  --text "Deployment succeeded at $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --from "deploy@company.com"

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 admin@company.com \
    --subject "BACKUP FAILED" \
    --text "Nightly backup failed at $(date)" \
    --from "alerts@company.com"

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 user@example.com \
  --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