Webhooks allow real-time event tracking across all supported message statuses, including specific delivery, error, and Event Flow events. Webhooks are designed to integrate seamlessly with external systems and offer full transparency of message handling from submission to final delivery or failure.
In this article you will learn more about:
Supported Events
Webhooks support all standard SendPro message events, including a few that are unique to Webhooks such as Delivered and Event Flow-related events.
Note
The events Processed, Submitted and Delivered have a different JSON structure. Click on the specific event for more information and an example.
Message has received a soft bounce
Message has received a hard bounce
Message has received a complaint (feedback loop)
Message is rejected (due to being on the filter list)
Message is discarded (due to discard flowstep)
Message has been delivered (accepted by receiving system)
The DELIVERED from the Webhooks has no equivalent in the Api and
has a different JSON structure than most other responses, see an
example below
[ { "messageEvent": { "id": "ba1bfcc2-67a3-4e28-a8b9-c2b(...)", "messageId": "2025081814(...)", "type": "DELIVERED", "received": "2025-08-18T14:19:59.514Z", "inserted": "2025-08-18T14:19:59.668Z", "snippet": "250 2.0.0 Ok: queued as 7B60551CD8\r\n", "mta": "(...)flowmailer.net [185.136(...)]", "data": null, "extraData": { "vmta": { "hostname": "(...)flowmailer.net" }, "connectionId": "2777(...)", "tls": { "cipher": "TLS(...)", "protocol": "TLS(...)" }, "mx": { "expanded": "(...)flowmailer.net", "original": "(...)flowmailer.net", "address": "185.136(...)" } } }, "messageTags": [] } ]
SMS or Letter has been sent
Delivery has been attempted, and will be retried
Message has been accepted by SendPro
Submitted events use the following structure (adding the message
object).
If your system has difficulty processing these differences, you can set up a separete webhook for Submitted using Filters.
{ "message": { "submitted": "2025-08-18T14:19:00.000Z", "id": "202508(...)", "transactionId": "97a4(...)", "messageIdHeader": null, "messageType": "EMAIL", "source": { "id": "7(...)", "description": "Test source" }, "flow": { "id": "19043", "description": "Test flow" }, "senderAddress": "example@(...).nl", "recipientAddress": "(...)@spotler.com", "backendStart": "2025-08-18T14:19:00.290Z", "backendDone": null, "headersIn": [ { "name": "Received", "value": "from 10.254.11.4 by (Flowmailer API) with HTTPS ID cbc483a(...) for <(...)@spotler.com>; Mon, 18 Aug 2025 16:19:00 +0200 (CEST)" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "From", "value": "Your name " }, { "name": "To", "value": "Your name <(...)@spotler.com>" }, { "name": "Subject", "value": "Example test" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" }, { "name": "Content-Transfer-Encoding", "value": "quoted-printable" } ], "status": "SUBMITTED", "subject": "Example test", "from": "example@(...).nl", "events": null, "fromAddress": { "name": "Your name", "address": "example@(...).nl" }, "toAddressList": [ { "name": "Your name", "address": "(...)@spotler.com" } ], "tags": [ "MyEarlytag" ] }, "messageEvent": { "id": "202508(...)", "messageId": "202508(...)", "type": "SUBMITTED", "received": "2025-08-18T14:19:00.281Z", "inserted": null, "snippet": null, "mta": null, "data": null }, "messageTags": [ "MyEarlytag", "thisisatag" ] }
Message is being handled by SendPro
Processed events use the following structure (adding the message
object).
If your system has difficulty processing these differences, you can set up a separete webhook for Processed using Filters.
{ "message": { "submitted": "2025-08-18T14:19:00.000Z", "id": "20250818141(...)", "transactionId": "97a4d6c277a(...)", "messageIdHeader": "<(...).flowmailer.net>", "messageType": "EMAIL", "source": { "id": "70(...)", "description": "Postman test Api" }, "flow": { "id": "19(...)", "description": "Example flow" }, "senderAddress": "example@(...).nl", "recipientAddress": "(...)@spotler.com", "backendStart": "2025-08-18T14:19:00.290Z", "backendDone": "2025-08-18T14:19:00.623Z", "headersIn": [ { "name": "Received", "value": "from 10.254.11.4 by (Flowmailer API) with HTTPS ID cbc483adb6a(...)5 for <(...)@spotler.com>; Mon, 18 Aug 2025 16:19:00 +0200 (CEST)" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "From", "value": "Your name " }, { "name": "To", "value": "Your name <(...)@spotler.com>" }, { "name": "Subject", "value": "Example test" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" }, { "name": "Content-Transfer-Encoding", "value": "quoted-printable" } ], "headersOut": [ { "name": "MIME-Version", "value": "1.0" }, { "name": "From", "value": "Your name " }, { "name": "To", "value": "Your name <(...)@spotler.com>" }, { "name": "Subject", "value": "Example test" }, { "name": "Content-Type", "value": "text/html; charset=UTF-8" }, { "name": "Content-Transfer-Encoding", "value": "quoted-printable" }, { "name": "Feedback-ID", "value": "543:543-(...):flowmailer" }, { "name": "Message-ID", "value": "<20250(...)@(...).net>" }, { "name": "Date", "value": "Mon, 18 Aug 2025 14:19:00 +0000" }, { "name": "X-Job", "value": "fm-7037-19043" } ], "status": "PROCESSED", "subject": "Example test", "from": "example@(...).nl", "events": null, "fromAddress": { "name": "Your name", "address": "example@(...).nl" }, "toAddressList": [ { "name": "Your name", "address": "(...)@spotler.com" } ], "tags": [ "MyEarlytag", "thisisatag" ] }, "messageEvent": { "id": "42d71b39-57(...)", "messageId": "202508(...)", "type": "PROCESSED", "received": "2025-08-18T14:19:00.623Z", "inserted": null, "snippet": null, "mta": null, "data": null, "extraData": { "totalProcessingTimeMillis": 309 } }, "messageTags": [ "MyEarlytag", "thisisatag" ] }
Message has been opened (tracking pixel has loaded)
Link in message has been clicked (tracking link has been activated)
Message is on Held list, likely due to error
Message has custom event
Message sent to return path
Message has been resent from API or UI
Message on hold, due to scheduling
Message has been resubmitted (resubmit flowstep)
Message cannot be handled due to error
Previous error has been resumed
Message in Event Flow is being handled by SendPro
Message in Event Flow has been accepted by SendPro
Message in Event Flow on hold, due to scheduling
Message in Event Flow cannot be handled due to error
Error in Event Flow has been resumed
Message in Event Flow is discarded (due to discard flowstep)
Response
Webhook responses follow the same JSON format as the Spotler SendPro API. The Inserted status in the API is renamed to Submitted in Webhooks to match better with what you will see in the Dashboard.
Basic Structure
Webhook events can have up to three possible object types:
messageEvent, containing info about the event(s)
message, containing information about the message sent - used in processed and submitted events
messageTags, containing the tags for a message, if Add Message Tags is selected in the interface
Single Event
An event will always have a type (in this case CLICKED). In this example, Message tags are also added.
[ { "messageEvent": { "id": "1fbbaa3d-0a95-4e5d-b266-a0(...)", "messageId": "202503181426(...)", "type": "CLICKED", "received": "2025-08-06T14:10:36.764Z", "inserted": "2025-08-06T14:10:36.815Z", "extraData": { "_mr": "false" }, "referer": null, "remoteAddr": "178.224.132.(...)", "userAgentString": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0", "deviceCategory": "Desktop", "userAgent": "Firefox", "userAgentType": "Browser", "userAgentVersion": null, "userAgentDisplayName": "Firefox", "operatingSystem": "Win10", "operatingSystemVersion": "10.0", "linkTarget": "https://web.flowmailer.net/viewonline.html?id=-4SLb9jkGGk:MRnxuS3q3qCq_(...)", "linkName": "https://web.flowmailer.net/viewonline.html?" }, "messageTags": [ "thisisatag" ] } ]
Multiple Events
A webhook may contain multiple events.
[ { MessageEvent {...} MessageTags {...} }, { MessageEvent {...} MessageTags {...} }, { message {...} MessageEvent {...} MessageTags {...} } ]
Event Flow Events
Event Flow events (such as EVENT_ERROR, EVENT_DISCARD) contain the triggering event.
[ { "messageEvent": { "id": "f65b5ad5-cac5-46b5-9f76-6b(...)", "messageId": "20250318142607736(...)", "type": "EVENT_DISCARD", "received": "2025-08-06T14:10:42.625Z", "inserted": "2025-08-06T14:10:42.871Z", "snippet": "Discarded", "mta": null, "data": null, "extraData": { "eventFlow": { "event": { "received": "2025-08-06T14:10:42.310Z", "id": "236371d0-3804-45e5-af38-0a(...)", "type": "CLICKED" }, "flow": { "id": 132655 } } } }, "messageTags": [ "thisisatag" ] } ]