Skip to content

Email delivery events

Markdown

Forwarding delivery, open, bounce and complaint events from your email service to Sayproof.

When your email service reports to Sayproof whether invitations reached the recipient and whether they were opened:

  • The invitation funnel on the Statistics › Invitations tab is calculated in full: invitations sent, delivered, opened, bounced and turned into a review.
  • Addresses that bounce permanently, that complain or that unsubscribe are automatically added to the list of people who do not want emails, and no further invitations are sent to them.

If no delivery events are received, send records remain in the “Sent” state and the open rate is shown as “unknown”; this value is not counted as zero.

  1. On the Email delivery events tab of the Integration screen (shown only if your own system sends the invitations), press Connect on the Email delivery events card. The Email delivery events password is shown only once.
  2. Once connected, open the collapsed Addresses to enter in your email service section on the card; it lists the endpoint addresses to enter in your email service. Enter the matching address in the webhook setting of the service you use.
Service Authentication
Generic (signed notice) The request is signed with the same three headers as signed order sending
Amazon SES (through SNS), SendGrid, Postmark, Mailgun The address contains an access code specific to your brand

The service you use is shown on the card once the first event arrives.

To disconnect, press Disconnect on the card; after confirmation, events from your email service are no longer taken. To connect again, create a new password with Connect and enter it in your email service.

Event Effect
delivered The send’s state becomes “Delivered”
deferred The send’s state becomes “Delayed, will be retried”
opened “Opened” is recorded; the send is also counted as delivered
bounced The send’s state becomes “Bounced”. If the bounce is permanent, the address is added to the list of people who do not want emails
complained The send’s state becomes “Customer complained” and the address is added to the list
unsubscribed The address is added to the list

The state only moves forward: a deferred event that arrives late does not undo the “Delivered” state. Only a hash of the address is written to the list, not the address itself. Service notices (rejection notices) are not affected by this list.

Only an event that matches an email sent by Sayproof adds an address to the list; an event that does not match is stored, is not counted in matched and does not change the list. The address added is the one the email was sent to; a different recipient address in the event is ignored.

For your own email system, or for a service that is not listed:

POST https://api.sayproof.example/v1/mail-events/generic
Content-Type: application/json
X-Sayproof-Secret: PASSWORD-ID
X-Sayproof-Timestamp: 2026-09-28T10:00:00+03:00
X-Sayproof-Signature: …
{
"events": [
{
"type": "delivered",
"reference": "SEND-ID",
"message_id": "service-message-id",
"recipient": "jane@example.com",
"occurred_at": "2026-09-28T10:00:00+03:00",
"permanent": false,
"event_id": "evt-1",
"detail": "hard_bounce"
}
]
}
  • A single event or a list of up to 500 events can be sent; the body can be at most 1 MB.
  • type is one of: delivered, deferred, bounced, complained, opened, unsubscribed. Other types are added to the ignored count in the response and are not processed.
  • permanent: true is only taken into account for a bounced event.
  • detail is stored as a code; email addresses in it are replaced with the word address before it is stored.
  • If a text field contains a character that cannot be stored (NUL \u0000 or an unpaired surrogate), the request is refused with 400 invalid / field_invalid.
  • If an event_id that has already been processed is sent again, it is not processed and is added to the duplicates count.
  • The signature rules are the same as for order transfer. Up to 600 requests can be sent in 5 minutes per password.
  • The ID in the X-Sayproof-Secret header is the Password ID column of the Email delivery events password row in the table in the Advanced: signing passwords section of the Channels › Keys tab.

Response: {"accepted", "matched", "duplicates", "ignored", "opted_out"}.

Sayproof determines which email an event belongs to from the reference field first and, if nothing is found, from the service’s message ID (message_id).

  • Every email Sayproof sends carries the X-Sayproof-Message header. Send this value back as reference in your service’s event. For the services supported out of the box, the field read is custom_args.sayproof_message for SendGrid, Metadata.sayproof_message for Postmark and user-variables.sayproof_message for Mailgun.
  • If you send invitations from your own system, add the event_id value from the Sayproof request to the email as the X-Sayproof-Message header; this value comes back as reference in the event.