Resend CLI: Send and Manage Email from the Terminal
The Resend CLI is the official command-line tool for Resend, an email platform built for developers. Install it with npm install -g resend-cli or brew install resend/cli/resend, authenticate with resend login, and then send emails, manage domains, and automate email infrastructure from a terminal or CI/CD pipeline.
What is Resend?
Resend is an email API for developers. Connect a domain, create an API key, and start sending transactional emails from your application, including password resets, order confirmations, and onboarding messages.
On March 13, 2026, Resend founder Zeno Rocha shipped the Resend CLI, bringing the same infrastructure to the terminal. The CLI has 53 commands across 13 resources, is written in TypeScript, and is fully open source under the MIT license.
It supports three common use cases:
-
Humans: Interactive prompts, readable tables, and natural-language scheduling such as
tomorrow at 9am - AI agents: JSON output, idempotency keys, and automatic agent detection
- CI/CD pipelines: Environment-variable authentication, scriptable flags, and consistent exit codes
If you're building an application that sends email, test your email API calls before they reach production. Apidog provides a visual interface for testing REST APIs, including Resend's email API. You can import the Resend OpenAPI specification, configure environments, and run organized test suites without writing additional test code.
Installing the Resend CLI
Choose the installation method that best fits your environment.
Install with cURL
This method downloads a standalone binary and does not require Node.js:
curl -fsSL https://resend.com/install.sh | bash
The installer downloads a prebuilt binary for your operating system and places it on your PATH.
Install with npm
The npm package requires Node.js 20 or later:
npm install -g resend-cli
Verify the installation:
resend --version
Install with Homebrew
On macOS or Linux, install the CLI with Homebrew:
brew install resend/cli/resend
Homebrew also handles future updates.
Install on Windows with PowerShell
Run the PowerShell installer:
irm https://resend.com/install.ps1 | iex
You can also download .exe binaries directly from the GitHub Releases page.
Build the CLI locally
To contribute to the CLI or build it from source, install Node.js 20 or later and pnpm:
git clone https://github.com/resend/resend-cli.git
cd resend-cli
pnpm install
pnpm build # outputs ./dist/cli.cjs
pnpm build:bin # native binary at ./dist/resend
Authenticating your account
Run resend login to connect the CLI to your Resend account:
resend login
The command opens your browser and guides you through creating an API key in the Resend dashboard. Credentials are stored locally at:
~/.config/resend/credentials.json
The file uses restricted 0600 permissions.
For CI/CD pipelines and other non-interactive environments, pass an API key directly:
resend login --key re_xxxxxxxxxxxxx
After authentication, the CLI resolves API keys in this order:
- The
--api-keyflag - The
RESEND_API_KEYenvironment variable - The stored credentials file
For CI pipelines, store RESEND_API_KEY as a secret environment variable:
RESEND_API_KEY=re_xxx \
resend emails send \
--from builds@yourco.com \
--to dev@yourco.com \
--subject "Build passed" \
--text "All tests green."
Use multiple accounts
If you work with multiple Resend organizations or teams, switch between stored profiles without logging out:
resend auth switch
You can also select a profile for one command:
resend <command> --profile production
Sending your first email
The main sending command is resend emails send. At minimum, provide:
- A sender address from a verified domain
- A recipient
- A subject
- A message body
Send a plain-text email
resend emails send \
--from "you@yourdomain.com" \
--to recipient@example.com \
--subject "Hello from the CLI" \
--text "This is a test email sent from the Resend CLI."
Send an HTML email
Pass HTML inline with --html:
resend emails send \
--from "team@yourco.com" \
--to user@example.com \
--subject "Your order is confirmed" \
--html "<h1>Order confirmed</h1><p>Thanks for your purchase.</p>"
For larger templates, use --html-file:
resend emails send \
--from "team@yourco.com" \
--to user@example.com \
--subject "Welcome aboard" \
--html-file ./templates/welcome.html
Schedule delivery
The CLI accepts natural-language dates as well as ISO 8601 timestamps:
resend emails send \
--from "you@yourco.com" \
--to user@example.com \
--subject "Scheduled check-in" \
--text "Just checking in." \
--schedule "tomorrow at 9am"
Other supported formats include:
in 1 hournext Monday at 3pm- A complete ISO 8601 timestamp
Capture the email ID
When output is piped, the CLI automatically switches to JSON output. Use jq to extract the email ID:
EMAIL_ID=$(resend emails send \
--from a@acme.com \
--to b@acme.com \
--subject "Test" \
--text "Hi" | jq -r '.data.id')
echo "Sent email: $EMAIL_ID"
You can use the ID for follow-up operations.
Cancel or update a scheduled email
Cancel a scheduled email:
resend emails cancel "$EMAIL_ID"
Update its schedule:
resend emails update "$EMAIL_ID" --schedule "next Monday at 10am"
List recent emails
resend emails list
Send a batch of emails
The CLI supports batches of up to 100 emails. Create a JSON file containing an array of email objects:
[
{
"from": "you@yourco.com",
"to": "alice@example.com",
"subject": "Hi Alice",
"text": "Hello!"
},
{
"from": "you@yourco.com",
"to": "bob@example.com",
"subject": "Hi Bob",
"text": "Hello!"
}
]
Send the batch:
resend emails send-batch --file emails.json
Each batch request counts as one API call against your rate limit, even when it sends up to 100 emails.
Managing domains and API keys
You need a verified domain before you can send email. The CLI supports the complete domain setup and verification workflow.
Add a domain
resend domains create \
--name yourdomain.com \
--region us-east-1
Supported regions are:
us-east-1eu-west-1sa-east-1ap-northeast-1
Choose the region closest to your users to minimize latency.
Verify DNS records
After you create a domain, Resend provides DNS records to add to your DNS provider, including SPF, DKIM, and DMARC records.
Start verification with:
resend domains verify --id <domain-id>
Check the domain status:
resend domains get --id <domain-id>
Poll the status until it returns verified.
Configure tracking and TLS
Run the interactive configuration command:
resend domains configure --id <domain-id>
This lets you configure options such as open tracking, click tracking, and custom DKIM.
List domains
resend domains list
Manage API keys
Create scoped API keys for individual services or environments instead of sharing one key everywhere:
resend api-keys create # Interactive, lets you scope per domain
resend api-keys list
resend api-keys delete --id <key-id>
A key scoped to one domain cannot access your other domains or account settings.
Advanced features
In addition to individual emails, the CLI supports broadcasts, webhooks, templates, contacts, and audiences.
Broadcasts
Create a broadcast draft, then send or schedule it:
resend broadcasts create # Interactive draft creation
resend broadcasts send --id <broadcast-id>
resend broadcasts schedule \
--id <broadcast-id> \
--date "next Monday at 10am"
Webhooks
Webhooks provide real-time delivery events such as bounces, opens, clicks, and spam reports.
Create and list webhook endpoints:
resend webhooks create # Register a new endpoint
resend webhooks list
For local development, forward webhook events to a local endpoint:
resend webhooks listen \
--forward-to http://localhost:3000/webhooks/resend
This avoids setting up ngrok or similar tunneling tools. The CLI supports 17 event types, including:
email.sentemail.deliveredemail.bouncedemail.openedemail.clicked
Templates
Create reusable HTML templates with dynamic variables:
resend templates create # Interactive template builder
Template variables use the {{variable_name}} syntax with fallback values. Reference a template by ID when sending emails.
Contacts and audiences
Resend also provides contact management for marketing emails:
resend contacts create \
--audience-id <id> \
--email user@example.com \
--first-name "Alice"
resend contacts list --audience-id <id>
resend contacts update \
--id <contact-id> \
--unsubscribed false
Run diagnostics
The doctor command checks your local setup:
resend doctor
It verifies your CLI version, API key validity, and verified domains. It can also detect AI coding agents such as Cursor, Claude Desktop, VS Code, and OpenClaw.
Using Resend CLI in CI/CD pipelines
The CLI is designed for automated environments. Use non-interactive authentication, machine-readable output, and automatic confirmation flags in scripts.
Use machine-readable output
Pass --json to force structured JSON output:
resend emails send \
--from a@co.com \
--to b@co.com \
--subject "Deploy" \
--text "Done" \
--json
The CLI also automatically uses JSON when its output is piped.
The --quiet flag suppresses spinners and progress indicators:
resend emails list --quiet | jq '.[0].id'
Skip confirmation prompts
Use --yes for destructive operations in scripts:
resend api-keys delete --id <key-id> --yes
GitHub Actions example
Store the API key in GitHub Actions secrets and expose it only to the step that needs it:
- name: Send deployment notification
env:
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
run: |
resend emails send \
--from deploys@yourco.com \
--to team@yourco.com \
--subject "Deploy to production: ${{ github.sha }}" \
--text "Deployed commit ${{ github.sha }} to production."
Account for rate limits
The Resend API rate limit is two requests per second, shared across all API keys for your team.
When sending multiple messages, prefer send-batch—which supports up to 100 emails per call—instead of looping over individual send commands.
Testing your email API with Apidog
The Resend CLI works well for interactive development and simple scripts. If your backend calls Resend's REST API directly, an API client can help you explore and test the integration before writing application code.
Apidog lets you send HTTP requests, inspect responses, organize test cases, and configure separate environments for different API keys and settings.
A typical workflow looks like this:
1. Import the Resend API specification
Resend provides API reference documentation at resend.com/docs. Import the API specification into Apidog to organize the available endpoints and view their request and response schemas.
2. Configure environments
Create development and production environments. Store your RESEND_API_KEY as an environment variable and reference it in requests with:
{{RESEND_API_KEY}}
You can switch between environments without manually replacing credentials.
3. Test the sending request
Before implementing the integration in your application, run the POST /emails endpoint with the payload you plan to use.
Verify:
- The response status
- The returned email ID
- Required-field validation
- Invalid-address behavior
- Other edge cases relevant to your application
4. Automate API tests
Use Apidog's test runner to chain requests and assert response values. For example, a test can:
- Send a test email
- Retrieve it by ID
- Verify its status
This catches integration problems before they reach production. Combined with the Resend CLI for local development, you have a terminal workflow for quick checks and an API testing environment for repeatable integration tests.
Resend pricing
The CLI is free and open source. Pricing applies to the Resend platform:
| Plan | Price | Monthly emails | Daily limit | Log retention |
|---|---|---|---|---|
| Free | $0/month | 3,000 | 100/day | 1 day |
| Pro | $20/month | 50,000 | No limit | 3 days |
| Scale | $90/month | 100,000 | No limit | 7 days |
| Enterprise | Custom | Custom | Custom | Custom |
Important free-tier details:
- The 100-email-per-day limit makes the free plan suitable for testing and small projects, not production traffic.
- Analytics such as open and click tracking require a paid plan.
- Log retention is limited to one day, so old email status may not be retrievable after 24 hours.
- The rate limit is two requests per second for all plans, shared across your team.
- Overage on paid plans is capped at five times the monthly quota to help prevent unexpected bills.
Dedicated IPs are available as a $30/month add-on on the Scale plan when sending more than 500 emails per day.
FAQ
Do I need Node.js to install the Resend CLI?
Not when using cURL or Homebrew, which install prebuilt standalone binaries. The npm installation requires Node.js 20 or later.
Why can't I send from any email address?
Resend requires a verified domain. You must own the domain, add the SPF, DKIM, and DMARC records provided by Resend, and complete verification. Free email providers such as Gmail are not supported as sender addresses.
Can I send to any email address on the free plan?
Yes. The free plan does not restrict recipients, but it limits you to 3,000 emails per month and 100 emails per day.
How does natural-language scheduling work?
The CLI parses phrases such as tomorrow at 9am, in 2 hours, and next Friday at 3pm, as well as standard ISO 8601 timestamps. Unless you specify otherwise, times are interpreted in your system's local timezone.
What happens when I pipe output?
The CLI detects when output is being piped and automatically switches to JSON-only output without spinners or prompts. You do not need to pass --json explicitly.
Can I use the CLI with multiple Resend accounts?
Yes. Run resend login multiple times to store different profiles. Then use resend auth switch to change profiles, or pass --profile <name> to a specific command.
Is the Resend CLI open source?
Yes. It is MIT licensed and hosted at github.com/resend/resend-cli.
What's the difference between --quiet and --json?
Both produce JSON output. --json forces JSON mode, while --quiet suppresses spinners and progress indicators and also implies JSON mode. In practice, they use the same output format; --quiet additionally removes non-data output.
Additional resources
- Resend CLI GitHub repository
- Resend documentation
- Resend pricing
- Resend changelog
- Apidog free API client
Top comments (1)
The implementation of the Resend CLI is intriguing, especially with its focus on user-friendliness through interactive prompts and natural-language scheduling. This makes it accessible for both developers and AI agents, enhancing efficiency in managing email tasks. One improvement idea could be to provide more examples or templates for common use cases, which would help users get started quickly. If you’re looking for support in expanding those templates or enhancing the CLI further, I’d be glad to explore a paid collaboration. How have users responded to the command-line interface so far?