Cloudflare Email
Transports

Cloudflare Email

Send emails via the Cloudflare Email Service REST API

The Cloudflare Email transport is an official Better-Notify package that sends email through the Cloudflare Email Service REST API. Use it when you are already on Cloudflare and want transactional email without an external provider.

It uses plain fetch() with zero external dependencies, so it works in Node.js, Bun, Cloudflare Workers, and any runtime with a global fetch.

Cloudflare Email Service is currently in beta and requires a Workers Paid plan.

Install

npm install @betternotify/cloudflare-email @betternotify/core @betternotify/email

Getting your credentials

You need two values: an API token and your account ID.

API token

  1. Go to API Tokens in your Cloudflare dashboard.
  2. Click Create Token.
  3. Select Create Custom Token.
  4. Under Permissions, set Account > Email Sending > Edit.

Cloudflare token permissions — Account, Email Sending, Edit

  1. Click Continue to summary, then Create Token.
  2. Copy the token — you will not see it again.

Account ID

  1. Go to your Cloudflare dashboard home page.
  2. Click the three-dot menu (⋮) next to your account name.
  3. Select Copy account ID.

Cloudflare account menu — Copy account ID

Store both values as environment variables:

CF_ACCOUNT_ID=your-account-id
CF_API_TOKEN=your-api-token

Usage

import { createNotify, createClient } from '@betternotify/core';
import { emailChannel } from '@betternotify/email';
import { cloudflareEmailTransport } from '@betternotify/cloudflare-email';

const email = emailChannel({
  defaults: { from: { name: 'My App', email: 'noreply@example.com' } },
});

const rpc = createNotify({ channels: { email } });
const catalog = rpc.catalog({
  /* routes */
});

const mail = createClient({
  catalog,
  transportsByChannel: {
    email: cloudflareEmailTransport({
      accountId: process.env.CF_ACCOUNT_ID!,
      apiToken: process.env.CF_API_TOKEN!,
    }),
  },
});

Options

Prop

Type

Error handling

The transport maps Cloudflare error codes to Better-Notify error codes:

Cloudflare codeMeaningBetter-Notify code
10001Invalid request schemaVALIDATION
10200Invalid email contentVALIDATION
10201Missing content lengthVALIDATION
10202Message too largeVALIDATION
10203Sending disabledCONFIG
10004Rate limitedPROVIDER
10002Internal server errorPROVIDER

Network failures and unparseable responses are wrapped as PROVIDER errors.

Attachments

The transport base64-encodes attachment content and infers the disposition from the cid field:

  • If cid is set, the attachment is sent as inline with a contentId.
  • Otherwise it is sent as attachment.
  • If contentType is not set, it defaults to application/octet-stream.

Limits

These limits are enforced by Cloudflare, not by the transport:

  • 50 recipients per email (to + cc + bcc combined)
  • 5 MiB total message size (25 MiB for verified addresses)
  • 998 characters subject line (RFC 5322)
  • 16 KB custom headers
  • Daily sending limits vary by account standing

If you need throttling or provider fallback, add withRateLimit middleware or wrap the transport in multiTransport({ strategy: 'failover' }).

On this page