MailerHandleWebhook¶
POST mailer/handleWebhooks/:uuid
The public endpoint an email provider posts events to. It is not called by integrations — the URL is configured in the provider dashboard and comes from MailerAddWebhook.
The module finds the webhook by uuid, verifies the signature, asks the provider adapter to
translate the payload, and applies the result: a status change, an engagement counter, or a
new suppression entry.
Access Control¶
Public. There is no session: the request is authenticated by the unguessable uuid plus the signature check against the webhook secret.
Request¶
{}
{
"command": "MailerHandleWebhook",
"extID": "1",
"data": {}
}
const res = await platform.MailerHandleWebhook({});
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
uuid |
string | Webhook identifier from the URL |
Behavior¶
- The endpoint always answers
200, even when the event is rejected: a provider retry cannot fix a wrong signature or an unknown message, and retry storms are worse than a recorded rejection. - A hard bounce, a block or a complaint adds the address to the suppression list automatically — that is the whole point of receiving these events.
- Opens and clicks are not statuses: they land in their own counters, so one open cannot overwrite the fact of delivery and a second one cannot overwrite a complaint.
DELIVERED → COMPLAINEDis the one allowed transition out of a final status: a spam complaint arrives after delivery, sometimes hours later, and dropping it would hide the most damaging signal there is.
Response Data¶
A rejected event answers with the same shape, where result is not PROCESSED and reason says why: WEBHOOK_NOT_FOUND, PROFILE_NOT_FOUND, PROFILE_NOT_IN_WEBHOOK_MODE, PROVIDER_NOT_FOUND, PROVIDER_WEBHOOKS_DISABLED, ADAPTER_HAS_NO_WEBHOOK_SUPPORT, NO_EXTERNAL_CALL_ID, UNVERIFIED, NO_EMAIL.
{
"result": "PROCESSED",
"emailId": 812,
"changed": true,
"status": "BOUNCED",
"suppressed": "HARD_BOUNCE"
}
Errors¶
| Code | Error | Description |
|---|---|---|
200 |
UNVERIFIED |
Signature did not match the webhook secret; the event is stored and ignored |
200 |
DUPLICATE |
This provider event was already applied |
500 |
INTERNAL_ERROR |
Module could not process the event; it is stored with result: "ERROR" |