Webhook Responses
Webhook When Tiny Relay sends a webhook event to your specified endpoint, the response will include the relevant event data as outlined below. To ensure you successfully receive these events, you will need to whitelist the following IP address from which Tiny Relay will send the events: 3.229.12.181. Please configure your firewall or security settings accordingly to allow traffic from this IP.
List of Webhook Events
| Event | Description |
|---|---|
| SEND | Event triggered when email is sent successfully |
| DELIVERED | Event triggered when email gets delivered |
| BOUNCED | Event triggered if email gets bounced |
| OPEN | Event triggered when email is opened by the recipients |
| CLICK | Event triggered if recipients clicks on a redirect link present in the email |
| UNSUBSCRIBE | Event triggered if receiver clicks on the unsubscribe link |
| SPAM | Event triggered if email gets marked as spam |
Delivery semantics
Delivery is at-least-once. If your endpoint times out or returns a 5xx we retry, and every retry of a given event repeats the same delivery id header — deduplicate your processing on that id rather than assuming each request is a distinct event.
On top of that, we suppress repeats before they leave us. Each event is given an identifier derived from the event's own identity — including the recipient, the event type and the time the event happened — so re-processing the same event reproduces the same identifier.
That suppression lasts 24 hours. Within the window, a repeat of an event you have already been sent is dropped before delivery. Beyond it, the same event re-processed would reach you again, so size your own deduplication store accordingly: 24 hours is how long we do it for you.
What the identifier does and does not collapse:
- A genuine repeat still reaches you. A second open or click by the same recipient happens at a different time, so it is a different event and is delivered on its own.
- A recipient listed twice in one send receives one
SENDevent, not two, because the two are identical on every field we can distinguish them by. - An event missing part of its identity is not deduplicated at all and may reach you more than once. That means an event with no occurrence time, no recipient, or no event type. This is deliberate — a duplicate you can discard, a dropped event you cannot recover.
Replay window
Event payloads are retained for 5 days currently. A missed event can be redelivered within that window; after it passes, the payload is gone and cannot be replayed. Retention does not affect normal delivery or retries.
Request
- application/json
Body
Possible values: [SEND, DELIVERED, BOUNCED, OPEN, CLICK, UNSUBSCRIBE, SPAM]
Represents the type of event that has occurred.
Possible values: [HARD_BOUNCED, SOFT_BOUNCED]
Represents the sub-type of the main event. For example, in the case of a bounced event we can have hard or soft bounces.
A string representing Unique identification(UUID) for each webhook request
Receiver's email address
Request Id provided sent as response to Send Email
Campaign Id provided to Send Email to track the campaign. If not provided, the generated requestId is used as the campaignId.
Metadata is stored against this campaignId. All requests using the same campaignId share the same metadata slot, and the latest metadata value replaces the previous value.
metadata object
Metadata associated with the send. This field is always present on v1 webhook payloads.
The metadata is echoed using normalized lowercase snake_case keys. If the send had no metadata, the metadata has expired, or the metadata could not be resolved, this field is returned as an empty object.
Metadata is best-effort and its absence does not delay or prevent webhook delivery.
Time the event occurred, in milliseconds since the Unix epoch (UTC), as a string.
Always present. If the event reached us without a time of its own, this falls back to the time we
processed it — so the field is never empty, but it is not always the moment the event happened. Use
eventTime when you need to tell those two cases apart.
Changed: this field previously carried a nanosecond counter (a 16-digit value such as
9748919598886666) that was not a wall-clock time and could not be converted to one. It is now a 13-digit epoch-millisecond timestamp. If you parserequestTime, check the value length.
Time the event actually occurred, in milliseconds since the Unix epoch (UTC).
This is the time the event happened, not the time the webhook was delivered. Delivery is asynchronous and retried, so the time your endpoint receives a request is not a reliable substitute. Use this field to order or timestamp events.
null on the rare event that reaches us without a time of its own. Unlike requestTime, this field
does not fall back to processing time — a null here is the signal that the occurrence time is
genuinely unknown.
Note: the interactive request builder on this page does not list this field yet. It is sent on every event type; the schema above is authoritative.
Represents the category of bounce.
Represents the description of bounce(dsn_diag).
Represents the status of bounce(dsn_status).