> For the complete documentation index, see [llms.txt](https://support.ordereazi.com/central/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://support.ordereazi.com/central/developers/webhooks/delivery-and-troubleshooting.md).

# Delivery and troubleshooting

How OrderEazi delivers and retries webhooks, how to build an endpoint that handles them, and what to check when deliveries fail.

If your endpoint is down, slow, or answers with an error, you can miss events or act on the same one twice. Knowing how OrderEazi sends webhooks, and when it tries again, lets you build an endpoint that handles both.

### How deliveries are sent

* **Queued first:** When an event happens, OrderEazi queues a delivery for each webhook registered for it. Each delivery carries a payload (the data about the event).
* **Sent once a minute:** Every minute, OrderEazi sends the queued deliveries, one at a time, about a second apart. Most arrive within 2 minutes of the event.
* **Stock and product events:** Stock level changes are gathered every few seconds, and product changes every 30 seconds. They're sent on the next run.
* **New webhooks:** A new webhook can take up to a minute to start receiving events.

### Which responses count as delivered

* **Any 2xx status code (200 to 299):** OrderEazi marks the delivery as delivered.
* **422 Unprocessable Content:** OrderEazi stops at once, without trying again. Use this only when the payload can never be used.
* **Any other status code:** OrderEazi tries again on the next run.
* **No answer within 100 seconds, or a connection error:** OrderEazi tries again on the next run.

OrderEazi makes up to 4 attempts in all: the first, and 3 retries about a minute apart. After the 4th attempt fails, it stops trying, and the delivery shows as **Failed**. The `X-OE-Webhook-Attempt` header says which attempt it is, and `X-OE-Webhook-Final-Attempt` is `true` on the last one.

OrderEazi keeps the first 255 characters of your endpoint's response, so a short, clear error message helps whoever checks the delivery.

### How to build a reliable endpoint

* **Answer quickly:** Save the payload, answer with a 2xx status code, and do the work afterwards. A slow answer holds up every other delivery in the queue.
* **Expect duplicates:** The same delivery can arrive twice, such as when your endpoint did the work but answered too late. Retries keep the same `X-OE-Webhook-Id`, so check it before you act.
* **Check the record too:** A delivery you resend gets a new ID. Also check the record itself, such as the document number, and skip changes you've already made.
* **Don't rely on order:** Deliveries usually arrive in the order the events happened, but a retry arrives after newer deliveries. Use the dates in the payload, or read the record through the API, to get its latest state.
* **Return 422 only for bad payloads:** If your system is just busy or down, return any other error, so OrderEazi tries again.

### How to resend a delivery

Resending is done in OrderEazi, not through the API. You'll need the **Webhooks** permission, in the **Integrations** permission group.

> **Warning:** Resending sends the payload to your endpoint again. Make sure your endpoint skips changes it has already made.

1. In the main menu, go to **Integrations** > **Webhooks**.
2. Select the **Queue** tab.
3. Filter by **Failed** to see deliveries that ran out of attempts.
4. Select the delivery to open its details.
5. Select **Resend now**.
6. Select **Resend** to confirm.

You see "Delivery #" and its number "has been requeued." The delivery is sent straight away, with the same payload and a new `X-OE-Webhook-Id`. See [Webhooks](/central/order-management/integrations/webhooks.md).

File links in a resent `OnWorkflowActionCompleted` delivery may have expired. Get the file with `GET /api/project/{pro}/attachment` instead, where `{pro}` is the project number.

### How long deliveries are kept

Deliveries are kept in the queue for about 90 days, then removed, whether they were delivered or not. To keep payloads longer, save them when your endpoint receives them.

### When deliveries don't arrive

1. Check the webhook is registered for the right event and address, with `GET /api/webhook/list`.
2. Make the event happen, then wait 2 minutes.
3. In OrderEazi, go to **Integrations** > **Webhooks**, and select the **Queue** tab.
4. Find the delivery. If there's none, the event didn't happen, or the webhook isn't registered for it.
5. Select the delivery to see your endpoint's response, or the error, such as a timeout.
6. Check your endpoint can be reached from the internet, at that exact address, and answers with a 2xx status code within a few seconds.

**When a delivery shows as Retrying or Failed:**

* **NotFound (404) or MethodNotAllowed (405):** The address is wrong, or the endpoint doesn't accept POST requests.
* **Unauthorized (401) or Forbidden (403):** Your endpoint refused the request. Check the address is exactly what your endpoint expects.
* **A timeout:** Your endpoint took longer than 100 seconds. Answer first, and do the work afterwards.
* **InternalServerError (500):** Your endpoint failed while handling the payload. Check your system's logs, fix the problem, and resend.

**Example:** Your endpoint is down for an hour, and 12 `OrderDispatched` deliveries show as **Failed**. Once it's back, you filter the **Queue** by **Failed** and resend each one. Your shop checks each `ProjectNumber` against the orders it has already marked as dispatched, and emails only the customers it hadn't told yet.

### Related pages

* [Webhooks](/central/developers/webhooks.md): how webhooks work, and the headers each delivery has
* [Managing webhooks](/central/developers/webhooks/managing-webhooks.md): register and remove webhooks
* [Webhooks](/central/order-management/integrations/webhooks.md) in Order Management: check and resend deliveries in OrderEazi
