<!-- source: https://secondlayer.tools/docs/api-reference#webhook-replay-progress-object -->

## The Webhook replay progress object

Live state of one replay. While it runs, `delivered` and `gaveUp` are `null`; they are set once no event is left pending.

| Field | Type | Description |
| --- | --- | --- |
| `replayId` | string | 16 hex characters. |
| `webhookId` | string | Webhook id (UUID). |
| `status` | enum | `scanning` while the range is read, `running` while events deliver, `done` when none are pending, `failed` if the scan broke. Values: `scanning`, `running`, `done`, `failed`. |
| `fromBlock` | integer | First block, inclusive. |
| `toBlock` | integer | Last block, inclusive. |
| `total` | integer | Events the replay queued. |
| `processed` | integer | Events delivered or given up on: `total` minus `pending`. |
| `pending` | integer | Events still waiting to be delivered or retried. |
| `delivered` | integer · nullable | Events delivered. `null` until the replay is done. |
| `gaveUp` | integer · nullable | Events that used up their retries. `null` until the replay is done. |
| `startedAt` | string | ISO 8601 time it started. |
| `finishedAt` | string · nullable | ISO 8601 time it finished. `null` while it runs. |
| `error` | string · nullable | Why the scan failed. `null` otherwise. |

```json
{
  "replayId": "a41f09c3d27e8b65",
  "webhookId": "3f1c2a9e-8b7d-4c21-9a55-6e0d4b2f7c18",
  "status": "done",
  "fromBlock": 8650000,
  "toBlock": 8700000,
  "total": 312,
  "processed": 312,
  "pending": 0,
  "delivered": 309,
  "gaveUp": 3,
  "startedAt": "2026-09-22T14:00:02.000Z",
  "finishedAt": "2026-09-22T14:06:40.000Z",
  "error": null
}
```
