Webhooks

The email was opened

Posted to the subscriptions to email.opened when the email is opened — the tracking pixel loaded, robots included, like opened_at. Signed and retried like every event. The test event (POST /api/v1/webhooks/{id}/test) arrives under this type too, with data: { test: true, message } and none of the fields of the real event: check data.test first.

postWebhookemail.opened

Headers

Mailcheer-Signaturestring required

t=<unix timestamp>,v1=<hex>: v1 is the HMAC-SHA256 of "<t>.<raw body>" keyed with the subscription's secret. Reject a t more than 300 seconds away from your clock.

Mailcheer-Timestampstring required

The same t, in seconds.

Mailcheer-Event-Idstring required

The event's id — the same on every attempt and every replay: the deduplication key.

Mailcheer-Event-Typestring required

The event's type.

Mailcheer-Delivery-Idstring required

This delivery. A manual replay gets a new one.

Mailcheer-Attemptstring required

The attempt number, starting at 1.

Payload

OR

Example payload

{
  "id": "evt_Ab3cD9eF0gH1iJ2k",
  "type": "email.bounced",
  "created_at": "2026-09-25T08:31:09.020Z",
  "data": {
    "message_id": "cmu651xf200021n7nm68sikfw",
    "email": "nobody@example.com",
    "source": "api",
    "subject": "Your September invoice",
    "reason": "Permanent"
  }
}

Response

Any 2xx within 15 seconds acknowledges receipt. Anything else — another status, a redirect (not followed), no answer, a network error — is retried: 5 attempts in all, the next ones 30 s, 2 min, 10 min and 1 h after the previous failure.

Changes

Webhooks have no change history: a webhook is keyed by its event name rather than a path and method, so no recorded change can name it.