# Email

> Send mail from your Workers through a send_email binding, from domains you own, to addresses that confirmed they want it.

Source: https://docs.fortly.com/email

A Worker with a `send_email` binding sends mail the same way it does on Cloudflare. Fortly sends it from a domain your account has verified, and only to destination addresses that have confirmed they want the mail. That makes contact forms, order notifications and alerts to your own inbox work unchanged, and it means Fortly is never an open relay.

This feature sends outbound email. Receiving and forwarding incoming mail is not available.

Set it up once per account under **Email** in the console. Its setup checklist connects sending domains, destinations and your Worker:

1. **Add a sending domain** and publish the DNS records it shows: a TXT record proving ownership, a DKIM key, and, recommended, an SPF include. Fortly checks them every few minutes and the page updates on its own. A subdomain such as `mail.example.com` keeps them apart from the mail you already receive.
2. **Add a destination address.** Fortly mails it a confirmation link. Nothing is sent to it until someone opens the link and confirms.

Any address at a verified domain can then send to any confirmed destination, within the Worker binding’s restrictions. Each connected Worker shows whether its own allowed sender and recipient addresses are ready, whether the mail service is configured, and whether the monthly allowance remains.

## In your Worker

```jsonc
// wrangler.jsonc
{
  "send_email": [{ "name": "EMAIL" }]
}
```

Cloudflare's structured form:

```js
await env.EMAIL.send({
  from: { name: "Shop", email: "orders@mail.example.com" },
  to: "me@example.com",
  replyTo: { name: buyer.name, email: buyer.email },
  subject: "New order",
  text: "…",
  html: "<p>…</p>",
});
```

The original raw form works too:

```js
import { EmailMessage } from "cloudflare:email";

await env.EMAIL.send(new EmailMessage("orders@mail.example.com", "me@example.com", rawMimeMessage));
```

`to`, `cc` and `bcc` each take one address or a list of addresses, and every address can be a string or `{ email, name }`. A message can have up to 50 recipients. A raw message is delivered byte for byte as you composed it.

The binding's own restrictions apply as on Cloudflare: `destination_address` limits it to one recipient, `allowed_destination_addresses` to a list, and `allowed_sender_addresses` limits who it may send as. Every recipient must still be a confirmed destination, and every sender must use a verified domain.

## When a send is refused

`send()` throws an error with a `code`:

| Code | Why |
| --- | --- |
| `E_SENDER_NOT_VERIFIED` | The from address is not at a verified sending domain of the project's account. |
| `E_SENDER_NOT_ALLOWED` | The binding's `allowed_sender_addresses` leave it out. |
| `E_RECIPIENT_NOT_ALLOWED` | A recipient is not a confirmed destination, or the binding's restrictions leave it out. |
| `E_FIELD_MISSING`, `E_VALIDATION_ERROR` | No recipient, no subject, no text or HTML, or an address that is not one. |
| `E_TOO_MANY_RECIPIENTS` | More than 50 recipients. |
| `E_RATE_LIMIT_EXCEEDED` | The account has sent its messages for the month. |
| `E_DELIVERY_FAILED` | The mail provider did not accept the message. |

Every message, sent or refused, appears under **Email → Activity** with the reason. Search by subject, recipient or project and filter by Sent, Refused or Failed. Activity refreshes every 30 seconds and can be refreshed manually. Removing a sending domain or destination requires confirmation before Workers lose access to it. **Deployments → Bindings** shows whether each `send_email` binding can send yet.

## Limits

| Plan | Messages a month |
| --- | --- |
| Free | 100 |
| Pro | 1,000 |
| Max | 5,000 |

Months are calendar months in UTC. Only sent messages count; refused ones do not. Sending to any address, such as a buyer's own inbox, is not available yet.

## Related

- [Worker bindings](https://docs.fortly.com/deploy/bindings): Inspect the live connection and follow the resource that needs setup.
- [Email API](https://docs.fortly.com/api/email): Manage domains and destinations and read delivery activity.
- [Schedules](https://docs.fortly.com/deploy/schedules): Send a report or alert from a scheduled Worker job.
