client.webhooks
client.webhooks — the webhooks operations.
On AsyncKindgi every method is the same, awaited.
client.webhooks.list()
Section titled “client.webhooks.list()”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,) -> WebhookTriggerCollectionPageList 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()
Section titled “client.webhooks.register()”register( body: RegisterWebhookTriggerBody | Mapping[str, Any] | None = None, /, *, idempotency_key: str | None = None, timeout: float | None = None, **fields: Any,) -> WebhookTriggerRecordRegister 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. toolsAllowedUnattended names the tools whose calls in its runs needn't wait for a person's yes, though a tool asks for one in a run no person started: naming it takes admin on the project, each id must be a tool the flow calls, and it's audited (trigger-tools-allowed-unattended-set).
client.webhooks.get()
Section titled “client.webhooks.get()”get(trigger_id: str | UUID, /, *, timeout: float | None = None) -> WebhookTriggerRecordFetch a webhook trigger. GET /v1/webhooks/{triggerId}
client.webhooks.update()
Section titled “client.webhooks.update()”update( trigger_id: str | UUID, body: PatchWebhookTriggerBody | Mapping[str, Any] | None = None, /, *, idempotency_key: str | None = None, timeout: float | None = None, **fields: Any,) -> WebhookTriggerRecordUpdate a webhook trigger. PATCH /v1/webhooks/{triggerId}
Changes the flow version (which needs execute on the flow, and must be a version the trigger's project runs), 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. toolsAllowedUnattended replaces the list ([] clears it; absent keeps it, a new flow version too): naming it takes admin on the trigger's project, it's checked against the flow at the version the trigger will run, and every change is audited. A webhook trigger is personal or shared, and no change moves its owner: only POST /v1/webhooks/{triggerId}/owner does. A trigger a person owns is personal: only they (holding write on its project) or a project admin may change it. A trigger a service account owns is shared: changing its flow version, its input, its toolsAllowedUnattended or hmacSecretName takes admin on its project, and the project's writers may change its label and delivery settings. Without an authorization store, a project admin here is a tenant-admin key. A change by anyone but a personal trigger's owner is audited as trigger-changed-for-owner, naming the fields changed (and the signing secret's name before and after) and the trigger's version after it, never their values.
client.webhooks.pause()
Section titled “client.webhooks.pause()”pause( trigger_id: str | UUID, /, *, idempotency_key: str | None = None, timeout: float | None = None,) -> WebhookTriggerRecordPause 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. A personal trigger's owner or a project admin pauses it; a shared one, any writer of its project.
client.webhooks.resume()
Section titled “client.webhooks.resume()”resume( trigger_id: str | UUID, /, *, idempotency_key: str | None = None, timeout: float | None = None,) -> WebhookTriggerRecordResume a webhook trigger. POST /v1/webhooks/{triggerId}/resume
A personal trigger's owner or a project admin resumes it; a shared one, any writer of its project.
client.webhooks.unregister()
Section titled “client.webhooks.unregister()”unregister( trigger_id: str | UUID, /, *, idempotency_key: str | None = None, timeout: float | None = None,) -> WebhookTriggerUnregisterResultSoft-delete a webhook trigger (tombstone). POST /v1/webhooks/{triggerId}/unregister
A personal trigger's owner or a project admin deletes it; a shared one, any writer of its project.
client.webhooks.fires()
Section titled “client.webhooks.fires()”fires( trigger_id: str | UUID, /, *, limit: int | None = None, cursor: str | None = None, timeout: float | None = None,) -> WebhookFirePageA 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.list_versions()
Section titled “client.webhooks.list_versions()”list_versions( trigger_id: str | UUID, /, *, limit: int | None = None, cursor: str | None = None, timeout: float | None = None,) -> WebhookTriggerVersionPageA webhook trigger's versions. GET /v1/webhooks/{triggerId}/versions
Newest first: each version of the webhook trigger, what it was from createdAt on, who made it (createdBy) and why (cause). Registering makes version 1, and each change makes the next (a PATCH that alters it, or a take-over to another owner): a PATCH that changes nothing makes none, nor do pausing, resuming or deleting. A version never changes once made. A delivery's run uses the newest when it starts, and keeps it whatever later edits make (the run's trigger.version). A webhook trigger from before versions has none until its next change or its first fire. The versions keep every input the webhook trigger has had, so a secret pasted into its input stays in an earlier version after you edit it out: rotate it. Whoever can read the webhook trigger can read its versions.
client.webhooks.get_version()
Section titled “client.webhooks.get_version()”get_version( trigger_id: str | UUID, version: int, /, *, timeout: float | None = None,) -> WebhookTriggerVersionFetch one version of a webhook trigger. GET /v1/webhooks/{triggerId}/versions/{version}
client.webhooks.take_ownership()
Section titled “client.webhooks.take_ownership()”take_ownership( trigger_id: str | UUID, body: TakeTriggerOwnerBody | Mapping[str, Any] | None = None, /, *, idempotency_key: str | None = None, timeout: float | None = None, **fields: Any,) -> WebhookTriggerRecordTake 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 (without an authorization store, a tenant-admin key) and execute on its flow. For a trigger whose owner left or lost access, or to make one shared or personal. It's the one way a trigger's owner changes, audited as trigger-owner-set, naming the trigger's version after it; a person it's taken from is told, where the server tells owners. Name runAsServiceAccountId instead to make a service account the owner: that needs act_as on the account (a tenant admin's), and the account must itself hold execute on the flow. With an authorization store, that's checked when the account is named: an account that can't is refused (409 trigger-owner-cannot-run-target). Or name runAsProject: true to make the project's own service account the owner, made the first time with the editor role on the project, so the trigger is shared and runs as the project. It runs only what the project's editors can, and is checked the same way. The trigger keeps its toolsAllowedUnattended, now for the new owner's runs; a body naming it is refused (change it with PATCH).