FlaresendDocs
Admin API

Post a fake delivery event

Run a hand-made Cloudflare delivery event through the events pipeline. Development only.

POST/v1/admin/dev/eventsAdmin key

Cloudflare 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:

typestringrequired

cf.email.sending.message. followed by delivered, deferred, bounced, failed, rejected or complained.

sourceobjectrequired

{ "type": "email.sending", "zoneId": "…", "domain": "acme.com" }. Only type is required.

payloadobjectrequired
Show payload properties
eventIdstringrequired

A unique ID. An event ID that was already processed returns duplicate.

messageIdstringrequired

The email's cloudflareMessageId.

recipientstringrequired

One recipient address.

deliveryobjectrequired

status (the same six values as the type), plus optional provider, deliveryTimeMs, smtpStatusCode, smtpEnhancedStatusCode and smtpResponse.

bounceobject

For bounces: { "type": "hard" | "soft", "classification", "reason" }. A hard bounce adds the recipient to the suppression list.

Optional, as Cloudflare sends them.

metadataobjectrequired

Must include eventTimestamp, an ISO 8601 date-time. It becomes the time of the timeline event.

Response

oktrue

Always true when the route ran.

resultOutcome | Outcome[]

One outcome, or an array in the same order when you posted an array.

  • { "kind": "processed", "emailId", "status", "eventId" }: applied. status is the email's status afterwards.
  • { "kind": "duplicate" }: this eventId was already processed.
  • { "kind": "not_found" }: no email has this messageId.
  • { "kind": "invalid", "reason" }: the event failed validation.