Define a minimal, versioned event contract
A webhook should say that an event occurred and provide enough stable context to retrieve or process it safely. Define the event type, schema version, unique delivery and event identifiers, occurrence time, subject reference, resource version, and a correlation identifier. Minimise health data in the payload and document which fields are immutable.
- Separate the event identifier from the delivery attempt identifier.
- Version the contract additively and state how long older versions remain accepted.
- Use opaque references where a consumer can retrieve authorised details through an API.
- Publish acknowledgement, retry, ordering, retention, and redelivery semantics.
Authenticate the raw delivery before processing
Require HTTPS and authenticate each delivery. A common vendor pattern signs the exact raw request body with a high-entropy shared secret and sends the digest in a header. The receiver calculates the expected digest and uses a constant-time comparison before parsing or acting on the payload. Never hard-code the secret in source control. [1][3]
- When the provider's documented signature scheme includes a signed timestamp, validate it using that scheme's specified tolerance.
- Where the provider documents stable event or delivery identifiers, use them to detect repeat processing under the agreed replay policy.
- Document and test secret rotation using the provider's supported procedure; do not assume that two verification secrets may overlap.
- Limit request size and content type before expensive parsing.
- Do not log secrets, signatures, access tokens, or full sensitive payloads.
A secure webhook delivery loop
A five-step loop from authenticated receipt through durable processing, safe retry, and source-to-destination reconciliation.
- Verify
Check TLS, raw-body signature, size, and the provider's documented replay controls.
- Accept
Persist the event and acknowledge only after durable queue admission.
- Process
Apply idempotent effects with version and ordering safeguards.
- Recover
Retry with backoff, inspect failures, and redeliver under audit.
- Reconcile
Compare authoritative source state with completed destination state.
Acknowledge quickly, then process asynchronously
After authentication and basic validation, persist the delivery durably and return a successful response within the provider's timeout. Perform clinical-system writes in a worker so transient latency does not trigger overlapping delivery attempts. Queue admission must fail closed: do not acknowledge a delivery that has not been durably accepted. [2]
- Partition work only when the ordering contract requires it, such as by patient or assessment identifier.
- Set bounded retry counts with exponential backoff and jitter.
- Move exhausted work to a reviewable failure queue instead of discarding it.
- Keep a controlled redelivery tool that preserves the original event identity.
Make every downstream effect idempotent
Duplicate delivery can occur through provider retry or operator redelivery, so downstream effects must be idempotent. Store processed event identifiers under a uniqueness constraint and use stable business identifiers for writes. HTTP defines PUT as idempotent, but a POST-based operation needs an application-level idempotency key or duplicate-detection rule before an implementation retries it automatically. [4][5]
Monitor, reconcile, and rehearse recovery
Measure accepted, rejected, queued, retried, completed, and dead-lettered deliveries. Alert on age and clinical impact, not only raw error rate. Periodically compare authoritative source records with successfully processed destinations because monitoring cannot detect an event that was never emitted.
- Trace by non-sensitive correlation identifiers across delivery, queue, API write, and review states.
- Test invalid signatures, expired provider-signed timestamps where applicable, duplicates, reordering, queue outage, destination outage, and secret rotation.
- Define who can redeliver, how that action is audited, and how duplicate effects are prevented.
- Maintain a manual clinical fallback and communicate delayed processing to its owner.
Sources and further reading
- Validating webhook deliveries (opens in a new tab)GitHub Docs. Accessed 2026-07-13. Official vendor guidance for HMAC validation, secret storage, raw payload handling, and constant-time comparison.
- Best practices for using webhooks (opens in a new tab)GitHub Docs. Accessed 2026-07-13. Official vendor guidance on secrets, replay protection, asynchronous handling, and redelivery.
- OWASP API Security Top 10 - 2023 (opens in a new tab)OWASP Foundation. Accessed 2026-07-13. OWASP community-maintained API security risk taxonomy covering authorization, resource consumption, inventory, and unsafe API consumption.
- RFC 9110: HTTP Semantics (opens in a new tab)Internet Engineering Task Force. Accessed 2026-07-13. Internet Standard defining safe and idempotent HTTP method semantics.
- FHIR R4 RESTful API (opens in a new tab)HL7 International. Updated 2019-11-01. Accessed 2026-07-13. Official FHIR guidance for conditional writes, transactions, versioning, and response outcomes.
- NIST SP 800-61 Rev. 3: Incident Response Recommendations (opens in a new tab)National Institute of Standards and Technology. Published 2025-04-03. Accessed 2026-07-13. Current NIST guidance for integrating incident response across cybersecurity risk management.