# Rotate a pipeline's webhook secret

`POST /v1/pipelines/{account}/{pipeline}/rotate-webhook-secret`

> This reference is the **skmtc/skmtc-api** API on Hub. Star it to see each revision, and add a pipeline to get its changes. https://skmtc.dev/skmtc/apis/skmtc-api

Replace the signing secret of a pipeline's webhook action. The response carries the new secret, shown only this once. The old secret stops at once: every later attempt signs with the new one, including retries of events captured before the rotation. 422 for a pipeline with no webhook action. Signed-in sessions only: a leaked personal access token must not be able to replace the secret and break a working receiver.

## Request

- Method: `POST`
- Path: `/v1/pipelines/{account}/{pipeline}/rotate-webhook-secret`
- `account` (path, string, required)
- `pipeline` (path, string, required)

## Response

### 200

The request has succeeded.

Content type: `application/json`. Type: `object`.

A pipeline with its webhook action's signing secret. Returned by create, update and rotate only.

- `id` (string, required): An RFC 4122 UUID, rendered as a string.
- `owner` (object, required): A user or organization account - the polymorphic resource owner.
  - `id` (string, required): Stable row id, immutable across handle renames - what cross-environment tooling (the staging-sync link ledger) keys on.
  - `handle` (string, required): Unique URL handle, e.g. `acme`.
  - `displayName` (string, required)
  - `type` (enum, required): Whether an account represents a single person or an organization.
    - One of: `user`, `org`
  - `avatarUrl` (string, required): An absolute URL.
  - `bio` (string, required)
  - `location` (string)
  - `emailDomain` (string): The company's email domain, e.g. `stripe.com` - org accounts only. A user with a verified email at this domain can claim the org.
  - `claimStatus` (enum): Claim state of the org - org accounts only.
    - One of: `claimed`, `unclaimed`
  - `joinedAt` (string, required): When the account was created.
  - `url` (string, required): API self-link for this account.
  - `htmlUrl` (string, required): Web UI link for this account.
- `name` (string, required): Unique within the owner account.
- `status` (enum, required): Whether a pipeline fires. `paused` is entered by hand, or after 5 failed deliveries in a row.
  - One of: `active`, `paused`
- `subscription` (object, required): The trigger of a pipeline: which API starts it. A pipeline fires when a revision becomes the latest revision of the API.
  - `api` (object, required): The API whose latest revision starts the pipeline.
    - `account` (string, required)
    - `slug` (string, required)
    - `url` (string, required): An absolute URL.
    - `htmlUrl` (string, required): An absolute URL.
- `actions` (array of PipelineAction, required): At most one action of each type, in the order they run.
  - Variant 1 (object): Makes code from the project of the subscription's API and this stack. The hub makes the private project (`{api}-{stack}`) from the two.
    - `type` (enum, required)
      - One of: `generate`
    - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
    - `stack` (object, required): The stack, at the version a delivery runs.
      - `account` (string, required)
      - `slug` (string, required)
      - `version` (string, required): Resolved or requested version.
      - `url` (string, required): An absolute URL.
      - `htmlUrl` (string, required): An absolute URL.
    - `stackPin` (object, required): How the action pins its stack version - `latest` (follow newest) or an exact published version. Resolved to an exact version at run creation.
      - `mode` (enum, required): Whether a version pin follows the newest version or holds an exact one.
        - One of: `latest`, `exact`
      - `version` (string): Exact published stack version, e.g. `3.0.1`. Present iff `mode` is `exact`.
    - `project` (object, required): The project the hub made from the API and the stack.
      - `account` (string, required)
      - `slug` (string, required)
      - `url` (string, required): An absolute URL.
      - `htmlUrl` (string, required): An absolute URL.
  - Variant 2 (object): Pushes the generated code to `repo` and keeps one pull request open against `baseBranch`.
    - `type` (enum, required)
      - One of: `pullRequest`
    - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
    - `repo` (string, required): Target repository, `owner/name` form.
    - `baseBranch` (string): Base branch; omitted = the repository's default branch at delivery time.
    - `credentialId` (string, required): The stored git credential used to push and open the PR (`gcr_…`).
  - Variant 3 (object): Publishes the generated code, compiled, as a package on the GitHub npm registry. Each delivery publishes the next patch version.
    - `type` (enum, required)
      - One of: `publish`
    - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
    - `packageName` (string, required): The package name, e.g. `@acme/stripe-sdk`: scoped and lower-case, as GitHub's npm registry takes only scoped names.
    - `firstVersion` (string, required): The version of the first publish, e.g. `0.1.0`: `x.y.z`, numbers without leading zeros, no pre-release or build part.
    - `credentialId` (string, required): The stored packages token used to publish, e.g. `gcr_…`.
  - Variant 4 (object): Sends a signed delivery-result event to an HTTPS destination, after the other actions, also when one of them failed.
    - `type` (enum, required)
      - One of: `webhook`
    - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
    - `url` (string, required): The destination. It must be a public HTTPS URL with no credentials in it; loopback, private and reserved addresses are rejected.
