> 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/technical-concepts/retry-policy-and-idempotency.md).

# Retry Policy & Idempotency

Networks fail, endpoints time out, and deployments happen mid-delivery. This page covers what MDI does when your endpoint doesn't acknowledge a webhook, and what you need to build on your side so that retries and repeated events never cause harm.

## Retry policy

When MDI delivers a webhook, it expects your endpoint to respond quickly with a 2xx status code. If it doesn't — because your endpoint returns a non-2xx status, or the request times out — MDI treats the delivery as failed and retries it.

**Timeout**: your endpoint has **15 seconds** to return an HTTP 200. If it doesn't respond within that window, the delivery attempt is considered failed and a retry is queued — even if your endpoint eventually would have succeeded, so this is a hard cutoff to design around, not a soft guideline.

**Retry schedule**: MDI retries a failed delivery **6 times**, on a fixed, increasing backoff, spanning roughly 24 hours in total before giving up:

| Attempt   | Delay after previous attempt |
| --------- | ---------------------------- |
| 1st retry | 15 minutes                   |
| 2nd retry | 30 minutes                   |
| 3rd retry | 1 hour                       |
| 4th retry | 4 hours                      |
| 5th retry | 8 hours                      |
| 6th retry | 11 hours                     |

If all 6 retries fail, the webhook is marked **permanently failed** and MDI stops attempting delivery. If your endpoint is down or misconfigured for an extended period, events sent during that window can exhaust the full schedule and never successfully arrive, so it's worth monitoring for that scenario rather than assuming delivery eventually happens no matter what.

{% hint style="warning" %}
Respond fast. If your endpoint does slow, synchronous work — database writes, downstream API calls, calling out to your own services — before returning a status code, you risk hitting the 15-second timeout and being counted as a failure even though your system would have eventually processed it correctly. Acknowledge with a 2xx as soon as you've durably received the payload, then do the heavy lifting asynchronously in a background job.
{% endhint %}

## Cross-check with Webhook Logs

The Partner Portal's **Webhook Logs** view gives you an independent way to check delivery health beyond whatever your own endpoint logs — for each webhook event, it shows the delivery attempts and the response your endpoint sent back, which is often the fastest way to tell whether a problem is on MDI's side or yours.

If a delivery needs to be redelivered without waiting for the automatic retry schedule described above, use the **Resubmit Webhook** action from that same view to manually re-trigger it.

## Why idempotency matters

Retries mean your endpoint can receive the same logical event more than once — for example, if your server processed a webhook successfully but the acknowledgment response was lost in transit, MDI has no way to know that and will retry anyway. On top of that, **no delivery-ID or dedup key is guaranteed today**, so you cannot rely on MDI handing you a unique identifier to detect duplicates automatically.

This means your endpoint must be idempotent: processing the same event twice should never produce a different or duplicated result than processing it once.

## Recommended pattern

Since there's no guaranteed dedup key, build your own using the data already present in the payload:

{% stepper %}
{% step %}
Key off the **Encounter (case) ID** combined with the status or event it represents — for example, "case `1234` reached `Completed`."
{% endstep %}

{% step %}
Before processing an incoming event, check whether you've already recorded that same key.
{% endstep %}

{% step %}
If you have, ignore the event rather than re-processing it (don't re-send notifications, don't re-run fulfillment logic, don't double-write records).
{% endstep %}

{% step %}
If you haven't, process it and store the key so future duplicates are recognized.
{% endstep %}
{% endstepper %}

This same principle extends to any event type in the Webhook Event Catalog — messages, orders, subscription changes — not just Encounter status. Whatever the event, pick a key that uniquely identifies "this specific thing happened," not just "an event of this type occurred."

{% hint style="warning" %}
Out-of-order delivery is possible given retries and queueing. Design your status-handling logic to tolerate a later event describing an earlier state — for example, don't assume a `Completed` event can never be followed by a stray retried `Assigned` event for the same case. Guard against overwriting a more advanced state with a stale one.
{% endhint %}


---

# 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/technical-concepts/retry-policy-and-idempotency.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.
