# client.webhooks

> client.webhooks — the webhooks operations.

`client.webhooks` — the `webhooks` operations.

On `AsyncKindgi` every method is the same, awaited.

## `client.webhooks.list()`

```python signature
list(
    *,
    limit: int | None = None,
    cursor: str | None = None,
    status: Literal['active', 'paused'] | None = None,
    project_id: str | UUID | None = None,
    timeout: float | None = None,
) -> WebhookTriggerCollectionPage
```

List webhook triggers. `GET /v1/webhooks`

The tenant's webhook triggers whose project the caller may read; with `projectId`, that project's only (which needs `read` on it).

## `client.webhooks.register()`

```python signature
register(
    body: RegisterWebhookTriggerBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> WebhookTriggerRecord
```

Register a webhook trigger. `POST /v1/webhooks`

A signed request to the trigger's `receiveUrl` (`POST /v1/hooks/{tenantId}/{webhookId}`) starts a run of its flow, as its owner: the caller, until an admin takes it over. The route mints `webhookId` (a random UUID). The signing secret is written first (`POST /v1/secrets`), and `hmacSecretName` names it; a model provider's key is refused (`400 provider-key-refused`). Where it's read is recorded on the trigger (`hmacSecretScope`): the first of its project, the project's org and the tenant that has it and that the caller administers, else the broadest they administer; the receiver reads it there only. Or `generateSecret: true`: the server makes it, stores it as `hmacSecretName` in the trigger's own project (a name the project already has is refused, `409 secret-write-conflict`), and returns it once as `signingSecret`. `signature` says how the sender signs (default: a hex HMAC-SHA256 of the raw body in `X-Kindgi-Signature`); `deliveryIdHeader` names the header whose value, with the body, dedupes deliveries. A trigger that names no `projectId` goes in the tenant's Default project. Needs `write` on the project and `execute` on the flow.

## `client.webhooks.get()`

```python signature
get(trigger_id: str | UUID, /, *, timeout: float | None = None) -> WebhookTriggerRecord
```

Fetch a webhook trigger. `GET /v1/webhooks/{triggerId}`

## `client.webhooks.update()`

```python signature
update(
    trigger_id: str | UUID,
    body: PatchWebhookTriggerBody | Mapping[str, Any] | None = None,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
    **fields: Any,
) -> WebhookTriggerRecord
```

Update a webhook trigger. `PATCH /v1/webhooks/{triggerId}`

Changes the flow version (which needs `execute` on the flow), the input, the label, which secret signs (`hmacSecretName`, never a model provider's key), the signature scheme, the delivery-id header, the body cap or the rate (`null` clears the last three). The flow itself stays: register another trigger for another flow. Rotating the secret's value goes through `POST /v1/secrets/{name}/rotate`.

## `client.webhooks.pause()`

```python signature
pause(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> WebhookTriggerRecord
```

Pause a webhook trigger. `POST /v1/webhooks/{triggerId}/pause`

While paused, a signed delivery is answered `202` and recorded as a `skipped` fire, and no run starts: **its event is dropped**. Senders such as WooCommerce never resend, so resuming doesn't bring those events back.

## `client.webhooks.resume()`

```python signature
resume(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> WebhookTriggerRecord
```

Resume a webhook trigger. `POST /v1/webhooks/{triggerId}/resume`

## `client.webhooks.unregister()`

```python signature
unregister(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> WebhookTriggerUnregisterResult
```

Soft-delete a webhook trigger (tombstone). `POST /v1/webhooks/{triggerId}/unregister`

## `client.webhooks.fires()`

```python signature
fires(
    trigger_id: str | UUID,
    /,
    *,
    limit: int | None = None,
    cursor: str | None = None,
    timeout: float | None = None,
) -> WebhookFirePage
```

A webhook trigger's deliveries. `GET /v1/webhooks/{triggerId}/fires`

Newest first: each delivery the trigger received and what came of it: the run it started (`started`, or `pending` while it starts), or why it was `skipped` (paused, its project or tenant suspended, or its tenant closing) or `refused` (`detail`: `signature-missing`, `signature-invalid`, `stale`, `secret-unavailable`, `unregistered`, `rate-limited`, `body-too-large`, `body-not-json`, `body-too-deep`, or the owner's lost access). A delivery that repeated an earlier one's dedupe key counts on that one (`duplicates`). A fire keeps the event only until its run starts. Refusals and skipped deliveries past 20 a minute only count (the trigger's `suppressedRefusals`).

## `client.webhooks.take_ownership()`

```python signature
take_ownership(
    trigger_id: str | UUID,
    /,
    *,
    idempotency_key: str | None = None,
    timeout: float | None = None,
) -> WebhookTriggerRecord
```

Take over a webhook trigger. `POST /v1/webhooks/{triggerId}/owner`

The caller becomes the trigger's owner, so its runs act as the caller from the next delivery. Needs `admin` on the trigger's project and `execute` on its flow. For a trigger whose owner left or lost access.