- `consecutiveFailures` (integer, required): Failed deliveries in a row; the auto-pause counter.
- `lastDelivery` (object | null, required): The newest delivery; `null` when the pipeline has none.
  - `id` (string, required): An RFC 4122 UUID, rendered as a string.
  - `status` (enum, required): In-flight and terminal states of a delivery. `superseded` means a newer latest revision came before the delivery finished. `skipped` means the delivery did not act, e.g. for a pipeline paused before it ran; the delivery's `reasonCode` says why.
    - One of: `pending`, `running`, `succeeded`, `failed`, `superseded`, `skipped`
  - `apiRevisionId` (string, required): Id of the revision this delivery fired for.
  - `actions` (array of PipelineAction, required): The actions and their settings when the delivery started.
    - Variant 1 (object): Makes code from the project of the subscription's API and this stack. The hub makes the private project (`{api}-{stack}`) from the two.
      - `type` (enum, required)
        - One of: `generate`
      - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
      - `stack` (object, required): The stack, at the version a delivery runs.
        - `account` (string, required)
        - `slug` (string, required)
        - `version` (string, required): Resolved or requested version.
        - `url` (string, required): An absolute URL.
        - `htmlUrl` (string, required): An absolute URL.
      - `stackPin` (object, required): How the action pins its stack version - `latest` (follow newest) or an exact published version. Resolved to an exact version at run creation.
        - `mode` (enum, required): Whether a version pin follows the newest version or holds an exact one.
          - One of: `latest`, `exact`
        - `version` (string): Exact published stack version, e.g. `3.0.1`. Present iff `mode` is `exact`.
      - `project` (object, required): The project the hub made from the API and the stack.
        - `account` (string, required)
        - `slug` (string, required)
        - `url` (string, required): An absolute URL.
        - `htmlUrl` (string, required): An absolute URL.
    - Variant 2 (object): Pushes the generated code to `repo` and keeps one pull request open against `baseBranch`.
      - `type` (enum, required)
        - One of: `pullRequest`
      - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
      - `repo` (string, required): Target repository, `owner/name` form.
      - `baseBranch` (string): Base branch; omitted = the repository's default branch at delivery time.
      - `credentialId` (string, required): The stored git credential used to push and open the PR (`gcr_…`).
    - Variant 3 (object): Publishes the generated code, compiled, as a package on the GitHub npm registry. Each delivery publishes the next patch version.
      - `type` (enum, required)
        - One of: `publish`
      - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
      - `packageName` (string, required): The package name, e.g. `@acme/stripe-sdk`: scoped and lower-case, as GitHub's npm registry takes only scoped names.
      - `firstVersion` (string, required): The version of the first publish, e.g. `0.1.0`: `x.y.z`, numbers without leading zeros, no pre-release or build part.
      - `credentialId` (string, required): The stored packages token used to publish, e.g. `gcr_…`.
    - Variant 4 (object): Sends a signed delivery-result event to an HTTPS destination, after the other actions, also when one of them failed.
      - `type` (enum, required)
        - One of: `webhook`
      - `skipped` (boolean, required): A skipped action keeps its settings and does not run; the delivery records it as `skipped`.
      - `url` (string, required): The destination. It must be a public HTTPS URL with no credentials in it; loopback, private and reserved addresses are rejected.
  - `results` (array of PipelineActionResult, required): One result for each action that has finished, in the order of `actions`. Empty while the delivery is pending, and for a `skipped` delivery.
    - `type` (enum, required): The type of an action.
      - One of: `generate`, `pullRequest`, `publish`, `webhook`
    - `outcome` (enum, required): What one action of a delivery came to. `skipped` - the action is set to skip. `notRun` - an earlier action failed, so the delivery stopped before it.
      - One of: `succeeded`, `failed`, `skipped`, `notRun`
    - `reasonCode` (string): A stable machine-readable code, when the action failed or did not run.
    - `detail` (string): What the action did or why it failed, e.g. the pull request URL or the published `name@version`.
    - `durationMs` (integer): How long the action took; absent for an action that did not run.
  - `reasonCode` (string): A stable machine-readable code for a `skipped` or `failed` delivery, e.g. `pipeline_paused`.
  - `startedAt` (string | null, required): When the delivery started; `null` while pending.
  - `finishedAt` (string | null, required): When the delivery reached a terminal state; `null` while non-terminal.
  - `createdAt` (string, required)
  - `url` (string, required): An absolute URL.
