You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 43b7d7d
Browse filesBrowse the repository at this point in the historyBrowse files
Optional reply-to address, or an array of addresses. Each address must be a valid email. When provided as an array, it must contain at least one entry. Forwarded to Resend as the message's `Reply-To` header.
29
33
</ParamField>
30
34
31
35
<ParamFieldbody="subject"type="string">
@@ -57,7 +61,9 @@ Sends transactional email from your project.
57
61
- Template mode: `templateId` or `templateName`
58
62
- Direct mode: `subject` + (`html` or `text`)
59
63
- Do not pass both `templateId` and `templateName`.
60
-
- If rendered subject/body becomes empty after variable interpolation, request is rejected with `400`.
64
+
-`to` and `replyTo` must contain valid email addresses. Array forms cannot be empty (`Recipient list cannot be empty`, `Reply-to list cannot be empty`).
65
+
- Subject is required after any template resolution and variable interpolation (`Subject is required`).
66
+
- The rendered message must include a non-empty `html` or `text` body. Requests where both come out empty after interpolation are rejected with `Provide html or text` (or `Provide at least one of html or text content.` when neither field was supplied).
61
67
62
68
### Template resolution order
63
69
@@ -123,6 +129,7 @@ const res = await fetch('https://api.ub.bitbros.in/api/mail/send', {
123
129
},
124
130
body:JSON.stringify({
125
131
to:'user@example.com',
132
+
replyTo:'support@acme.com',
126
133
subject:'Welcome to Acme',
127
134
html:'<h1>Hello</h1><p>Your account is ready.</p>'
128
135
})
@@ -212,10 +219,14 @@ public class Main {
212
219
213
220
### Errors
214
221
215
-
| Status | Cause |
216
-
| :--- | :--- |
217
-
|`400 Bad Request`| Invalid payload, invalid template ID, or empty rendered subject/body |
218
-
|`401 Unauthorized`| Missing project context |
219
-
|`403 Forbidden`| Non-secret key used |
220
-
|`404 Not Found`| Template or project not found |
221
-
|`429 Too Many Requests`| Monthly mail limit exceeded |
222
+
| Status | Message | Cause |
223
+
| :--- | :--- | :--- |
224
+
|`400 Bad Request`|`Invalid recipient email format` / `Recipient list cannot be empty`|`to` is missing, malformed, or an empty array |
225
+
|`400 Bad Request`|`Invalid replyTo email format` / `Reply-to list cannot be empty`|`replyTo` is malformed or an empty array |
226
+
|`400 Bad Request`|`Subject is required`| Subject missing, blank, or empty after template/variable interpolation |
227
+
|`400 Bad Request`|`Provide at least one of html or text content.`| Neither `html` nor `text` supplied (or both empty after interpolation) |
228
+
|`400 Bad Request`|`Template not found.`|`templateId` / `templateName` does not resolve |
229
+
|`401 Unauthorized`|`Project context missing.`| Request has no resolved project |
230
+
|`403 Forbidden`|`Forbidden. This action requires a Secret Key (sk_live_...).`| Non-secret key used |
231
+
|`404 Not Found`|`Project not found.`| Project record missing |
232
+
|`429 Too Many Requests`|`Monthly mail limit exceeded.`| Project quota exhausted for the month |
Copy file name to clipboardExpand all lines: mintlify/docs/guides/mail-platform.mdx
+38-14Lines changed: 38 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,8 +7,8 @@ description: "Comprehensive developer guide for urBackend Mail Platform: BYOK, b
7
7
8
8
urBackend Mail Platform extends transactional sending into a full delivery workflow with:
9
9
10
-
- async queue-backed single sending (`/api/mail/send`)
11
-
- direct provider batch sending (`/api/mail/send-batch`)
10
+
- async queue-backed single sending (`/api/mail/send`), with optional `replyTo`
11
+
- direct provider batch sending (`/api/mail/send-batch`, 1..100 items, per-item `replyTo`)
12
12
- BYOK (Bring Your Own Key) with encrypted project-level Resend keys
13
13
- delivery tracking via persistent `MailLog`
14
14
- audience/contact management (BYOK-gated)
@@ -101,14 +101,21 @@ All `/api/mail/*` send endpoints require your **Secret Key** (`sk_live_...`) in
101
101
102
102
| Field | Type | Required | Notes |
103
103
|---|---|---:|---|
104
-
|`to`|`string`| ✅ | recipient email |
104
+
|`to`|`string \| string[]`| ✅ | recipient email(s); array form must have at least one entry |
105
+
|`replyTo`|`string \| string[]`| Optional | reply-to address(es); forwarded to Resend as the `Reply-To` header |
105
106
|`subject`|`string`| Direct mode ✅ | required when not using template fields |
106
107
|`html`|`string`| Direct mode one of `html/text`| HTML body |
107
108
|`text`|`string`| Direct mode one of `html/text`| Text body |
108
109
|`templateId`|`string`| Template mode one of `templateId/templateName`| 24-char ObjectId |
109
110
|`templateName`|`string`| Template mode one of `templateId/templateName`| key/name lookup |
110
111
|`variables`|`object`| Optional | template vars |
111
112
113
+
Validation notes:
114
+
115
+
-`to` and `replyTo` must be valid email addresses. Array forms cannot be empty (`Recipient list cannot be empty`, `Reply-to list cannot be empty`).
116
+
- Subject must be non-empty after any template/variable interpolation (`Subject is required`).
117
+
- Rendered body must contain a non-empty `html` or `text` value; requests where both are empty after interpolation are rejected (`Provide at least one of html or text content.`).
118
+
112
119
#### Quota and limits
113
120
114
121
- per-request monthly quota slot is reserved in Redis
@@ -169,13 +176,30 @@ Array of 1..100 items:
169
176
[
170
177
{
171
178
"to": "u1@example.com",
179
+
"replyTo": "support@acme.com",
172
180
"subject": "Campaign",
173
181
"html": "<p>Hello</p>"
174
182
}
175
183
]
176
184
```
177
185
178
-
Each item supports `to`, `subject`, `html?`, `text?`.
186
+
Each item supports:
187
+
188
+
| Field | Type | Required | Notes |
189
+
|---|---|---:|---|
190
+
|`to`|`string \| string[]`| ✅ | recipient email(s); array form must have at least one entry |
191
+
|`replyTo`|`string \| string[]`| Optional | reply-to address(es); array form must have at least one entry |
192
+
|`subject`|`string`| ✅ | non-empty after trimming |
193
+
|`html`|`string`| one of `html/text` ✅ | HTML body |
194
+
|`text`|`string`| one of `html/text` ✅ | Text body |
195
+
196
+
Validation is enforced by a strict Zod schema on every batch call:
197
+
198
+
- The batch array itself must contain **1..100** items. Empty batches are rejected with `Batch cannot be empty`; larger batches are rejected with `Max 100 emails per batch`.
199
+
- Each `to` and `replyTo` value is validated as a proper email address.
200
+
- Each item must supply a non-empty `subject` (`Subject is required`).
201
+
- Each item must supply at least one of `html` or `text` (`Provide html or text`).
202
+
- Templates (`templateId` / `templateName` / `variables`) are **not** supported in batch mode. Batch items always go directly to Resend with the exact `subject` / `html` / `text` you provide.
179
203
180
204
#### Quota behavior
181
205
@@ -196,8 +220,8 @@ curl -X POST "https://api.ub.bitbros.in/api/mail/send-batch" \
|`POST /api/mail/send-batch`|`429`| Monthly mail limit exceeded |
595
+
|`POST /api/mail/send`|`400`|`Recipient list cannot be empty` / `Reply-to list cannot be empty` / `Subject is required` / `Provide at least one of html or text content.` / `Template not found.`|
596
+
|`POST /api/mail/send`|`403`|`Forbidden. This action requires a Secret Key (sk_live_...).`|
597
+
|`POST /api/mail/send`|`429`|`Monthly mail limit exceeded.`|
598
+
|`POST /api/mail/send-batch`|`400`|`Batch cannot be empty` / `Max 100 emails per batch` / `Recipient list cannot be empty` / `Reply-to list cannot be empty` / `Subject is required` / `Provide html or text`|
599
+
|`POST /api/mail/send-batch`|`403`|`Forbidden. This action requires a Secret Key (sk_live_...).`|
600
+
|`POST /api/mail/send-batch`|`429`|`Monthly mail limit exceeded.`|
577
601
|`GET /api/mail/logs/:resendId`|`400`| Invalid resendId format |
578
602
|`GET /api/mail/logs/:resendId`|`404`| Mail log entry not found for this project |
579
603
|`GET /api/mail/audiences` + audience mutations |`403`| This feature requires a BYOK Resend key |
|`to`|`string \| string[]`| Yes | Recipient email address(es). Array form must contain at least one entry. |
26
+
|`replyTo`|`string \| string[]`| No | Reply-to address(es). Forwarded to Resend as the `Reply-To` header. Array form must contain at least one entry. |
26
27
|`subject`|`string`| Template mode: No, Direct mode: Yes | Email subject line. |
27
28
|`text`|`string`| Direct mode: one of `text` or `html` is required | Plain text body. |
28
29
|`html`|`string`| Direct mode: one of `text` or `html` is required | HTML body. |
@@ -85,6 +86,7 @@ console.log(response.id);
85
86
// Direct mode
86
87
const response =awaitclient.mail.send({
87
88
to: 'customer@example.com',
89
+
replyTo: 'support@acme.com',
88
90
subject: 'Welcome to urBackend',
89
91
html: '<h1>Hi there!</h1><p>Thanks for joining.</p>'
0 commit comments