Back to Blogs
9 min readMar 21, 2026

Resend CLI: Send Production Emails Directly From Your Terminal

A complete developer guide to Resend CLI - authenticate, send emails, manage domains, and integrate with CI/CD pipelines. Built for humans, AI agents, and automation.

resend cli tutorialsend emails from terminalresend api cli toolemail automation cliresend cli githubnodejs email cli

Resend CLI: Send Production Emails Directly From Your Terminal

If you're building a SaaS product, side project, or automation pipeline, you've probably needed to send transactional emails.

Resend CLI is the official command-line tool from Resend that lets you send emails, manage domains, and automate workflows - all without leaving your terminal.

This guide covers everything from installation to production use cases.

Resend CLI

Resend CLI

Why Use Resend CLI Instead of the SDK?

The Resend Node.js SDK is great for application code, but the CLI shines in different scenarios:

Quick testing without writing code
Send test emails instantly to verify templates, check deliverability, or debug formatting.

CI/CD pipeline notifications
Send deployment alerts, build status updates, or error reports directly from GitHub Actions, Jenkins, or CircleCI.

Local development workflows
Test email flows without spinning up your entire application stack.

Script automation
Integrate email sending into bash scripts, cron jobs, or data processing pipelines.

AI agent integrations
Built for machine-readable output — perfect for AI coding assistants like Cursor or Claude Desktop.

The CLI is built for humans and machines — interactive when you need it, scriptable when you don't.

Installation (4 Different Methods)

cURL (Fastest for Linux/macOS)

curl -fsSL https://resend.com/install.sh | bash

This installs the binary to ~/.resend/bin/ and updates your PATH automatically.

Node.js (Cross-platform)

npm install -g resend-cli

Requires Node.js 20+. Works everywhere npm does.

Homebrew (macOS/Linux)

brew install resend/cli/resend

Keeps the CLI updated through Homebrew's update cycle.

PowerShell (Windows)

irm https://resend.com/install.ps1 | iex

Or download the .exe directly from GitHub releases.

Authentication: 3 Ways to Provide Your API Key

The CLI resolves your Resend API key using this priority chain:

  1. --api-key flag (highest priority)

    resend --api-key re_xxx emails send ...
  2. RESEND_API_KEY environment variable

    export RESEND_API_KEY=re_xxxresend emails send ...
  3. Config file (lowest priority)

    resend login

If no key is found, the CLI exits with error code auth_error.

Interactive Login

resend login

The CLI will:

  1. Check for an existing key
  2. Offer to open your Resend dashboard to create one
  3. Prompt for the key with masked input
  4. Validate it against the API before saving

Your key is stored at ~/.config/resend/credentials.json with 0600 permissions (owner read/write only).

Non-interactive Login (CI/CD)

resend login --key re_xxxxxxxxxxxxx

No prompts — perfect for CI pipelines.

Sending Your First Email

Basic Text Email

resend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --subject "Hello from the terminal" \  --text "This email was sent using Resend CLI."

HTML Email

resend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --subject "Weekly Newsletter" \  --html "<h1>Welcome</h1><p>Your HTML content here.</p>"

HTML Email from File

resend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --subject "Newsletter" \  --html-file ./templates/newsletter.html

This is powerful for template-based workflows.

Advanced Email Options

Multiple Recipients

resend emails send \  --from "you@yourdomain.com" \  --to alice@example.com bob@example.com charlie@example.com \  --subject "Team update" \  --text "Hello everyone"

Space-separated recipient list.

CC, BCC, and Reply-To

resend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --cc manager@example.com \  --bcc archive@example.com \  --reply-to noreply@example.com \  --subject "Meeting notes" \  --text "Attached are the notes from today's meeting."

Using a Different API Key for One Command

resend --api-key re_other_key emails send \  --from "staging@yourdomain.com" \  --to test@example.com \  --subject "Staging test" \  --text "Testing with staging credentials"

The --api-key flag overrides all other key sources.

Interactive vs Non-Interactive Mode

The CLI automatically detects whether you're running it in a terminal or a script.

Interactive Mode (Terminal)

When run in a TTY (terminal), missing required flags trigger prompts:

resend emails send# CLI will prompt for: from, to, subject, and body

This is perfect for quick manual sends.

Non-Interactive Mode (Scripts/CI)

When piped or run in CI, all required flags must be provided:

echo "" | resend emails send --from "you@yourdomain.com"# Error: Missing required flags: --to, --subject

The CLI will not prompt — it will error with a list of missing fields.

Managing Multiple Accounts with Profiles

If you work across multiple Resend teams or use different API keys for staging/production, profiles make this easy.

Switch Between Profiles

resend auth switch

Interactive profile switcher — no need to log out and back in.

Use a Specific Profile for One Command

resend domains list --profile productionresend emails send --profile staging --from ...

The --profile (or -p) flag overrides the active profile.

CI/CD Integration Examples

GitHub Actions

name: Send Deployment Notificationon:  push:    branches: [main]jobs:  notify:    runs-on: ubuntu-latest    env:      RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}    steps:      - name: Install Resend CLI        run: curl -fsSL https://resend.com/install.sh | bash      - name: Send email        run: |          resend emails send \            --from "deploy@yourdomain.com" \            --to "team@yourdomain.com" \            --subject "Deploy complete: ${{ github.sha }}" \            --text "Version ${{ github.sha }} deployed successfully."

GitLab CI

