# Take over a webhook trigger

POST

/v1/webhooks/{triggerId}/owner

```sh
curl --request POST \
  --url https://example.com/v1/webhooks/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/owner \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{ "runAsServiceAccountId": "example" }'
```

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. 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.

## Authorizations

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

## Parameters

### Path Parameters

**triggerId**

required

string format: uuid

TriggerId — the trigger id (a UUID).

### Header Parameters

**Idempotency-Key**

string

\>= 1 characters

Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the tenant is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per `docs/API-ROUTE-CONVENTIONS.md` §3.1). A retry sent while the first request still runs is answered `409 idempotency-key-in-flight` with `Retry-After`, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets `409 idempotency-key-replay-withheld`, with the first request’s status and when it succeeded (from 0.1.5).

## Request Body

application/json

Who the trigger’s runs act as from now. Absent, or an empty body: the caller takes it over (today’s behaviour). With `runAsServiceAccountId`: that service account becomes the owner.

object

**runAsServiceAccountId**

A service account the trigger’s runs act as (its owner), named by id, instead of the caller. Needs `act_as` on that account — a tenant admin holds it — and the account must itself hold what the trigger runs.

string

\>= 1 characters

##### Examplegenerated

```json
{
  "runAsServiceAccountId": "example"
}
```

## Responses

### 200

The trigger, with its new owner.

application/json

A webhook trigger: a signed request to its `receiveUrl` starts a run of its flow, as its owner. The signing secret is never on it, only its name.

object

**triggerId**

required

string

**webhookId**

required

The routable id in the receive URL. Route-minted (a random UUID); unique per tenant. Not a secret: the signature is what a request is checked by.

string

**receiveUrl**

Where the sender posts: `{public URL}/v1/hooks/{tenantId}/{webhookId}`. Absent when the deployment has no public URL configured (`KINDGI_PUBLIC_URL`); it’s never taken from a request’s `Host`.

string format: uri

**flowId**

required

string

\>= 1 characters

**flowVersion**

required

string

\>= 1 characters

**projectId**

required

The trigger’s project: its runs are this project’s.

string format: uuid

**owner**

required

Who its runs act as: whoever registered it, until an admin takes it over (`POST …/owner`). Checked again at every delivery.

object

**kind**

required

string

Allowed values: user service

**id**

required

string

**displayName**

The owner’s name at the time of the response: the person’s display name, or the service account’s name. Absent when it can’t be read (no directory, a removed account) and from a runtime before Kindgi 0.1.6: show the id then.

string

**input**

The flow’s input on every delivery, in place of the event. Absent: the event (the body, parsed as JSON for a JSON content type, else its text).

**hmacSecretName**

required

The signing secret, by name (written with `POST /v1/secrets`, or made by `generateSecret`). Read in the env the deployment serves, at `hmacSecretScope`.

string

\>= 1 characters

**hmacSecretScope**

One of:

- **object**

  One of:

  - **object**

    object

    **kind**

    required

    string

    Allowed value: tenant

  - **object**

    object

    **kind**

    required

    string

    Allowed value: org

    **orgId**

    required

    string format: uuid

  - **object**

    object

    **kind**

    required

    string

    Allowed value: project

    **projectId**

    required

    string format: uuid

- **null**

  null

**signingSecret**

Only in the answer to a register with `generateSecret`: the new signing secret, shown this once, to paste into the sender. It’s stored as `hmacSecretName` in the trigger’s own scope; no later read shows it.

string

**signature**

required

One of:

- **object**

  object

  **kind**

  required

  string

  Allowed values: hmac-sha256

  **encoding**

  required

  string

  Allowed values: hex base64

  **header**

  required

  The header that carries the signature (matched case-insensitively).

  string

  \>= 1 characters <= 100 characters

  **prefix**

  Stripped from the header’s value before decoding (e.g. `sha256=`).

  string

  \>= 1 characters <= 32 characters

- **object**

  object

  **kind**

  required

  string

  Allowed values: standard-webhooks

  **toleranceSeconds**

  integer

  \>= 1 <= 3600

**deliveryIdHeader**

The header whose value, with the body, is a delivery’s dedupe key (WooCommerce: `X-WC-Webhook-Delivery-ID`, which is per second, not per event, so the body counts too). Absent: deliveries aren’t deduped (`standard-webhooks` dedupes on its own `webhook-id`).

string

**bodyLimitBytes**

required

The largest body it takes (default 262144).

integer

\>= 1024 <= 1048576

**rateLimitPerMinute**

required

Accepted deliveries a minute (default 600); past it, `429`.

integer

\>= 1 <= 6000

**label**

required

string | null

**status**

required

Lifecycle status. Only `active` triggers fire. Tombstoned rows are excluded from every read path.

string

Allowed values: active paused

**statusReason**

Why the runtime paused it (repeated refused or failed starts; a sender’s failed proofs never count), when it did.

string

**suppressedRefusals**

Refusals and skipped deliveries this minute past the 20 recorded in its history, which only counted.

object

**since**

required

string format: date-time

**count**

required

integer

\>= 1

**lastFiredAt**

required

string | null format: date-time

**createdAt**

required

string format: date-time

**updatedAt**

required

string format: date-time

##### Example

```json
{
  "owner": {
    "kind": "user"
  },
  "hmacSecretScope": {
    "kind": "tenant"
  },
  "signature": {
    "kind": "hmac-sha256",
    "encoding": "hex"
  },
  "status": "active"
}
```

### 400

Malformed request body.

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"
  }
}
```

### 404

No webhook trigger with that id, or no such service account.

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"
  }
}
```

### 409

Idempotency-Key was reused with a different body, or resource-state conflict.

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"
  }
}
```

### 413

The request body is over the API’s limit (`request-too-large`; `details.maxBytes` says how much).

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"
  }
}
```

### 500

Server error (unmapped domain code or framework crash).

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"
  }
}
```

### 501

`trigger-operation-unsupported`: this deployment can’t change a trigger’s owner.

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/webhooks/{triggerId}`: Fetch a webhook trigger](https://docs.kindgi.com/reference/api/operations/webhooksget.md)
- [`PATCH /v1/webhooks/{triggerId}`: Update a webhook trigger](https://docs.kindgi.com/reference/api/operations/webhooksupdate.md)
- [`POST /v1/webhooks/{triggerId}/pause`: Pause a webhook trigger](https://docs.kindgi.com/reference/api/operations/webhookspause.md)
- [`POST /v1/webhooks/{triggerId}/resume`: Resume a webhook trigger](https://docs.kindgi.com/reference/api/operations/webhooksresume.md)
- [Error code `request-too-large`](https://docs.kindgi.com/reference/errors.md#request-too-large)
- [Error code `trigger-operation-unsupported`](https://docs.kindgi.com/reference/errors.md#trigger-operation-unsupported)
- [Every error code](https://docs.kindgi.com/reference/errors.md)
