resend-cli 2.5.0 → 2.7.0-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resend-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0-preview.0",
|
|
4
4
|
"description": "The official CLI for Resend",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">=22"
|
|
20
20
|
},
|
|
21
|
-
"packageManager": "pnpm@11.
|
|
21
|
+
"packageManager": "pnpm@11.8.0",
|
|
22
22
|
"files": [
|
|
23
23
|
"dist/cli.cjs",
|
|
24
24
|
"skills/"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@clack/prompts": "1.4.0",
|
|
44
44
|
"@commander-js/extra-typings": "14.0.0",
|
|
45
45
|
"commander": "14.0.3",
|
|
46
|
-
"esbuild": "0.28.
|
|
46
|
+
"esbuild": "0.28.1",
|
|
47
47
|
"esbuild-wasm": "0.28.0",
|
|
48
48
|
"picocolors": "1.1.1",
|
|
49
49
|
"resend": "6.14.0"
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@biomejs/biome": "2.4.11",
|
|
63
63
|
"@types/node": "24.12.4",
|
|
64
|
-
"@yao-pkg/pkg": "6.
|
|
65
|
-
"tsx": "4.22.
|
|
64
|
+
"@yao-pkg/pkg": "6.20.0",
|
|
65
|
+
"tsx": "4.22.4",
|
|
66
66
|
"typescript": "5.9.3",
|
|
67
|
-
"vitest": "4.1.
|
|
67
|
+
"vitest": "4.1.9"
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -11,6 +11,8 @@ description: >
|
|
|
11
11
|
license: MIT
|
|
12
12
|
metadata:
|
|
13
13
|
author: resend
|
|
14
|
+
# Skill version is independent from the CLI/package.json version —
|
|
15
|
+
# bump it on skill content changes, not CLI releases.
|
|
14
16
|
version: "2.3.0"
|
|
15
17
|
homepage: https://resend.com/docs/cli-agents
|
|
16
18
|
source: https://github.com/resend/resend-cli
|
|
@@ -145,7 +147,7 @@ Auth resolves: `--api-key` flag > `RESEND_API_KEY` env > config file (`resend lo
|
|
|
145
147
|
| `automations` | create, get, list, update, delete, stop, open, runs |
|
|
146
148
|
| `events` | create, get, list, update, delete, send, open |
|
|
147
149
|
| `broadcasts` | create, send, update, delete, list |
|
|
148
|
-
| `contacts` | create, update, delete, segments, topics |
|
|
150
|
+
| `contacts` | create, update, delete, segments, topics, imports |
|
|
149
151
|
| `contact-properties` | create, update, delete, list |
|
|
150
152
|
| `segments` | create, get, list, delete, contacts |
|
|
151
153
|
| `templates` | create, publish, duplicate, delete, list |
|
|
@@ -170,6 +172,7 @@ Read the matching reference file for detailed flags and output shapes.
|
|
|
170
172
|
| 6 | **Sending a dashboard-created broadcast via CLI** | Only API-created broadcasts can be sent with `broadcasts send` — dashboard broadcasts must be sent from the dashboard |
|
|
171
173
|
| 7 | **Passing `--events` to `webhooks update` expecting additive behavior** | `--events` replaces the entire subscription list — always pass the complete set |
|
|
172
174
|
| 8 | **Expecting `logs list` to include request/response bodies** | List returns summary fields only — use `logs get <id>` for full `request_body` and `response_body` |
|
|
175
|
+
| 9 | **CSV import fails with `create_error` ("missing required email column")** | `contacts imports create` matches columns case-sensitively by lowercase names (`email`, `first_name`, `last_name`) — use `--column-map` for headers like `Email`/`First Name` |
|
|
173
176
|
|
|
174
177
|
## Common Patterns
|
|
175
178
|
|
|
@@ -98,3 +98,44 @@ List contact's topic subscriptions.
|
|
|
98
98
|
| `--topics <json>` | string | Yes (non-interactive) | JSON array: `[{"id":"topic-uuid","subscription":"opt_in"}]` |
|
|
99
99
|
|
|
100
100
|
Subscription values: `opt_in` | `opt_out`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## contacts imports create
|
|
105
|
+
|
|
106
|
+
Bulk-import contacts from a local CSV file. The file is uploaded as multipart form data (max 100MB). Imports run **asynchronously** — the command returns an import id immediately while the file is processed in the background (poll with `contacts imports get`).
|
|
107
|
+
|
|
108
|
+
| Flag | Type | Required | Description |
|
|
109
|
+
|------|------|----------|-------------|
|
|
110
|
+
| `--file <path>` | string | Yes (non-interactive) | Path to the CSV file to import |
|
|
111
|
+
| `--column-map <json>` | string | No | JSON object mapping contact fields to CSV column headers: `{"email":"Email","firstName":"First Name","properties":{"plan":{"column":"Plan","type":"string"}}}` |
|
|
112
|
+
| `--on-conflict <strategy>` | string | No | How to handle existing contacts: `upsert` (default, updates) or `skip` |
|
|
113
|
+
| `--segment-id <id...>` | string[] | No | Add imported contacts to segment(s) — repeatable |
|
|
114
|
+
| `--topics <json>` | string | No | JSON array: `[{"id":"topic-uuid","subscription":"opt_in"}]` |
|
|
115
|
+
|
|
116
|
+
Mappable contact fields: `email`, `firstName`, `lastName`, `unsubscribed`, `properties`.
|
|
117
|
+
|
|
118
|
+
Without `--column-map`, columns are matched by the lowercase names `email` (required), `first_name`, `last_name` — matching is **case-sensitive**, so a CSV with `Email`/`First Name` headers fails with `create_error` (422 "missing required email column"). Use `--column-map` to import such a file.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## contacts imports get
|
|
123
|
+
|
|
124
|
+
Retrieve a contact import's status and counts.
|
|
125
|
+
|
|
126
|
+
**Argument:** `[id]` — Contact import ID (interactive picker when omitted)
|
|
127
|
+
|
|
128
|
+
Status values: `queued` | `in_progress` | `completed` | `failed`
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## contacts imports list
|
|
133
|
+
|
|
134
|
+
| Flag | Type | Default | Description |
|
|
135
|
+
|------|------|---------|-------------|
|
|
136
|
+
| `--limit <n>` | number | 10 | Max results (1-100) |
|
|
137
|
+
| `--after <cursor>` | string | — | Forward pagination |
|
|
138
|
+
| `--before <cursor>` | string | — | Backward pagination |
|
|
139
|
+
| `--status <status>` | string | — | Filter by status: `queued` \| `in_progress` \| `completed` \| `failed` |
|
|
140
|
+
|
|
141
|
+
**Alias:** `ls`
|
|
@@ -22,9 +22,18 @@ All errors exit with code `1` and output JSON to **stderr**:
|
|
|
22
22
|
| `missing_body` | None of `--text`, `--html`, `--html-file`, or `--react-email` provided | Provide at least one body flag |
|
|
23
23
|
| `react_email_build_error` | Failed to bundle a React Email `.tsx` template with esbuild | Check the template compiles; ensure `react` and one of `react-email` (6.0+), `@react-email/components` (5.x), or `@react-email/render` are installed in the project |
|
|
24
24
|
| `react_email_render_error` | Bundled template failed during `render()` | Check the component exports a default function and renders valid React Email markup |
|
|
25
|
-
| `file_read_error` | Could not read file from `--html-file` path | Check file path exists and is readable |
|
|
25
|
+
| `file_read_error` | Could not read file from a `--file`/`--html-file`/`--text-file` path | Check file path exists and is readable |
|
|
26
26
|
| `send_error` | Resend API rejected the send request | Check from address is on a verified domain; check recipient is valid |
|
|
27
27
|
|
|
28
|
+
## Contact Import Errors
|
|
29
|
+
|
|
30
|
+
| Code | Cause | Resolution |
|
|
31
|
+
|------|-------|------------|
|
|
32
|
+
| `missing_file` | `contacts imports create` called non-interactively without `--file` | Pass `--file <path>` to the CSV to import |
|
|
33
|
+
| `invalid_column_map` | `--column-map` is not valid JSON, or is not an object | Pass a JSON object mapping contact fields to CSV headers, e.g. `{"email":"Email"}` |
|
|
34
|
+
| `invalid_topics` | `--topics` is not valid JSON, or is not an array | Pass a JSON array of `{id, subscription}` objects |
|
|
35
|
+
| `create_error` | Resend API rejected the import (e.g. CSV missing the required `email` column, or file over 100MB) | Ensure the CSV has an `email` column (or map it with `--column-map`) and is under 100MB |
|
|
36
|
+
|
|
28
37
|
## Domain Errors
|
|
29
38
|
|
|
30
39
|
| Code | Cause | Resolution |
|
|
@@ -414,3 +414,40 @@ resend emails receiving listen --interval 10
|
|
|
414
414
|
# Stream as NDJSON (for scripting)
|
|
415
415
|
resend emails receiving listen --json | head -3
|
|
416
416
|
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 13. Bulk Import Contacts from CSV
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# 1. Prepare a CSV. Without --column-map, columns are matched by the lowercase
|
|
424
|
+
# names email (required), first_name, last_name — matching is CASE-SENSITIVE,
|
|
425
|
+
# so headers like "Email" or "First Name" will NOT match (import fails with a
|
|
426
|
+
# 422 "missing required email column"). Map those with --column-map instead.
|
|
427
|
+
cat > contacts.csv << 'EOF'
|
|
428
|
+
email,first_name,last_name
|
|
429
|
+
ada@example.com,Ada,Lovelace
|
|
430
|
+
alan@example.com,Alan,Turing
|
|
431
|
+
EOF
|
|
432
|
+
|
|
433
|
+
# 2. Start the import (returns an import id immediately; runs async)
|
|
434
|
+
resend contacts imports create --file ./contacts.csv
|
|
435
|
+
|
|
436
|
+
# If your CSV uses different header names, map them with --column-map.
|
|
437
|
+
# You can also set a conflict strategy and add contacts to a segment:
|
|
438
|
+
cat > contacts-custom.csv << 'EOF'
|
|
439
|
+
Email,First Name,Last Name
|
|
440
|
+
ada@example.com,Ada,Lovelace
|
|
441
|
+
EOF
|
|
442
|
+
resend contacts imports create \
|
|
443
|
+
--file ./contacts-custom.csv \
|
|
444
|
+
--column-map '{"email":"Email","firstName":"First Name","lastName":"Last Name"}' \
|
|
445
|
+
--on-conflict upsert \
|
|
446
|
+
--segment-id <segment-id>
|
|
447
|
+
|
|
448
|
+
# 3. Poll status until "completed" (or "failed")
|
|
449
|
+
resend contacts imports get <import-id>
|
|
450
|
+
|
|
451
|
+
# 4. Review past imports (filter by status)
|
|
452
|
+
resend contacts imports list --status completed
|
|
453
|
+
```
|