# List a webhook endpoint's deliveries

GET

/v1/webhook-endpoints/{endpointId}/deliveries

```sh
curl --request GET \
  --url 'https://example.com/v1/webhook-endpoints/example/deliveries?status=pending&limit=25' \
  --header 'Authorization: Bearer <token>'
```

Newest first. Each delivery carries the event it delivers.

## Authorizations

- **[bearerAuth](https://docs.kindgi.com/v0.5.0/reference/api.md#bearerauth)**

## Parameters

### Path Parameters

**endpointId**

required

string

The webhook endpoint id.

### Query Parameters

**status**

`pending`: waiting for its next attempt. `delivered`: the endpoint answered 2xx. `failed`: every attempt failed, or the endpoint was unregistered first; redeliver queues it again.

string

Allowed values: pending delivered failed

Only deliveries with this status.

**limit**

integer

default: 25 >= 1 <= 100

1..100. Default 25.

**cursor**

string

Where the previous page ended: its `nextCursor`, as it came. A runtime that seals cursors takes one only for the same list, filters and caller, within a day; otherwise `400 bad-input`, and the list starts again without it. Absent → first page.

## Responses

### 200

Page of deliveries.

application/json

object

**data**

required

Array\<object>

object

**deliveryId**

required

string

**endpointId**

required

string

**event**

required

One of: discriminator: type

- **object**

  object

  **id**

  required

  Event id, also sent as the `webhook-id` header; the same on every retry.

  string

  **type**

  required

  string

  Allowed value: run.finished

  **createdAt**

  required

  string format: date-time

  **data**

  required

  object

  **run**

  required

  A finished top-level run: its identity and outcome, never its input or output. Field names match `GET /v1/runs/{runId}`.

  object

  **id**

  required

  RunId.

  string format: uuid

  **projectId**

  required

  string format: uuid

  **flowId**

  required

  string

  **flowVersion**

  required

  string

  **status**

  required

  string

  Allowed values: completed failed cancelled

  **dryRun**

  required

  boolean

  **failureMessage**

  required

  Why the run failed or was cancelled; `null` when it completed.

  string | null

  **failure**

  A failed run’s error, as `GET /v1/runs/{runId}` reads it back: its `code`, and the error’s own `details` when it has them. Absent unless the run failed, and from a runtime that doesn’t send it yet; read `failureMessage` then.

  object

  **code**

  required

  string

  **message**

  required

  string

  **cause**

  What the error came from, when it says: e.g. for `capability-routing-failed`, the router’s `capability-unsatisfiable` with its reasons, by provider.

  **reason**

  The error’s own reason, when it gives one: for a turn that ended at its approval (`hitl-cancelled`), `timeout` when nobody decided in time. Absent from an older runtime and from errors without one; read `code` then.

  string

  **details**

  The error’s own facts, for a code that has them: for `rate-limit-exceeded`, `limit` (the budget that refused: `schema-compile-time` or `template-render-time`) and `budgetMs`, the names the API’s `429` uses. Never the wait: read back later, it’s stale. Absent for any other code, and from an older runtime.

  object

  **_key_**

  additional properties

  any

  **createdAt**

  required

  string format: date-time

  **completedAt**

  required

  string format: date-time

  **usage**

  The model calls of the run tree (this run and every run it started) that the cost ledger had recorded when this run finished: a child run still running then isn’t in it. `calls` counts failed calls too. Absent when the runtime records no usage.

  object

  **calls**

  required

  integer

  **costUsd**

  required

  number

  **tokens**

  required

  object

  **prompt**

  required

  integer

  **completion**

  required

  integer

  **cacheRead**

  required

  integer

  **cacheWrite**

  required

  integer

  **reasoning**

  required

  integer

  **agent**

  On an agent’s run: the agent, the version that ran and the conversation, as `GET /v1/runs/{runId}` shows them (an agent run’s `flowId` is `agent.turn`). Absent on a flow’s run, and from a runtime before Kindgi 0.1.6.

  object

  **id**

  required

  The agent id.

  string

  **version**

  required

  The agent version that ran (semver).

  string

  **conversationId**

  required

  string format: uuid

  **via**

  Why this version ran: named by the caller (`explicit`); held by the flow version a flow’s agent step runs in (`flow-pin`: the node’s `config.version`, else the version the flow version pinned when it was published); the conversation’s own (`conversation`); the version pinned for the run’s scope (`pinned`); or the latest, nothing being pinned (`latest`). Absent on runs from before Kindgi 0.1.4.

  string

  Allowed values: explicit flow-pin conversation pinned latest

  **pinnedScope**

  One of: discriminator: kind

  - **object**

    The whole workspace.

    object

    **kind**

    required

    string

    Allowed values: tenant

  - **object**

    An org’s projects.

    object

    **kind**

    required

    string

    Allowed values: org

    **orgId**

    required

    string format: uuid

  - **object**

    One project.

    object

    **kind**

    required

    string

    Allowed values: project

    **projectId**

    required

    string format: uuid

  - **object**

    A segment path within a project: it covers every run whose path starts with it.

    object

    **kind**

    required

    string

    Allowed values: segment

    **projectId**

    required

    string format: uuid

    **path**

    required

    Array\<object>

    \>= 1 items <= 8 items

    object

    **key**

    required

    Lowercase, like an identifier: `company`, `contact-role`.

    string

    /^\[a-z]\[a-z0-9\_-]{0,63}$/

    **value**

    required

    string

    \>= 1 characters <= 256 characters

- **object**

  An Improve run ended (`completed`, `failed` or `cancelled`): one a person started, or one an `improve` schedule did. Its outcome names the suggested change it wrote, if it wrote one.

  object

  **id**

  required

  Event id, also sent as the `webhook-id` header; the same on every retry.

  string

  **type**

  required

  string

  Allowed value: improve-run.finished

  **createdAt**

  required

  string format: date-time

  **data**

  required

  object

  **improveRun**

  required

  The Improve run, as `GET /v1/improve-runs/{improveRunId}` shows it.

  object

  **id**

  required

  string format: uuid

  **agentId**

  required

  string

  **projectId**

  The project it works in. Absent from older servers, and on a run started for a workspace or an org before Improve runs worked in a project.

  string format: uuid

  **startsFrom**

  required

  The version an Improve run starts from: the one the project runs, pinned there (`pin`) or the agent’s latest (`latest`).

  object

  **version**

  required

  string

  **follows**

  required

  string

  Allowed values: pin latest

  **testSetVersion**

  The version of the project’s test set it searches and proves on; absent until it’s frozen.

  string

  **setAside**

  The test set’s cases set aside for the proof: `cases` of `of`. None with fewer than five. Absent from older servers.

  object

  **cases**

  required

  integer

  **of**

  required

  integer

  **tiers**

  required

  The tiers it tries, the prompt tier first.

  Array\<string>

  Allowed values: settings prompt

  **objective**

  required

  string

  Allowed values: passRate weightedPrecisionAtK

  **groupWeights**

  required

  Which corrections its comparisons count.

  string

  Allowed values: as-recorded experts-only

  **model**

  For the prompt tier: the provider and model that drafts the templates.

  object

  **providerId**

  required

  string

  **model**

  required

  string

  **candidates**

  For the prompt tier: how many templates it drafts.

  integer

  \>= 1 <= 5

  **budget**

  required

  object

  **maxCostUsd**

  required

  The most the Improve run’s comparisons may cost, in US dollars.

  number

  \> 0 <= 100

  **maxCandidates**

  required

  The most candidates it compares.

  integer

  \>= 1 <= 200

  **requestedBy**

  required

  `user:<id>` or `service:<id>`.

  string

  **status**

  required

  string

  Allowed values: running completed failed cancelled

  **tried**

  required

  Candidates tried so far.

  integer

  **costUsd**

  required

  What its comparisons have cost so far (US dollars).

  string

  **outcome**

  One of: discriminator: kind

  - **object**

    A change passed more cases than the version the run started from, and failed none that passed: the run wrote it as a suggested change for a reviewer to decide.

    object

    **kind**

    required

    string

    Allowed value: suggested

    **suggestedChangeId**

    required

    string format: uuid

  - **object**

    No change the run tried did better: `reason` says why, and `holdOut` has the best change’s numbers when one got that far.

    object

    **kind**

    required

    string

    Allowed value: nothing-better

    **reason**

    required

    string

    **holdOut**

    The best change’s proof numbers, when one got that far: on every case, or on the set-aside part for a run stored before that.

    object

    **baseline**

    required

    number | null

    **candidate**

    required

    number | null

    **delta**

    required

    number | null

    **spread**

    number

  - **object**

    The run reached its budget with nothing kept.

    object

    **kind**

    required

    string

    Allowed value: cost-cap

    **spentUsd**

    required

    What it spent, in US dollars.

    string

  - **object**

    The run failed: `message` says why.

    object

    **kind**

    required

    string

    Allowed value: failed

    **message**

    required

    string

  **takes**

  The ids of the corrections it took when it started. Absent from older servers.

  Array\<string>

  **cancelReason**

  Why a `cancelled` Improve run stopped when nobody cancelled it: a comparison’s test run was cancelled for it (that run’s `cancelReason`, e.g. `project-suspended`). It wrote no suggested change. Absent when it was cancelled.

  string

  **comparisons**

  Its comparisons so far, each a test run to open: `reference` (the version as it is, on each part: what the proof is held to, case by case), each `candidate` (the block and the values it changed, on the search part: what picks the change to suggest), and the `proof` (the suggested change, on `all` the cases at the reference’s repetitions: what keeps it or not; an Improve run from before 0.4 ran its proof on the hold-out part). Absent from older servers.

  Array\<object>

  object

  **testRunId**

  string format: uuid

  **role**

  required

  string

  Allowed values: reference candidate proof

  **part**

  required

  string

  Allowed values: search hold-out all

  **blockId**

  string

  **changed**

  object

  **_key_**

  additional properties

  any

  **score**

  number | null

  **failed**

  string

  **refused**

  For a drafted template that was never compared: why the check refused it (what it reads or names that the agent doesn’t have, or its size).

  Array\<object>

  object

  **path**

  required

  string

  **message**

  required

  string

  **why**

  For a drafted template: what the drafter meant it to change.

  string

  **trigger**

  The improve schedule and fire that started it (`GET /v1/schedules/{triggerId}/fires`); absent for an Improve run a person started.

  object

  **triggerId**

  required

  string

  **fireId**

  required

  string

  **createdAt**

  required

  string format: date-time

  **updatedAt**

  required

  string format: date-time

  **finishedAt**

  string format: date-time

- **object**

  An approval was asked for: a reviewer’s decision is waiting. Sent once per approval (an escalation is a new approval). `projectId` in the endpoint’s filter narrows it to the approval’s project.

  object

  **id**

  required

  Event id, also sent as the `webhook-id` header; the same on every retry.

  string

  **type**

  required

  string

  Allowed value: approval.requested

  **createdAt**

  required

  string format: date-time

  **data**

  required

  object

  **approval**

  required

  The approval an `approval.requested` event names. What it is about stays behind sign-in: no `context`, no tool call or run input.

  object

  **approvalId**

  required

  string

  **projectId**

  string

  **requiredRole**

  required

  The least reviewer role that may decide it.

  string

  Allowed values: standard senior admin

  **title**

  string

  **assignedTo**

  The one reviewer it is assigned to, when it is.

  string

  **createdAt**

  required

  string format: date-time

  **expiresAt**

  string format: date-time

  **url**

  Its page in the console, when the runtime knows its public address.

  string

- **object**

  object

  **id**

  required

  string

  **type**

  required

  string

  Allowed value: webhook.test

  **createdAt**

  required

  string format: date-time

  **data**

  required

  object

  **endpointId**

  required

  string

**status**

required

`pending`: waiting for its next attempt. `delivered`: the endpoint answered 2xx. `failed`: every attempt failed, or the endpoint was unregistered first; redeliver queues it again.

string

Allowed values: pending delivered failed

**attempts**

required

integer

**nextAttemptAt**

required

string | null format: date-time

**lastAttemptAt**

required

string | null format: date-time

**lastResponseStatus**

required

HTTP status of the last attempt; `null` when it got no response.

integer | null

**lastError**

required

Why the last attempt failed (`timeout`, `connection-refused`, `url-refused`, …).

string | null

**createdAt**

required

string format: date-time

**deliveredAt**

required

string | null format: date-time

**nextCursor**

string

**hasMore**

required

boolean

##### Example

```json
{
  "data": [
    {
      "event": {
        "type": "run.finished",
        "data": {
          "run": {
            "status": "completed",
            "agent": {
              "via": "explicit",
              "pinnedScope": {
                "kind": "tenant"
              }
            }
          }
        }
      },
      "status": "pending"
    }
  ]
}
```

### 400

Unknown `status`.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 401

Missing / malformed / expired / revoked bearer token.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 403

Not a tenant admin (`permission-denied`). Without an authorization store, a tenant admin is the deployment’s API token, an admin key, or a console signed in with either.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 404

No endpoint with that id.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 503

The database was too busy to answer in time (`database-busy`); `Retry-After` (whole seconds) says when to try again.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

## See also

- [`GET /v1/webhook-endpoints/{endpointId}`: Fetch a webhook endpoint](https://docs.kindgi.com/v0.5.0/reference/api/operations/webhookendpointsget.md)
- [`PATCH /v1/webhook-endpoints/{endpointId}`: Update a webhook endpoint](https://docs.kindgi.com/v0.5.0/reference/api/operations/webhookendpointsupdate.md)
- [`POST /v1/webhook-endpoints/{endpointId}/unregister`: Unregister a webhook endpoint (soft delete)](https://docs.kindgi.com/v0.5.0/reference/api/operations/webhookendpointsunregister.md)
- [`POST /v1/webhook-endpoints/{endpointId}/deliveries/{deliveryId}/redeliver`: Redeliver an event](https://docs.kindgi.com/v0.5.0/reference/api/operations/webhookendpointsredeliver.md)
- [Error code `database-busy`](https://docs.kindgi.com/v0.5.0/reference/errors.md#database-busy)
- [Error code `permission-denied`](https://docs.kindgi.com/v0.5.0/reference/errors.md#permission-denied)
- [Every error code](https://docs.kindgi.com/v0.5.0/reference/errors.md)
