Summary
Send Internet mail via Cloudflare Email Sending, falling through to Resend on Cloudflare auth/permission errors, from username@cooperemail.com. Accepts text, html, cc, bcc, reply_to, headers, labels, and attachments [{filename, content_type, content_base64, content_id?}]. in_reply_to may be a msg_ id: the wire In-Reply-To uses that message's Message-ID and the send keeps its thread_id. Any other in_reply_to value is sent as-is. Inline images use content_id and cid: in HTML. A paused inbox returns 403 inbox_paused and does not send or count the attempt. Allow and block lists are checked before the provider is called. HTTP 403 recipient_blocked means nothing is sent, stored, or counted. HTTP 403 recipient_suppressed means the address is on the suppression list and nothing is sent, stored, or counted. Outbound JSON includes delivery_events. Progress email to a verified owner is exempt from allow and block lists, and owner confirmation and progress mail are not checked against the suppression list. If no sending credential is usable, the API returns smtp_not_configured — Cooper does not fake a send. Idempotency-Key is optional (example: Idempotency-Key: send-001). It is 1 to 256 characters of letters, digits, and - . _ ~. The same key and the same request within 24 hours returns HTTP 200 with idempotent true and Idempotent-Replayed: true and does not send again. A different request with that key is 409 idempotency_key_conflict. A second call while the first is still running is 409 idempotency_request_in_progress. An empty or invalid key is 400 invalid_idempotency_key. A failed send removes the key. When client_id is also set, client_id is checked first. The daily cron deletes keys after 24 hours. When usage is at 80 percent of a plan limit, the response includes notices.
Request
{
"to": [
"ada@example.com"
],
"subject": "Hello",
"text": "Tuesday works.",
"html": "<p>Tuesday works.</p><img src=\"cid:logo\" alt=\"\" />",
"attachments": [
{
"filename": "logo.png",
"content_type": "image/png",
"content_base64": "iVBORw0KGgo…",
"content_id": "logo"
}
],
"client_id": "send-001"
}Response
HTTP 200. Sample values illustrate the schema.
{
"id": "inb_example",
"inbox_id": "inb_example",
"thread_id": "thr_example",
"direction": "outbound",
"from": "ada@example.com",
"to": [
"string"
],
"subject": "Hello",
"text": "Tuesday works.",
"html": "string",
"extracted_text": "string",
"extracted_html": "string",
"preview": "string",
"delivery_events": [
{
"type": "string",
"recipient": "string",
"created_at": "2026-10-18T12:00:00.000Z",
"detail": "string"
}
],
"cc": [
"string"
],
"bcc": [
"string"
],
"reply_to": "string",
"in_reply_to": "string",
"references": [
"string"
],
"labels": [
"string"
],
"auth": {
"spf": "string",
"dkim": "string",
"dmarc": "string"
}
}Errors
- HTTP 403 inbox_paused
- HTTP 403 recipient_blocked
- HTTP 403 recipient_suppressed
- HTTP 409 idempotency_key_conflict
- HTTP 409 idempotency_request_in_progress
- HTTP 400 invalid_idempotency_key
Idempotency
Idempotency-Key is 1 to 256 characters of letters, digits, and - . _ ~. The same key and the same request within 24 hours returns the original response with HTTP 200 and Idempotent-Replayed: true. A different request is HTTP 409 idempotency_key_conflict. A second call while the first is running is HTTP 409 idempotency_request_in_progress. An empty or invalid key is HTTP 400 invalid_idempotency_key. client_id is checked first when both are set.