Files
dotfiles/dot_claude/skills/cloudflare-email-service/references/rest-api.md
T
Prad NukalaandClaude Fable 5 20891f3910 config(git,claude,ssh): templated gitconfig; claude settings/commands/hooks/skills; ssh config
gitconfig: name/email from chezmoi data, gh credential helper by PATH
lookup (portable to darwin). claude: no credentials, history, projects,
sessions, or plugin caches. ssh config as private_ (0600).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 14:53:46 -04:00

5.9 KiB

Sending Emails — REST API

Send emails via HTTP requests from any application. If your app runs on Cloudflare Workers, use the Workers binding instead — simpler and more performant.

For the full OpenAPI specification, refer to the Email Sending API reference.

Endpoint

POST https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send

Authentication

Authenticate with a Cloudflare API token that has email sending permission:

Authorization: Bearer <API_TOKEN>

Request Fields

IMPORTANT: The REST API uses different field names than the Workers binding in some cases.

Field Type Required Description
to string or string[] Yes Recipient(s), max 50 combined with cc/bcc
from string or {address, name} Yes Sender — uses address not email for object form
subject string Yes Email subject line
html string No* HTML body
text string No* Plain text body
cc string or string[] No CC recipients
bcc string or string[] No BCC recipients
reply_to string or {address, name} No Snake_case, not camelCase
attachments array No File attachments and inline images
headers object No Custom email headers

*At least one of html or text required. Include both for best deliverability.

Key differences from Workers binding: from uses address (REST) vs email (Workers), reply_to (REST) vs replyTo (Workers), content_id (REST) vs contentId (Workers) for inline attachments, errors use numeric codes (REST) vs string E_* codes (Workers), and responses return delivery status (delivered/permanent_bounces/queued) instead of just messageId.

Examples

Simple send:

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "user@example.com",
    "from": "welcome@yourdomain.com",
    "subject": "Welcome!",
    "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
    "text": "Welcome! Thanks for signing up."
  }'

Multiple recipients with CC/BCC:

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": ["user1@example.com", "user2@example.com"],
    "cc": ["manager@company.com"],
    "bcc": ["archive@company.com"],
    "from": { "address": "orders@yourdomain.com", "name": "Orders" },
    "reply_to": "support@yourdomain.com",
    "subject": "Order Confirmation",
    "html": "<h1>Your order is confirmed</h1>",
    "text": "Your order is confirmed"
  }'

With attachments:

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "customer@example.com",
    "from": "invoices@yourdomain.com",
    "subject": "Your Invoice",
    "html": "<h1>Invoice attached</h1>",
    "attachments": [
      {
        "content": "JVBERi0xLjQKJeLjz9MK...",
        "filename": "invoice.pdf",
        "type": "application/pdf",
        "disposition": "attachment"
      }
    ]
  }'

With inline images (embedded via cid: URI):

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "user@example.com",
    "from": "newsletter@yourdomain.com",
    "subject": "Check this out",
    "html": "<h1>Hello!</h1><img src=\"cid:logo\">",
    "attachments": [
      {
        "content": "iVBORw0KGgoAAAANSUhEUg...",
        "filename": "logo.png",
        "type": "image/png",
        "disposition": "inline",
        "content_id": "logo"
      }
    ]
  }'

Attachment fields differ by type:

  • Regular attachment: content (base64), filename, type (MIME), disposition: "attachment"
  • Inline image: content (base64), filename, type (MIME), disposition: "inline", content_id (referenced in HTML as cid:<content_id>)

With custom headers:

curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send" \
  --header "Authorization: Bearer <API_TOKEN>" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "user@example.com",
    "from": "notifications@yourdomain.com",
    "subject": "Your weekly digest",
    "html": "<h1>Weekly Digest</h1>",
    "headers": {
      "List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=abc123>",
      "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
      "X-Campaign-ID": "weekly-digest-2026-03"
    }
  }'

See the email headers reference for the full list of allowed headers.

Response

Success:

{
  "success": true,
  "errors": [],
  "messages": [],
  "result": {
    "delivered": ["recipient@example.com"],
    "permanent_bounces": [],
    "queued": []
  }
}

Error (numeric codes, not E_* string codes like Workers):

{
  "success": false,
  "errors": [{ "code": 1000, "message": "Sender domain not verified" }],
  "result": null
}

Error Handling

Status Meaning Retry?
200 Success N/A
400 Validation error No — fix the request
401 Invalid API token No — check your token
429 Rate limited Yes — exponential backoff
500 Server error Yes — exponential backoff

Only retry on 429 and 500. Validation errors (400) won't succeed on retry.