Post a fake delivery event
Run a hand-made Cloudflare delivery event through the events pipeline. Development only.
/v1/admin/dev/eventsAdmin keyCloudflare does not deliver email events to wrangler dev, so locally emails stop at sent. This route takes a Cloudflare email event and runs it through the same code as the events queue consumer: it updates the recipient and email status, writes the timeline event, adds hard bounces and complaints to the suppression list and fans out to webhooks.
Not available in production
The route only exists when the mailer's ENVIRONMENT var is not production. In production it returns 404 not_found.
The event is matched to an email by payload.messageId, which must equal the email's cloudflareMessageId. The send consumer sets that after sending, so send the email first and wait until it is sent.
The easiest way to call it is the CLI, which fetches the email, builds one event per recipient and posts them: flaresend dev event <type> <emailId> (or pnpm dev:event delivered <emailId> from the repo root). See Local development.
Body
One Cloudflare email event object, or an array of them. The fields Flaresend reads:
cf.email.sending.message. followed by delivered, deferred, bounced, failed, rejected or complained.
{ "type": "email.sending", "zoneId": "…", "domain": "acme.com" }. Only type is required.
Show payload propertiesHide payload properties
A unique ID. An event ID that was already processed returns duplicate.
The email's cloudflareMessageId.
One recipient address.
status (the same six values as the type), plus optional provider, deliveryTimeMs, smtpStatusCode, smtpEnhancedStatusCode and smtpResponse.
For bounces: { "type": "hard" | "soft", "classification", "reason" }. A hard bounce adds the recipient to the suppression list.
Optional, as Cloudflare sends them.
Must include eventTimestamp, an ISO 8601 date-time. It becomes the time of the timeline event.
Response
Always true when the route ran.
One outcome, or an array in the same order when you posted an array.
{ "kind": "processed", "emailId", "status", "eventId" }: applied.statusis the email's status afterwards.{ "kind": "duplicate" }: thiseventIdwas already processed.{ "kind": "not_found" }: no email has thismessageId.{ "kind": "invalid", "reason" }: the event failed validation.