The plain text body. Send it alongside html so clients that can't show HTML still get a readable message.
Send an email
Queue one email for delivery. Returns as soon as the email is stored, without waiting for Cloudflare.
/v1/emailsAPI keyThe email is validated, logged and put on the send queue. The response comes back with status 202 and status: "queued" before Cloudflare has seen the message. Follow what happens next with Retrieve an email or webhooks.
Headers
A key of up to 256 characters that makes the request safe to retry. A second request with the same key and the same body returns the first email with idempotent: true instead of sending again. The same key with a different body fails with 409 idempotency_payload_mismatch. Takes priority over the idempotencyKey body field. See Idempotency.
Body parameters
The sender, as "Name <address>" or a bare address. The address must be on one of the project's allowed domains, and in the allowed senders list if the project has one.
Optional when the project has a default sender (defaultFrom).
One address or an array of addresses. to, cc and bcc together can hold at most 50 unique addresses. Duplicates are removed; the first list an address appears in wins.
Carbon copy recipients.
Blind carbon copy recipients.
The address replies should go to.
Up to 998 characters. Line breaks are replaced with spaces. Required unless template is set, in which case the template's subject is used.
The HTML body. At least one of html, text or template is required.
The name of a template to render. A template stored in the project wins over a built-in template with the same name. subject, html and text in the request override what the template renders. See Templates.
Values for the template's variables. Checked against the template before anything is stored.
Custom headers. Names can't be From, To, Cc, Bcc, Subject, Reply-To, Date, Message-ID, Content-Type or MIME-Version. Values can't contain line breaks and are at most 2,048 bytes. At most 20 headers that don't start with X-, and 16 KB in total. See Custom headers.
Up to 20 files. The whole email, attachments included, must be under 5 MiB.
Show attachment propertiesHide attachment properties
An ISO 8601 date-time with a time zone offset, for example 2026-10-01T09:00:00Z. Must be in the future and at most 30 days ahead. The response has status: "scheduled". See Scheduling.
Add an open-tracking pixel. Defaults to the project setting. Only applies when there is an HTML body.
Rewrite links to count clicks. Defaults to the project setting. Only applies when there is an HTML body.
The same as the Idempotency-Key header, for callers that can't set headers. The header wins when both are sent.
Response
Status 202 for a new email. Status 200 when the request replays an earlier one with the same idempotency key, or when you use a test key.
The email ID, for example email_01K6B2Y4ZP9R3M7T8V5N2QXW4C.
queued when it will be sent now, scheduled when scheduledAt was set, test when you used an fs_test_ key (nothing is sent).
Present and true only when this is a replay of an earlier request with the same idempotency key.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_body | A field is missing or malformed. param names the field. |
| 400 | too_many_recipients | More than 50 addresses across to, cc and bcc. |
| 400 | invalid_header | A custom header breaks one of the rules above. |
| 400 | invalid_attachment | Content is not base64, or an inline file has no contentId. |
| 400 | payload_too_large | The email is over 5 MiB. |
| 400 | invalid_schedule | scheduledAt is in the past or more than 30 days ahead. |
| 400 | invalid_template_data | data doesn't match the template. |
| 403 | invalid_sender | from is not on the project's allowed domains or senders. |
| 404 | template_not_found | No template with that name. |
| 409 | idempotency_payload_mismatch | The idempotency key was used with a different body. |
| 422 | recipient_suppressed | A recipient is on the suppression list. param is the address. |
| 429 | rate_limited | Too many requests for this project. Retry after the Retry-After header. |
| 429 | daily_limit_exceeded | The project's daily limit is used up. Resets at 00:00 UTC. |
See Errors for the full list.