Send via API Email API

Receive mail events by webhook

Configure an endpoint so your code knows whether a message arrived or failed, pick the right events, and verify the signature so you cannot be fed fake data.

The send call returns "accepted for sending", not "delivered". Webhooks tell you what happened afterwards, without polling.

Before you start

Pick a channel

Go to Email API → Webhooks → Add webhook. Besides HTTP it can post straight into common chat channels.

The Webhooks page: the add webhook button, and the endpoint list with delivery history columns for transaction ID, target URL and attempts

ChannelSuits
HTTPan application that acts on it — marking addresses bad, stopping retries
A team chat channelpeople watching, not machines acting

Chat channels are convenient for alerting but do not replace HTTP: a person will not update your database every time an address goes bad.

Pick the events

There are seven, and you should choose what you will actually handle rather than all of them.

The add webhook screen: channel selection with HTTP and chat channels, a destination URL field, and a list of five email events with bounced and complained pre-selected

EventFires whenWhat you should do
email.sentthe system accepts itusually nothing — you knew from the response
email.deliveredthe recipient reports acceptancerecord it, if useful
email.openedthe recipient opens it — fires on every opencount opens, if useful
email.clickedthe recipient clicks a link in it — fires on every clickcount clicks, if useful
email.bouncedthe message came backmark the address bad and stop sending
email.complainedthe recipient reported it as spamstop sending to that address immediately
email.failedit could not be sentread the reason, fix, retry

email.bounced and email.complained are preselected because they are the two events you must handle to keep a usable sending reputation.

email.complained is the serious one: continuing to mail someone who reported you as spam damages the reputation of the whole domain.

Verify the signature

After creation the system shows a secret that appears only once — save it like an API key. Editing a webhook later does not change it.

The secret verifies the signature in the X-CloudFly-Signature header. Your endpoint must check it before trusting the payload.

The webhook address is public

Without signature checking, anyone who knows it can send fake email.bounced events, and your application will happily mark working customer addresses as dead.

Write the endpoint properly

Three things the system expects:

  1. Respond quickly. Return 2xx within 10 seconds; heavy work goes on a queue, answer first.
  2. Tolerate duplicates. An event can arrive more than once, for example after Replay. Key on email_id + type (add timestamp for email.opened/email.clicked).
  3. No automatic resends. Each event is sent once; a non-2xx code, a reply slower than 10 seconds or a redirect is logged as an error.

Monitor and debug

The webhook page has a delivery history with transaction id, destination URL and attempts columns. History is kept for 30 days.

SymptomUsual cause
A row shows Delivery erroryour endpoint returned a non-2xx code, took longer than 10 seconds or could not be reached — fix it, then click Replay on that row
Attempts above 1 on a rowsomeone clicked Replay on it — each click adds 1; the system never retries on its own
No history at allno event of the type you selected has happened yet
Endpoint pauseduse the activate button to switch it back on

Pausing means missing events

The pause button stops delivery without deleting the configuration or the secret, but events that happen while the endpoint is paused are neither saved nor delivered later. If you still need the events while you fix the receiving system, leave the endpoint running and click Replay on the failed rows once it is fixed.

Check your work

  1. Send a message to an address you know does not exist on a domain you control
  2. Wait a few minutes
  3. Your endpoint receives email.bounced, and the delivery history shows a successful row
  4. That address appears in the suppression list

Step 4 is the cross-check that the system and your application are looking at the same truth.