deploy_notify:  stage: notify  variables:    RESEND_API_KEY: $RESEND_API_KEY  script:    - curl -fsSL https://resend.com/install.sh | bash    - resend emails send --from "ci@yourdomain.com" --to "team@yourdomain.com" --subject "Build passed" --text "Deployment successful"

CircleCI

version: 2.1jobs:  notify:    docker:      - image: cimg/node:20.0    environment:      RESEND_API_KEY: $RESEND_API_KEY    steps:      - run: npm install -g resend-cli      - run: resend emails send --from "ci@yourdomain.com" --to "team@yourdomain.com" --subject "Pipeline complete" --text "Build finished"

JSON Output for Scripting

The CLI automatically switches to JSON output when:

  • Running in a non-TTY environment (pipes, CI)
  • Using the --json flag
  • Using the --quiet flag

Example: Extract Email ID

resend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --subject "Test" \  --text "Testing" \  --json | jq -r '.id'# Output: 49a3999c-0ce1-4ea6-ab68-afcd6dc2e794

Example: Error Handling in Scripts

response=$(resend emails send --from ... --to ... --subject ... --text ... --json)if echo "$response" | jq -e '.error' > /dev/null 2>&1; then  echo "Email send failed: $(echo "$response" | jq -r '.error.message')"  exit 1else  echo "Email sent successfully: $(echo "$response" | jq -r '.id')"fi

Environment Diagnostics with resend doctor

The doctor command runs health checks on your CLI setup.

resend doctor

Checks performed:

  • CLI version (detects updates)
  • API key presence and masking
  • Domain verification status
  • AI agent detection (Cursor, Claude Desktop, VS Code MCP)

Example Output

  Resend Doctor  ✔ CLI Version: v1.6.0 (latest)  ✔ API Key: re_...xxxx (source: env)  ✔ Domains: 2 verified, 0 pending  ✔ AI Agents: Detected: Cursor, Claude Desktop

JSON Mode for Automation

resend doctor --json | jq '.checks[] | select(.status == "fail")'

Practical Use Cases for Solo Developers

1. Send yourself deployment alerts

# In your deploy scriptresend emails send \  --from "deploy@yourdomain.com" \  --to "you@yourdomain.com" \  --subject "Deploy successful: $(git rev-parse --short HEAD)" \  --text "Your changes are live."

2. Test email templates locally

# Iterate on template designresend emails send \  --from "test@yourdomain.com" \  --to "you@yourdomain.com" \  --subject "Template preview" \  --html-file ./email-templates/welcome.html

3. Send error reports from cron jobs

# In your cron scriptif ! ./backup.sh; then  resend emails send \    --from "cron@yourdomain.com" \    --to "you@yourdomain.com" \    --subject "Backup failed" \    --text "Check server logs immediately."fi

4. Send weekly analytics summaries

# Weekly report scriptreport=$(python generate_weekly_report.py)resend emails send \  --from "analytics@yourdomain.com" \  --to "you@yourdomain.com" \  --subject "Weekly Analytics: $(date +%Y-%m-%d)" \  --text "$report"

Error Codes Reference

When things go wrong, the CLI exits with code 1 and outputs structured JSON.

Error CodeCause
auth_errorNo API key found or client creation failed
missing_keyNo --key provided in non-interactive mode
invalid_key_formatKey does not start with re_
validation_failedResend API rejected the key
missing_bodyNo --text, --html, or --html-file provided
file_read_errorCould not read the file passed to --html-file
send_errorResend API returned an error

Example error output:

{  "error": {    "message": "No API key found",    "code": "auth_error"  }}

Configuration File Locations

The CLI respects platform conventions:

PlatformConfig DirectoryInstall Directory
Linux~/.config/resend/ (respects $XDG_CONFIG_HOME)~/.resend/bin/
macOS~/.config/resend/~/.resend/bin/
Windows%APPDATA%\resend\%USERPROFILE%\.resend\bin\

Credentials file: credentials.json (0600 permissions)

When NOT to Use Resend CLI

The CLI is not ideal for:

  • Application code — Use the Resend Node.js SDK or other SDKs
  • Bulk email sends — Use the API's batch endpoint or SDK methods
  • Complex templating logic — Better handled in application code with a templating engine

The CLI is for quick sends, testing, automation, and CI/CD — not for replacing your transactional email infrastructure.

Quick Comparison: CLI vs SDK vs API

FeatureCLISDKAPI
Install time1 commandnpm installNo install
AuthLogin + profilesEnvironment variableAPI key in code
Use caseTerminal, CI/CD, scriptsApplication codeDirect HTTP
InteractiveYes (optional)NoNo
JSON outputYesProgrammaticJSON response
Best forTesting, automationProduction appsCustom integrations

Final Thoughts

Resend CLI bridges the gap between "I need to send a quick email" and "I need to integrate email into my pipeline."

For solo developers and small teams, it's a productivity multiplier:

  • No boilerplate code for one-off sends
  • CI/CD notifications in 2 lines
  • Local template testing without spinning up servers
  • Profile switching for multi-account workflows

If you're already using Resend, the CLI is a tool you'll reach for daily.

Quick Reference

# Installcurl -fsSL https://resend.com/install.sh | bash# Authenticateresend login# Send emailresend emails send \  --from "you@yourdomain.com" \  --to recipient@example.com \  --subject "Subject" \  --text "Body"# Check setupresend doctor# Get helpresend --helpresend emails send --help

License: MIT
Maintained by: Resend

Related Blogs

View all