Payload envelope
Your webhook endpoint receives a fixed envelope. The same JSON ispayload on a delivery when you fetch it from the SDK:
type is the trigger you subscribed to. On the ledger record the SDK returns, that field is called trigger; in the body your endpoint parses, it is type. data holds ids and counts for that trigger, not clinical field values:
Verifying the signature
Every webhook delivery carries anOlira-Signature header: t=<unix_ts>,v1=<hex_hmac>. Recompute it with your destination’s signing secret and compare; this proves the request came from Olira and was not altered in transit.
Reject a missing or malformed timestamp, one too far in the past (replay), or one unreasonably far in the future (clock skew or forgery) before checking the signature at all. During secret rotation the header carries two v1= entries; check if any matches, don’t assume there’s exactly one. The timestamp is fresh on every attempt, including retries.
rotate_action_destination_secret returns the new secret once, the same way create does.
Retries and the ledger
Failed webhook deliveries retry automatically, then stop if they keep failing. A destination that fails long enough is auto-disabled (20+ consecutive failures over 72 hours or more); re-enable it before you expect new sends. Every attempt is a row in the delivery ledger: pending or sending, delivered, retrying, dead-lettered, skipped, orbuffered (waiting for that destination’s daily digest — that can be close to a day, not a few minutes). List and open deliveries in the Console, or with list_action_deliveries and get_action_delivery (the latter includes the exact JSON that was sent).
redeliver_action_delivery resends the same body as the original, not a newly generated one. That works for up to 30 days. If the destination is disabled, re-enable it first (HTTP 409 otherwise).
