Resend CLI
by @maciejlis
Send and manage emails via the Resend CLI. Covers sending, domains, contacts, segments, broadcasts, templates, topics, webhooks, and API keys.
clawhub install resend-cliπ About This Skill
name: resend description: "Send and manage emails via the Resend CLI. Covers sending, domains, contacts, segments, broadcasts, templates, topics, webhooks, and API keys." homepage: https://github.com/resend/resend-cli source: https://github.com/resend/resend-cli license: MIT metadata: emoji: "π§" primaryEnv: RESEND_API_KEY requires: bins: ["resend"] env: ["RESEND_API_KEY"] configPaths: - "~/.config/resend/credentials.json" install: - id: resend-brew kind: brew tap: resend/cli formula: resend bins: ["resend"] label: "Install Resend CLI (brew)"
Resend CLI β Email for Developers
Official CLI for Resend. Covers sending, domains, contacts, segments, broadcasts, templates, webhooks, and API keys.
Prerequisites
brew install resend/cli/resend (recommended) or npm install -g resend-cliresend login or set RESEND_API_KEY env var~/.config/resend/credentials.json (0600 permissions)sending_access key (not full-access) when possibleAuth
Key priority: --api-key flag > RESEND_API_KEY env var > ~/.config/resend/credentials.json.
Always use --json or --quiet flag for non-interactive (agent) usage β forces JSON output, no spinners.
Quick Reference
Emails
# Send
resend emails send \
--from "Name " \
--to recipient@example.com \
--subject "Subject" \
--text "Body" \
--jsonSend with HTML file
resend emails send --from you@domain.com --to user@example.com \
--subject "Newsletter" --html-file ./email.html --jsonSend with attachments
resend emails send --from you@domain.com --to user@example.com \
--subject "Report" --text "See attached" --attachment ./report.pdf --jsonSchedule for later
resend emails send --from you@domain.com --to user@example.com \
--subject "Later" --text "Hi" --scheduled-at 2026-08-05T11:00:00Z --jsonWith CC, BCC, reply-to, tags, headers
resend emails send --from you@domain.com --to user@example.com \
--subject "Meeting" --text "Notes" \
--cc manager@example.com --bcc archive@example.com \
--reply-to noreply@example.com \
--tags category=marketing --headers X-Entity-Ref-ID=123 --jsonBatch send (up to 100 emails from JSON file)
resend emails batch --file ./emails.json --json
File format: [{"from":"...","to":["..."],"subject":"...","text":"..."},...]
List sent emails
resend emails list --jsonGet email details
resend emails get --jsonCancel scheduled email
resend emails cancel --jsonUpdate scheduled email
resend emails update --scheduled-at 2026-08-06T09:00:00Z --json
Inbound (Receiving) Emails
# List received emails
resend emails receiving list --jsonGet received email
resend emails receiving get --jsonList attachments
resend emails receiving attachments --jsonGet single attachment
resend emails receiving attachment Forward received email
resend emails receiving forward \
--to user@example.com --from you@domain.com --json
Domains
# List domains
resend domains list --jsonCreate domain (returns DNS records to configure)
resend domains create --name example.com --region eu-west-1 --tls enforced --jsonCreate with receiving enabled
resend domains create --name example.com --sending --receiving --jsonVerify domain (trigger DNS check)
resend domains verify --jsonGet domain details + DNS records
resend domains get --jsonUpdate domain settings
resend domains update --tls enforced --open-tracking --jsonDelete domain
resend domains delete --yes --json
Domain lifecycle: create β configure DNS β verify β get (poll until "verified").
Regions: us-east-1, eu-west-1, sa-east-1, ap-northeast-1.
Contacts
# List contacts
resend contacts list --jsonCreate contact
resend contacts create --email jane@example.com \
--first-name Jane --last-name Smith --jsonCreate with properties + segments
resend contacts create --email jane@example.com \
--properties '{"company":"Acme","plan":"pro"}' \
--segment-id --jsonGet contact (by ID or email)
resend contacts get user@example.com --jsonUpdate contact
resend contacts update user@example.com --unsubscribed --jsonDelete contact
resend contacts delete --yes --jsonList contact's segments
resend contacts segments user@example.com --jsonAdd contact to segment
resend contacts add-segment user@example.com --segment-id --jsonRemove from segment
resend contacts remove-segment user@example.com --jsonList contact's topic subscriptions
resend contacts topics user@example.com --jsonUpdate topic subscriptions
resend contacts update-topics user@example.com \
--topics '[{"id":"topic-uuid","subscription":"opt_in"}]' --json
Segments
# List segments
resend segments list --jsonCreate segment
resend segments create --name "Newsletter Subscribers" --jsonGet segment
resend segments get --jsonDelete segment (no update endpoint β delete + recreate to rename)
resend segments delete --yes --json
Broadcasts
# Create draft
resend broadcasts create \
--from hello@domain.com \
--subject "Weekly Update" \
--segment-id \
--html "Hello {{{FIRST_NAME|there}}}
" --jsonCreate from HTML file
resend broadcasts create --from hello@domain.com \
--subject "Launch" --segment-id --html-file ./email.html --jsonCreate + send immediately
resend broadcasts create --from hello@domain.com \
--subject "Launch" --segment-id --html "Hi
" --send --jsonCreate + schedule
resend broadcasts create --from hello@domain.com \
--subject "News" --segment-id --text "Hello!" \
--send --scheduled-at "tomorrow at 9am ET" --jsonSend existing draft
resend broadcasts send --jsonList broadcasts
resend broadcasts list --jsonGet broadcast details
resend broadcasts get --jsonUpdate draft
resend broadcasts update --subject "Updated Subject" --jsonDelete broadcast
resend broadcasts delete --yes --json
Template variables in HTML: {{{FIRST_NAME|Friend}}} β triple-brace with optional fallback.
Templates
# List templates
resend templates list --jsonCreate template with variables
resend templates create --name "Welcome" \
--subject "Welcome!" \
--html "Hello {{{NAME}}}
" \
--var NAME:string --jsonCreate with fallback
resend templates create --name "Invoice" \
--subject "Invoice" \
--html "Amount: {{{AMOUNT}}}
" \
--var AMOUNT:number:0 --jsonGet template
resend templates get --jsonUpdate template
resend templates update --subject "Updated Subject" --jsonPublish draft β live
resend templates publish --jsonDuplicate template
resend templates duplicate --jsonDelete template
resend templates delete --yes --json
Lifecycle: create (draft) β update β publish. Re-publish after updating a published template.
Topics
# List topics
resend topics list --jsonCreate topic
resend topics create --name "Product Updates" --jsonCreate with default opt-out
resend topics create --name "Weekly Digest" --default-subscription opt_out --jsonGet topic
resend topics get --jsonUpdate topic
resend topics update --name "Security Alerts" --jsonDelete topic
resend topics delete --yes --json
Webhooks
# List webhooks
resend webhooks list --jsonCreate webhook (all events)
resend webhooks create \
--endpoint https://app.example.com/hooks/resend \
--events all --jsonGet webhook
resend webhooks get --jsonUpdate webhook
resend webhooks update --status disabled --jsonDelete webhook
resend webhooks delete --yes --jsonListen locally (dev)
resend webhooks listen --json
Event types (17): email.sent, email.delivered, email.delivery_delayed, email.bounced, email.complained, email.opened, email.clicked, email.failed, email.scheduled, email.suppressed, email.received, contact.created, contact.updated, contact.deleted, domain.created, domain.updated, domain.deleted.
API Keys
# List API keys
resend api-keys list --jsonCreate full-access key
resend api-keys create --name "Production" --jsonCreate domain-scoped sending key
resend api-keys create --name "CI Token" \
--permission sending_access --domain-id --jsonDelete key (immediate, irreversible)
resend api-keys delete --yes --json
Utility
# Doctor β check CLI version, API key, domains, AI agent detection
resend doctor --jsonWho am I
resend whoami --jsonOpen dashboard in browser
resend openAuth β switch profile
resend auth switchLogin (non-interactive)
resend login --key re_xxx --jsonLogout
resend logout --json
Global Flags
| Flag | Description |
|------|-------------|
| --api-key | Override API key for this command |
| -p, --profile | Use specific profile |
| --json | Force JSON output |
| -q, --quiet | Suppress spinners (implies --json) |
Agent Usage Rules
1. Always use --json flag β ensures structured output, no TTY prompts.
2. All required flags must be provided β no interactive prompts in non-TTY mode.
3. Destructive actions need --yes β deletes require confirmation bypass.
4. Exit codes: 0 = success, 1 = error. Errors include message + code.
5. Batch limit: 100 emails per emails batch request.
6. Attachments not supported in batch sends.
7. --scheduled-at requires --send flag on broadcasts.
Error Codes
| Code | Cause |
|------|-------|
| auth_error | No API key found |
| missing_body | No --text/--html/--html-file |
| file_read_error | Can't read file |
| send_error | API rejected the send |
| missing_key | Login without --key in non-interactive |
| validation_failed | API rejected the key |
βοΈ Configuration
brew install resend/cli/resend (recommended) or npm install -g resend-cliresend login or set RESEND_API_KEY env var~/.config/resend/credentials.json (0600 permissions)sending_access key (not full-access) when possible