Event Webhooks
Configure and verify email Webhooks, including seven event types, signatures, idempotency, and manual failure troubleshooting.
Webhooks push email events to your server. Callback configuration is API Key-level and currently requires platform operators; the customer console has no self-service page for Webhook URLs, subscriptions, signing secrets, or delivery logs.
Before activation
- Provide a publicly accessible HTTPS callback URL with a valid certificate. URLs resolving to private, loopback, link-local, or other reserved addresses are rejected.
- Confirm the event types and callback authentication mode.
- Ensure the receiver returns 2xx within 10 seconds without relying on redirects, cookies, or automatic retries.
- Implement deduplication by
eventIdand reconciliation by Message ID.
Subscribable events
eventType | Meaning |
|---|---|
delivered | The receiving server accepted the message; inbox placement and reading are not guaranteed. |
bounced | A bounce event was received. |
complained | A spam complaint was received. |
opened | An open was recorded; tracking configuration and client privacy behavior affect this event. |
clicked | A link click was recorded. |
delivery_delayed | Delivery is delayed, not finally delivered. |
send_failed | The platform Sender produced a definite failure or rejection. |
Open and click events depend on channel tracking support and configuration. send_failed is message-level and has an empty recipient string.
Request format
The platform sends POST with Content-Type: application/json. Common headers include:
X-Innomail-Event: event type;X-Innomail-Event-Id: event task identifier corresponding to the body'seventId.
Example body:
{
"eventId": "EVENT-EXAMPLE-001",
"eventType": "delivered",
"messageId": "SINGLE-EXAMPLE-001",
"recipient": "alice@example.net",
"occurredAt": "2026-11-11T03:00:00Z",
"reasonCode": "",
"reasonMessage": ""
}Treat every field as a string. reasonCode and reasonMessage can be empty. Provider events and Sender failure events draw reasons from different sources and do not share one code table.
Verify callback signatures
The platform configures one of these modes for the API Key. Use the mode and encoding supplied during activation, and never log real secrets.
X-CALLBACK-ID
Header format:
X-CALLBACK-ID: timestamp=<milliseconds>;nonce=<random>;username=<username>;signature=<signature>Computation:
signature = HMAC-SHA256(webhookSigningSecret, timestamp + nonce + username)Concatenate the three values without separators. The default output is lowercase hex; Base64 can be configured by the platform. Recalculate using the exact received timestamp, nonce, and username, compare in constant time, and validate timestamp freshness.
Compatibility mode: X-Innomail-Signature
If no dedicated Webhook username and signing secret are configured, compatibility mode can be used:
signKey = HMAC-SHA256(apiSecret, "innomail-webhook-v1")
material = X-Innomail-Timestamp + "." + X-Innomail-Event-Id + "." + rawBody
X-Innomail-Signature = "sha256=" + lowercaseHex(HMAC-SHA256(signKey, material))rawBody must be the exact received bytes; do not format the JSON first. The signing key is derived, rather than using the API Secret directly as the message HMAC key.
Idempotency and responses
- Use the body's
eventIdas the event deduplication key and persist processing results. - One
messageIdcan legitimately have multiple differenteventTypevalues, so do not deduplicate only by Message ID. - Return 2xx after processing succeeds, or persist first and process asynchronously.
- Each task is currently attempted only once. Connection failures, timeouts, and non-2xx responses are not automatically retried or replayed.
- Do not rely on the old claim that CB- and CBRT- IDs arrive in pairs, and do not wait for an automatic retry that does not exist.
Troubleshooting missing events
- Confirm that the correct API Key has the callback URL, enabled state, and event subscriptions configured by the platform.
- Check public DNS, the HTTPS certificate, resolved addresses, and the 10-second response time.
- Check the signature mode, raw body, timestamp units, and hex/Base64 encoding.
- Compare with send records to confirm that the event occurred; open and click also require channel tracking support.
- Contact platform operators with the Message ID, eventId, occurrence time, and receiver logs. Customers currently have no Webhook delivery-log query or manual replay interface.
Sender failure codes
See Sender failure codes.
FAQ
Why is there no automatic redelivery?
Each Webhook task is currently attempted once. Connection failures, timeouts, and non-2xx responses are not retried or replayed. Keep the receiver available, persist events before asynchronous processing, and reconcile with send records.
Can one message have multiple events?
Yes. One messageId can have several event types. Deduplicate by eventId, not Message ID.
Why does signature verification fail?
Check the configured mode, exact raw body bytes, timestamp units, and hex or Base64 encoding. In compatibility mode, the message signing key is derived from the API Secret.
Related resources
Last updated on