- `viewer` (object, required): The requesting viewer's effective permissions on this pipeline.
  - `canRead` (boolean, required): May view the resource.
  - `canWrite` (boolean, required): May edit metadata and settings (the `writer` relation).
  - `canAdmin` (boolean, required): May manage collaborators and delete the resource (the `admin` relation).
- `createdAt` (string, required)
- `updatedAt` (string, required)
- `url` (string, required): An absolute URL.
- `htmlUrl` (string, required): An absolute URL.
- `webhookSecret` (string): The webhook action's signing secret in plaintext, shown only this once. Present when the request added the webhook action, and on rotate. It cannot be read again; rotate it to get a new one.

Example response:

```json
{
  "id": "00000000-0000-0000-0000-000000000000",
  "owner": {
    "id": "string",
    "handle": "string",
    "displayName": "string",
    "type": "user",
    "avatarUrl": "string",
    "bio": "string",
    "location": "string",
    "emailDomain": "string",
    "claimStatus": "claimed",
    "joinedAt": "2026-10-30T12:00:00Z",
    "url": "string",
    "htmlUrl": "string"
  },
  "name": "string",
  "status": "active",
  "subscription": {
    "api": {
      "account": "string",
      "slug": "string",
      "url": "string",
      "htmlUrl": "string"
    }
  },
  "actions": [
    {
      "type": "generate",
      "skipped": true,
      "stack": {
        "account": "string",
        "slug": "string",
        "version": "string",
        "url": "string",
        "htmlUrl": "string"
      },
      "stackPin": {
        "mode": "latest",
        "version": "string"
      },
      "project": {
        "account": "string",
        "slug": "string",
        "url": "string",
        "htmlUrl": "string"
      }
    }
  ],
  "consecutiveFailures": 0,
  "lastDelivery": {
    "id": "00000000-0000-0000-0000-000000000000",
    "status": "pending",
    "apiRevisionId": "string",
    "actions": [
      {
        "type": "generate",
        "skipped": true,
        "stack": {
          "account": "string",
          "slug": "string",
          "version": "string",
          "url": "string",
          "htmlUrl": "string"
        },
        "stackPin": {
          "mode": "latest",
          "version": "string"
        },
        "project": {
          "account": "string",
          "slug": "string",
          "url": "string",
          "htmlUrl": "string"
        }
      }
    ],
    "results": [
      {
        "type": "generate",
        "outcome": "succeeded",
        "reasonCode": "string",
        "detail": "string",
        "durationMs": 0
      }
    ],
    "reasonCode": "string",
    "startedAt": "2026-10-30T12:00:00Z",
    "finishedAt": "2026-10-30T12:00:00Z",
    "createdAt": "2026-10-30T12:00:00Z",
    "url": "string"
  },
  "viewer": {
    "canRead": true,
    "canWrite": true,
    "canAdmin": true
  },
  "createdAt": "2026-10-30T12:00:00Z",
  "updatedAt": "2026-10-30T12:00:00Z",
  "url": "string",
  "htmlUrl": "string",
  "webhookSecret": "string"
}
```

