# List deliveries

Source: https://help.ruuster.com/api/webhooks-deliveries

```http
GET https://api.ruuster.com/v1/webhooks/{webhookId}/deliveries
```

Delivery attempts for one subscription from the last 30 days, newest first.

- Authentication: `x-api-key` and `x-email` headers of an owner or admin
- Rate limit: 120 requests per minute per key

## Path parameters

| Name | Type | Description |
|---|---|---|
| `webhookId` | string | The subscription id, `whk_…` |

## Query parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `status` | string | | `pending`, `delivered`, `failed` or `dropped` (subscription deleted) |
| `from` | date | | First day, `YYYY-MM-DD`, included |
| `to` | date | | Day after the last day, `YYYY-MM-DD`, excluded |
| `cursor` | string | | `meta.nextCursor` from the previous page. Omit for the first page |
| `limit` | integer | `100` | Rows per page, 1 to 500 |

## Response

Each item in `data.deliveries`: `deliveryId`, `eventId`, `kind`, `attempt`, `status`, `statusCode`, `error`, `latencyMs`, `attemptedAt`, `nextRetryAt` (for `pending`). Kept 30 days.

## Example request

cURL:

```bash
curl -s "https://api.ruuster.com/v1/webhooks/whk_2c7f9a4e1b/deliveries?from=2026-10-01&to=2026-10-02&limit=2" \
  -H "x-api-key: $RUUSTER_API_KEY" \
  -H "x-email: $RUUSTER_EMAIL"
```

Node.js:

```javascript
const res = await fetch("https://api.ruuster.com/v1/webhooks/whk_2c7f9a4e1b/deliveries?from=2026-10-01&to=2026-10-02&limit=2", {
  headers: {
    "x-api-key": process.env.RUUSTER_API_KEY,
    "x-email": process.env.RUUSTER_EMAIL,
  },
});
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.requestId})`);
console.log(body.data);
```

Python:

```python
import os
import requests

res = requests.get(
    "https://api.ruuster.com/v1/webhooks/whk_2c7f9a4e1b/deliveries?from=2026-10-01&to=2026-10-02&limit=2",
    headers={"x-api-key": os.environ["RUUSTER_API_KEY"], "x-email": os.environ["RUUSTER_EMAIL"]},
    timeout=30,
)
body = res.json()
if not body["ok"]:
    raise RuntimeError(f'{body["error"]["code"]}: {body["error"]["message"]} ({body.get("requestId")})')
print(body["data"])
```

## Example response

```json
{
  "ok": true,
  "data": {
    "deliveries": [
      { "deliveryId": "dlv_4d7b2e90c1", "eventId": "evt_9a17f2c4b8e05d31", "kind": "lead.tour_request",
        "attempt": 1, "status": "delivered", "statusCode": 200, "error": null, "latencyMs": 212,
        "attemptedAt": "2026-10-01T15:42:10Z", "nextRetryAt": null },
      { "deliveryId": "dlv_1f9c6a38e2", "eventId": "evt_2b84d0e6c97f1a53", "kind": "lead.favorite",
        "attempt": 2, "status": "pending", "statusCode": 503, "error": "Service Unavailable", "latencyMs": 640,
        "attemptedAt": "2026-10-01T15:31:02Z", "nextRetryAt": "2026-10-01T15:36:02Z" }
    ]
  },
  "meta": { "range": { "from": "2026-10-01", "to": "2026-10-02", "tz": "America/Chicago" }, "total": 15, "nextCursor": "cur_Hy2e8LPq7Lm3XvT8wR" }
}
```
