pub fn send(
ctx: &Ctx,
email: Email,
) -> impl Future<Output = Result<()>> + Send + use<>Expand description
Sends email now, from MAIL_FROM, with the adapter named by MAIL_ADAPTER.
log prints the whole email to the Worker console between
LOG_PREFIX lines and sends nothing; resend
makes one POST https://api.resend.com/emails subrequest; cloudflare
calls the EMAIL_BINDING send_email
binding. The request waits for the provider; use
deliver_later to answer first and retry failures.
The returned future is Send, so axum handlers can await it.
Free-plan limits (September 2026): Resend sends 100 emails a day and 3,000 a month from one domain, to any recipient; Cloudflare Email Service on Workers Free only delivers to verified destination addresses of the account.
§Errors
Error::BadRequest(400): a recipient (to,cc,bcc) orreply_tois not an email address.Error::Internal(500), with a log message naming the fix:MAIL_ADAPTERunset or unknown;MAIL_FROMunset or not an address; a subject that is empty or spans several lines; theRESEND_API_KEYsecret or theEMAIL: bindings.sendEmail()binding missing; the provider refused the email (e.g. Resend’s quota reached, an unverified domain or recipient) or could not be reached.
§Examples
use axum::extract::State;
use ocre::mail::Email;
use ocre::{Ctx, Result};
async fn invite(State(ctx): State<Ctx>) -> Result<&'static str> {
let email = Email::new("ada@example.com", "You're invited", "Join us: https://example.com/join");
ocre::mail::send(&ctx, email).await?;
Ok("invited")
}