Installation
- cURL
- npm
- Homebrew
- PowerShell (Windows)
Authentication
The CLI resolves your API key using the following priority chain:| Priority | Source | How to set |
|---|---|---|
| 1 (highest) | --api-key flag | resend --api-key re_xxx emails send ... |
| 2 | RESEND_API_KEY env var | export RESEND_API_KEY=re_xxx |
| 3 (lowest) | Saved credentials | resend login |
auth_error.
resend login
Authenticate by storing your API key locally. The key is validated against the Resend API before being saved.
--key flag:
| Flag | Description |
|---|---|
--key <key> | API key to store (required in non-interactive mode) |
resend logout
Remove your saved API key.
--profile flag on any command to run it with a specific profile:
| Command | Description |
|---|---|
resend auth list | List all profiles |
resend auth switch [name] | Switch the active profile |
resend auth rename [old] [new] | Rename a profile |
resend auth remove [name] | Remove a profile |
resend whoami | Show current authentication status |
Emails
Send, retrieve, cancel, and manage email delivery.resend emails send
Send an email. Provide all options via flags for scripting, or let the CLI prompt interactively for missing fields.
| Flag | Required | Description |
|---|---|---|
--from <address> | Yes * | Sender email address (must be from a verified domain) |
--to <addresses...> | Yes | One or more recipient email addresses (space-separated) |
--subject <subject> | Yes * | Email subject line |
--text <text> | One of text/html | Plain text body |
--text-file <path> | One of text/html | Path to a plain text file (use - for stdin) |
--html <html> | One of text/html | HTML body as a string |
--html-file <path> | One of text/html | Path to an HTML file (use - for stdin) |
--react-email <path> | One of text/html | Path to a React Email template (.tsx) to render and send |
--cc <addresses...> | No | CC recipients |
--bcc <addresses...> | No | BCC recipients |
--reply-to <address> | No | Reply-to email address |
--scheduled-at <datetime> | No | Schedule for later (ISO 8601 or natural language) |
--attachment <paths...> | No | File path(s) to attach |
--headers <key=value...> | No | Custom headers as key=value pairs |
--tags <name=value...> | No | Email tags as name=value pairs |
--idempotency-key <key> | No | Deduplicate this send request |
--template <id> | No | Template ID to use |
--var <key=value...> | No | Template variables as key=value pairs |
--template, which provides them.
Examples:
resend emails batch
Send up to 100 emails in a single API request from a JSON file.
| Flag | Required | Description |
|---|---|---|
--file <path> | Yes | Path to JSON file containing array of email objects (use - for stdin) |
--react-email <path> | No | Path to a React Email template (.tsx). Rendered HTML applies to every email in the batch |
--idempotency-key <key> | No | Deduplicate this batch request |
--batch-validation <mode> | No | strict (default, entire batch fails on any error) or permissive |
Receiving
Process inbound emails, download attachments, and stream incoming messages.Domains
Manage your sending and receiving domains.API Keys
Create, list, and revoke API keys for programmatic access.Broadcasts
Create and send broadcast emails to segments.Contacts
Manage contacts, segment membership, and topic subscriptions.resend contacts imports create
Start an asynchronous CSV import. The command uploads the file and returns a
contact import ID immediately; use resend contacts imports get <id> to check
processing status.
| Flag | Required | Description |
|---|---|---|
--file <path> | Yes | Path to the CSV file to import. Maximum file size is 200MB |
--column-map <json> | No | JSON object mapping CSV headers to contact fields |
--on-conflict <mode> | No | upsert to update existing contacts or skip to leave them unchanged |
--segment-id <id...> | No | Segment IDs to add imported contacts to. Repeat the flag for multiple segments |
--topics <json> | No | JSON array of topic subscriptions with id and subscription fields |
--column-map, CSV headers must match the lowercase contact field
names exactly: email, first_name, and last_name. Use --column-map when
your CSV uses headers like Email or First Name.
resend contacts imports get
Retrieve a contact import by ID, including status and row counts.
resend contacts imports list
List contact imports. The default limit is 10.
| Flag | Required | Description |
|---|---|---|
--limit <n> | No | Maximum number of imports to return. Must be between 1 and 100 |
--after <cursor> | No | Return imports after this contact import ID |
--before <cursor> | No | Return imports before this contact import ID |
--status <status> | No | Filter by queued, in_progress, completed, or failed |
Contact Properties
Define custom properties to store additional data on contacts.Segments
Group contacts into targetable segments for broadcasts.Topics
Manage subscription topics that contacts can opt in or out of.Templates
Create and manage email templates.Logs
View API request logs.Webhooks
Register endpoints and listen for email event notifications.resend webhooks create
Register a webhook endpoint.
| Flag | Required | Description |
|---|---|---|
--endpoint <url> | Yes | HTTPS URL to receive events |
--events <types...> | Yes | Event types to subscribe to (use all for all events) |
resend webhooks listen
Listen for webhook events locally during development. Starts a server, registers a temporary webhook, streams events, and cleans up on exit.
| Flag | Required | Description |
|---|---|---|
--url <url> | Yes | Your public URL (e.g., Tailscale Funnel URL) |
--events <types...> | No | Event types to listen for (default: all) |
--forward-to <url> | No | Forward payloads to a local server (passes original Svix headers) |
--port <port> | No | Local server port (default: 4318) |
See the webhook events documentation for the full
list of available event types. For agent-specific webhook patterns, see CLI
for AI Agents.
Automations
Create, manage, and monitor event-driven automation workflows.resend automations create
Create a new automation from a JSON file describing the workflow graph.
| Flag | Required | Description |
|---|---|---|
--name <name> | Yes * | Automation name |
--status <status> | No | Initial status: enabled or disabled (default: disabled) |
--steps <json> | Yes * | Steps array as JSON string |
--connections <json> | Yes * | Connections array as JSON string |
--file <path> | Yes * | Path to JSON file with full automation payload (use - for stdin) |
--file, or --name with --steps and --connections. When using --file, other flags override file values.
Other automation commands
| Flag | Required | Description |
|---|---|---|
--status <status> | No | Filter by status: running, completed, failed, cancelled (comma-separated) |
Events
Define and send events that trigger automations.resend events send
Send an event to trigger matching automations for a contact.
| Flag | Required | Description |
|---|---|---|
--event <name> | Yes | Event name (e.g. user.created) |
--contact-id <id> | One of contact | Contact ID (mutually exclusive with --email) |
--email <email> | One of contact | Contact email (mutually exclusive with --contact-id) |
--payload <json> | No | Event payload as JSON string |
Utility
Diagnose your setup, manage authentication, and configure shell completions.resend doctor
Run environment diagnostics. Verifies your CLI version, API key, credential storage, and domain status.
| Check | Pass | Warn | Fail |
|---|---|---|---|
| CLI Version | Running latest | Update available | N/A |
| API Key | Key found (shows masked key + source) | N/A | No key found |
| Credential Storage | Secure backend (e.g., macOS Keychain) | Plaintext file fallback | N/A |
| API Validation | Verified domains exist | Sending-only key, no domains, or all pending | API key invalid |
0 when all checks pass or warn. Exits 1 if any check fails.
Other utility commands
| Command | Description |
|---|---|
resend whoami | Show current authentication status |
resend open | Open the Resend dashboard in your browser |
resend update | Check for available CLI updates |
resend completion [shell] | Generate shell completion scripts (bash, zsh, fish, powershell) |
resend completion --install | Auto-install completions into your shell profile |
Global options
These flags work on every command:| Flag | Description |
|---|---|
--api-key <key> | Override API key for this invocation |
-p, --profile <name> | Profile to use (overrides RESEND_PROFILE env var) |
--json | Force JSON output even in interactive terminals |
-q, --quiet | Suppress spinners and status output (implies --json) |
--insecure-storage | Save API key as plaintext instead of secure storage |
--version | Print version and exit |
--help | Show help text |
Output behavior
The CLI has two output modes that switch automatically:| Mode | When | Stdout | Stderr |
|---|---|---|---|
| Interactive | Terminal (TTY) | Formatted text | Spinners, prompts |
| Machine | Piped, CI, or --json | JSON | Nothing |
1 and output structured JSON:
CI/CD
SetRESEND_API_KEY as an environment variable, with no resend login needed:
Configuration
| Item | Path | Notes |
|---|---|---|
| Config directory | ~/.config/resend/ | Respects $XDG_CONFIG_HOME on Linux, %APPDATA% on Windows |
| Credentials | System secure storage | macOS Keychain, Windows Credential Manager, or Linux secret service |
| Install directory | ~/.resend/bin/ | Respects $RESEND_INSTALL |
Using the CLI with AI Agents
Learn about Agent Skills, non-interactive mode, and local webhook development
for AI agents.