Skip to content

Event Callbacks

DUO can notify your application when something happens to a message it sent: delivery, bounce, open, click or unsubscription. You give DUO a URL in the event_callback parameter, and DUO sends a POST request to that URL with the event and the contacts it applies to.

Where to set the URL

Send type Where Parameter
Campaigns (email and SMS) POST /campaign or PUT /campaign/<campaign> event_callback
Transactional messages Each send request event_callback

Warning

For transactional messages, the URL must be sent in every send request. The event_callback field of the transactional message itself is stored but not used for callbacks.

The URL must use http or https and include a host and a path, e.g. https://example.com/duo/events. Use https.

Events

event Meaning Email SMS
submitted The message was submitted for delivery ✓
delivered The message was delivered ✓ ✓
bounced The message was not delivered because of a permanent error ✓ ✓
opened The message was opened ✓
clicked A link in the message was clicked ✓
unsubscribed The contact unsubscribed through the unsubscribe link ✓

There is no event for spam complaints.

The request

DUO sends a POST with Content-Type: application/x-www-form-urlencoded to the URL, without its query string. The body has these fields:

Field Type Description
event string The event, as in the table above
when int Unix timestamp of the event, rounded down to the minute
email[<n>] string Email of each contact the event applies to. Empty if the contact has no email.
telephone[<n>] string Telephone of each contact. Empty if the contact has no telephone.

Events are grouped before they are sent. One request covers one event type for one campaign or transactional message, and lists every contact it applies to in that period, using the same index <n> in email[], telephone[] and any per-contact field. The request can arrive up to five minutes after the event.

Example request body (decoded):

event=delivered
when=1793701080
email[0]=ana@example.com
telephone[0]=351910000001
email[1]=bruno@example.com
telephone[1]=

Adding your own fields

Parameters in the query string of the event_callback URL are moved into the request body.

  • A fixed value is sent unchanged, once per request. Use it to identify the source or to send a secret token (see Delivery and security).
  • A placeholder is replaced with each contact's value and sent as an array, with the same index as email[].
Placeholder Value
%CustomField:<id>% The contact's value for the custom field <id> of the list
%List:ID% The contact list ID
%EventPayload:externalid% Transactional SMS only: the externalid[] value sent with the message

Placeholders must be URL-encoded in the URL: %CustomField:42% is written %25CustomField%3A42%25.

Example: with this callback URL

https://example.com/duo/events?source=newsletter&token=s3cr3t&customer=%25CustomField%3A42%25

DUO sends POST https://example.com/duo/events with:

source=newsletter
token=s3cr3t
event=opened
when=1793701080
email[0]=ana@example.com
telephone[0]=351910000001
customer[0]=C-1001

Delivery and security

  • No retries. Each request is sent once. DUO does not read the response, and a failed request is not repeated. If you need every event, also use the statistics endpoints, such as Campaign Stats or Transactional Stats.
  • No signature. Requests are not signed. To check that a request comes from DUO, put a secret token in the URL query string, as in the example above, and compare it on your side.
  • Answer quickly with any 2xx status and process the events afterwards.
  • Expect duplicates and gaps. Design the receiver so that processing the same event twice does no harm.