> ## Documentation Index
> Fetch the complete documentation index at: https://docs.edplay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Deliveries, Retries, and the Delivery Log

> How to respond to a delivery, when Edplay retries a failure, and how to read the delivery log to see exactly what happened.

## Respond fast

Return a `2xx` status as quickly as you can. Any non-`2xx` response, or no response within **3 seconds**, counts as a failure and triggers a retry.

Do not do real work inside the request. Validate the signature, put the payload on your own queue, return `200`, and process it afterwards.

```text theme={null}
receive → verify signature → enqueue → 200 OK        ← under 3s
                                  ↓
                            process later
```

## Two rules for your handler

<AccordionGroup>
  <Accordion title="Be idempotent" icon="fingerprint">
    A retry can deliver the same event twice, and `course.progress_updated` fires often. Deduplicate on `user.id` plus `course.id` plus `occurred_at`, or make your write naturally idempotent.
  </Accordion>

  <Accordion title="Do not trust arrival order" icon="shuffle">
    Deliveries are queued and retried independently, so a later event can arrive before an earlier one. Order your processing by `occurred_at`, never by arrival time.
  </Accordion>
</AccordionGroup>

## Retries

If a delivery fails, Edplay retries automatically:

| Attempt | When                                    |
| ------- | --------------------------------------- |
| 1       | Immediately                             |
| 2       | About 10 seconds after attempt 1 fails  |
| 3       | About 100 seconds after attempt 2 fails |

After the third failure Edplay stops. The event is not redelivered later.

<Warning>
  A prolonged outage on your side means lost events. If your receiver is down for more than a couple of minutes, backfill the missing data through the API.
</Warning>

A delivery counts as failed when your endpoint:

* returns any non-`2xx` status,
* takes longer than 3 seconds to respond,
* closes the connection, or
* presents an invalid or untrusted TLS certificate.

## Read the delivery log

Go to **Workspace Settings** > **Integrations** > **Webhooks** > **Delivery log**. It shows the 20 most recent attempts, newest first.

| Column        | What it shows                                                        |
| ------------- | -------------------------------------------------------------------- |
| **Event**     | Which event, and which attempt number this row represents.           |
| **Status**    | **Pending** (queued, not yet settled), **Delivered**, or **Failed**. |
| **Response**  | The HTTP status your endpoint returned, or **No response yet**.      |
| **Attempted** | When Edplay last tried.                                              |

Click **Show details** on a row to see the exact URL Edplay called, the error message, and the response body your endpoint returned. That response body is usually enough to tell a signature rejection from an application error.

<Note>
  A test send is queued rather than sent inline, so its row appears a moment after you click **Send test event**. Use **Refresh** if it is not there yet.
</Note>

<Tip>
  Every row has a **UUID**. If you need help from Edplay support, send that UUID and the approximate timestamp — it is enough to trace the call end to end.
</Tip>

Next: [Troubleshooting](/webhooks/troubleshooting)
