> For the complete documentation index, see [llms.txt](https://docs.mdintegrations.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mdintegrations.com/partner/troubleshooting/webhook-reliability.md).

# Webhook Reliability

Build webhook receivers that validate, acknowledge, and process deliveries safely.

Webhooks notify your system about events such as Encounter updates, messages, and pharmacy fulfillment. Because delivery over the network is never perfectly reliable, you should build your receiver assuming deliveries can arrive late, arrive more than once, or fail outright — the practices below are what keep that from turning into a real problem.

### Acknowledge before processing

Validate the request, persist the delivery, then return `2xx` promptly, and only after that's done should you process the event — hand it off to a queue or background worker rather than working through it inline.

This ordering matters because a delayed response can trigger a retry on MDI's side. Avoid performing slow downstream work before responding, or you risk triggering the very duplicate deliveries you're trying to avoid.

### Verify every request

Verify both configured security mechanisms before processing anything else:

1. Compare the request's `Authorization` header with your configured static value.
2. Recompute the HMAC-SHA256 signature from the raw request body.
3. Compare it with the request's `Signature` header.
4. Reject the request when either check fails.

Make sure you're using the secret and authorization value that correspond to the environment you're receiving in, and never log either value.

{% hint style="warning" %}
Verify the signature against the raw request body. Re-serializing parsed JSON can change the bytes and cause a mismatch.
{% endhint %}

### Make processing idempotent

The same delivery can arrive more than once — that's expected behavior during retries, not a bug — so your handling logic needs to tolerate it gracefully rather than assume each delivery is unique.

The way to do that is with an idempotency key that identifies the state transition, such as the Encounter ID paired with the event status. Record the keys you've already processed and skip anything that comes in as a duplicate.

### Protect the transport

{% hint style="danger" %}
Serve webhook endpoints over HTTPS only. HTTP endpoints expose patient-related data in transit and are unsupported.
{% endhint %}

Beyond the transport itself, keep Sandbox and Live fully separated: use distinct endpoints, secrets, and authorization values for each, and never route Sandbox events into Live workflows.

### Monitor delivery health

Log each delivery with its timestamp, event type, resource ID, and processing result, while excluding protected health information from those logs.

From there, alert on repeated verification failures, processing failures, and unexpected delivery gaps, since these often point to an invalid endpoint, expired configuration, or a downstream outage rather than a one-off blip.

It's also worth cross-checking your own logging against the Partner Portal's **Webhook Logs** view, which independently records the delivery attempts and the response your endpoint returned for each event — useful for confirming what MDI actually sent versus what you captured on your end. When a delivery needs to be redelivered outside the automatic retry schedule, use **Resubmit Webhook** from that same view to trigger it manually.

### Test before launch

Before enabling Live traffic, use Test Bench to exercise your Sandbox endpoint with realistic payloads, and confirm signature checks, asynchronous processing, failure handling, and duplicate delivery behavior all work the way you expect.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.mdintegrations.com/partner/troubleshooting/webhook-reliability.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