### 401

Binds a concrete HTTP `Status` to the shared `ApiError` body.

Content type: `application/json`. Type: `object`.

The uniform error envelope returned for every non-2xx response.

- `code` (enum, required): Machine-readable error category. Each value pairs with one HTTP status.
  - One of: `badRequest`, `unauthorized`, `forbidden`, `notFound`, `conflict`, `unprocessable`, `payloadTooLarge`, `unsupportedMediaType`, `documentTooLarge`, `webhookLimitReached`, `rateLimited`, `internal`, `unavailable`, `badGateway`, `notImplemented`
- `message` (string, required): Human-readable summary safe to surface to end users.
- `requestId` (string, required): Correlates the response with server logs for support.
- `details` (array of ErrorDetail)
  - `field` (string): Dotted path to the offending field, when applicable.
  - `message` (string, required): Human-readable explanation of this specific problem.

Example response:

```json
{
  "code": "badRequest",
  "message": "string",
  "requestId": "string",
  "details": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
```

### 403

Binds a concrete HTTP `Status` to the shared `ApiError` body.

Content type: `application/json`. Type: `object`.

The uniform error envelope returned for every non-2xx response.

- `code` (enum, required): Machine-readable error category. Each value pairs with one HTTP status.
  - One of: `badRequest`, `unauthorized`, `forbidden`, `notFound`, `conflict`, `unprocessable`, `payloadTooLarge`, `unsupportedMediaType`, `documentTooLarge`, `webhookLimitReached`, `rateLimited`, `internal`, `unavailable`, `badGateway`, `notImplemented`
- `message` (string, required): Human-readable summary safe to surface to end users.
- `requestId` (string, required): Correlates the response with server logs for support.
- `details` (array of ErrorDetail)
  - `field` (string): Dotted path to the offending field, when applicable.
  - `message` (string, required): Human-readable explanation of this specific problem.

Example response:

```json
{
  "code": "badRequest",
  "message": "string",
  "requestId": "string",
  "details": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
```

### 404

Binds a concrete HTTP `Status` to the shared `ApiError` body.

Content type: `application/json`. Type: `object`.

The uniform error envelope returned for every non-2xx response.

- `code` (enum, required): Machine-readable error category. Each value pairs with one HTTP status.
  - One of: `badRequest`, `unauthorized`, `forbidden`, `notFound`, `conflict`, `unprocessable`, `payloadTooLarge`, `unsupportedMediaType`, `documentTooLarge`, `webhookLimitReached`, `rateLimited`, `internal`, `unavailable`, `badGateway`, `notImplemented`
- `message` (string, required): Human-readable summary safe to surface to end users.
- `requestId` (string, required): Correlates the response with server logs for support.
- `details` (array of ErrorDetail)
  - `field` (string): Dotted path to the offending field, when applicable.
  - `message` (string, required): Human-readable explanation of this specific problem.

Example response:

```json
{
  "code": "badRequest",
  "message": "string",
  "requestId": "string",
  "details": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
```

### 422

Binds a concrete HTTP `Status` to the shared `ApiError` body.

Content type: `application/json`. Type: `object`.

The uniform error envelope returned for every non-2xx response.

- `code` (enum, required): Machine-readable error category. Each value pairs with one HTTP status.
  - One of: `badRequest`, `unauthorized`, `forbidden`, `notFound`, `conflict`, `unprocessable`, `payloadTooLarge`, `unsupportedMediaType`, `documentTooLarge`, `webhookLimitReached`, `rateLimited`, `internal`, `unavailable`, `badGateway`, `notImplemented`
- `message` (string, required): Human-readable summary safe to surface to end users.
- `requestId` (string, required): Correlates the response with server logs for support.
- `details` (array of ErrorDetail)
  - `field` (string): Dotted path to the offending field, when applicable.
  - `message` (string, required): Human-readable explanation of this specific problem.

Example response:

```json
{
  "code": "badRequest",
  "message": "string",
  "requestId": "string",
  "details": [
    {
      "field": "string",
      "message": "string"
    }
  ]
}
```

## Changes

No changes to this operation in the revisions on Hub.
