API reference
Send batch
Queue up to 100 emails in a single request.
Why use this
For example
A nightly job emails 80 customers their personalised weekly summary — each with different content — in one request instead of 80 separate calls.
Example
import { YourMail } from "yourmail";
const yourmail = new YourMail(process.env.YOURMAIL_API_KEY!, {
baseUrl: process.env.YOURMAIL_BASE_URL!,
});
const { data } = await yourmail.batch([
{
from: "hello@mail.acme.com",
to: "alice@example.com",
subject: "Your receipt",
html: "<p>Receipt for Alice</p>",
},
{
from: "hello@mail.acme.com",
to: "bob@example.com",
subject: "Your receipt",
html: "<p>Receipt for Bob</p>",
},
]);
for (const result of data) {
if ("id" in result) {
console.log("queued:", result.id);
} else {
console.error("failed:", result.error.type, result.error.message);
}
}const res = await fetch(
"https://api.yourmail.dev/v1/emails/batch",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
emails: [
{
from: "hello@mail.acme.com",
to: "alice@example.com",
subject: "Your receipt",
html: "<p>Receipt for Alice</p>",
},
{
from: "hello@mail.acme.com",
to: "bad-address", // this item will produce an error entry
subject: "Your receipt",
html: "<p>Receipt for Bad</p>",
},
],
}),
}
);
// Always HTTP 200; check each item individually
const { data } = await res.json();curl -X POST https://api.yourmail.dev/v1/emails/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emails": [
{
"from": "hello@mail.acme.com",
"to": "alice@example.com",
"subject": "Your receipt",
"html": "<p>Receipt for Alice</p>"
},
{
"from": "hello@mail.acme.com",
"to": "bob@example.com",
"subject": "Your receipt",
"html": "<p>Receipt for Bob</p>"
}
]
}'Request body
The body must be { emails: [...] }, where each item follows the same schema as a single send. The array must not be empty and may not exceed 100 items.
emailsSendRequest[]- RequiredArray of send requests, 1–100 items. Each item is identical to the POST /v1/emails body.
Auth and gating
Authentication and rate limiting run once for the whole request before any item is processed. If the request-level gate fails (e.g. invalid API key or rate limit exceeded), the entire batch is rejected with a top-level error response — no items are queued. Per-item errors (bad recipient, validation failure, quota exceeded, etc.) are reported inside the data array and do not affect other items.
Mixed results
The response is always HTTP 200 with one entry per input email in the same order. Each entry is either a success { id: string } or an error { error: { type, message } }. A partially-failed batch still returns 200 — iterate data and check for error on each item, or read the top-level summary ({ total, succeeded, failed }) to spot a failure without walking the array.
// 200 OK — one entry per input email (same order)
{
"data": [
{ "id": "jn7abc123def456" },
{ "error": { "type": "validation_error", "message": "\"to\" contains an invalid email address" } }
],
// Tally so a status-only client can spot a failure without walking "data".
"summary": { "total": 2, "succeeded": 1, "failed": 1 }
}Request-level errors
These fail the entire batch before any item is processed.
validation_errorBody is not { emails: [...] } or the array is empty
authentication_errorAPI key missing, malformed, or not recognised
validation_erroremails array exceeds 100 items
rate_limitedPer-second burst exceeded for this account
quota_exceeded is a per-item error — quota is checked individually for each email in the batch. When quota runs out mid-batch, the remaining items produce { error: { type: "quota_exceeded", ... } } entries in the data array; items processed before the limit was hit are unaffected.