← Settings

Delivery webhooks

Let your application know when a message is delivered, delayed or rejected. This is optional. Epistole already tracks delivery for you.

Add an endpoint

Use a public HTTPS URL on port 443 without query parameters. Keep authentication secrets out of the URL.

Events to receive

Receiving events

Verify the Epistole-Signature header against the exact request body before processing an event. Accept timestamps within five minutes, and deduplicate by Epistole-Delivery-Id. Return a 2xx response promptly.

Events start when an endpoint is enabled. Disabling cancels pending callbacks; enabling again does not replay history. Retries may arrive more than once or out of order. Message delivery means the recipient's mail server accepted it, not guaranteed inbox placement.

Python signature verification example
import hashlib, hmac, time

def verify(secret, header, raw_body):
    parts = dict(p.split("=", 1) for p in header.split(","))
    timestamp = int(parts["t"])
    if abs(time.time() - timestamp) > 300:
        return False
    signed = str(timestamp).encode() + b"." + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])
# Reject malformed headers. Store processed delivery IDs durably.