> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Generate a signing secret (beta)

`POST /api/v1/connections/{connection_id}/trigger-ingress/signing-secret/generate`

This endpoint is in beta. Its request and response may change.

Generates a signing secret for an app that doesn't sign its events (`provides_bearer_secret` is `true` on its triggers), and returns it once. A generated secret starts with `skwh_`. Give it to the app, which sends it with every event: in an `Authorization: Bearer` header, in the `X-Scalekit-Webhook-Secret` header, or as the last segment of `url_with_secret` when the app can't set a header. Store it with your server's secrets now; it's never returned again. If a secret already exists, a new one starts a rotation. An app that signs its own events takes its secret through [Set a signing secret](https://docs.scalekit.com/agentkit/reference/triggers/set-a-signing-secret/) instead.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_id` | string | Yes | The connection whose webhook URL receives the generated secret. Between 1 and 64 characters. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `endpoint` | object | The connection's webhook endpoint after the secret was stored, rendered exactly as [Get a webhook URL](https://docs.scalekit.com/agentkit/reference/triggers/get-a-webhook-url/) renders it: the secret appears here only in masked form, and rotation_in_progress is true when this call started a rotation. |
| `endpoint.connection_id` | string | ID of the connection this webhook URL belongs to. |
| `endpoint.id` | string | Unique identifier of the connection's webhook endpoint. |
| `endpoint.masked_signing_secret` | string | The stored secret with all but its last four characters replaced, or every character replaced for a secret of 8 characters or fewer. Empty when none is configured. Enough to compare against the secret the provider's app configuration shows, and never enough to sign with. |
| `endpoint.previous_signing_secret_expires_at` | string | When the previous secret stops being accepted even if the rotation is never confirmed: 24 hours after the rotation started. Absent when no rotation is in progress. |
| `endpoint.rotation_in_progress` | boolean | Whether the previous signing secret is still accepted alongside the current one. True from the moment a different secret replaces a stored one until the rotation is confirmed, or until previous_signing_secret_expires_at passes. |
| `endpoint.signing_secret_configured` | boolean | Whether a signing secret is stored. While false, every event sent to the URL is answered with 503 so the provider retries it, and the provider's own URL verification fails. |
| `endpoint.signing_secret_rotation_id` | string | Identifies the latest signing-secret rotation; it increases by one each time a rotation starts. Zero when none has ever started. Pass this value to [Confirm a signing secret rotation](https://docs.scalekit.com/agentkit/reference/triggers/confirm-a-signing-secret-rotation/) to confirm this specific rotation. A value naming a rotation that a newer one has since replaced is refused rather than confirming the wrong rotation. |
| `endpoint.url` | string | The URL to paste into the provider's app configuration as the event destination. It is built on your environment's domain, using its custom domain when one is set, and ends in a random token unique to this connection, so treat it as confidential. Returned whether or not a signing secret has been set. The URL accepts request bodies up to 1 MB and answers a larger one with 413. Until a signing secret is set it answers events with 503, so the provider retries them; an event that fails signature verification is answered with 400. |
| `signing_secret` | string | The generated secret, in plain text. Returned only in this response and never again by any endpoint, nor written to a log. The provider presents it back on every event in exactly one of three ways: an `Authorization: Bearer <secret>` header, the `X-Scalekit-Webhook-Secret` header, or the final path segment of url_with_secret. |
| `url_with_secret` | string | Endpoint.url with the secret appended as a final path segment. Paste this into the provider's console when the provider cannot send a custom header. It is as sensitive as signing_secret and is likewise returned only in this response. |

**Errors**

- `400`: Invalid request, nothing written - connection_id is not a valid connection ID; the connection's provider signs its own events, so its secret is copied from the provider's app configuration and stored with [Set a signing secret](https://docs.scalekit.com/agentkit/reference/triggers/set-a-signing-secret/) instead (error_code TRIGGER_SIGNING_SECRET_NOT_GENERATABLE); or the provider's webhook trigger definitions are temporarily unavailable (error_code TRIGGER_INGRESS_DEFINITIONS_UNAVAILABLE)
- `404`: Not found - no webhook URL has been created for this connection yet (error_code TRIGGER_INGRESS_ENDPOINT_NOT_CREATED; call [Create a webhook URL](https://docs.scalekit.com/agentkit/reference/triggers/create-a-webhook-url/) first), the connection does not exist in this environment (error_code RESOURCE_NOT_FOUND), or Triggers isn't turned on for your environment (error_code RESOURCE_NOT_FOUND)
- `409`: Conflict - a rotation is already in progress. Confirm it with [Confirm a signing secret rotation](https://docs.scalekit.com/agentkit/reference/triggers/confirm-a-signing-secret-rotation/), or wait for the previous secret's expiry, before generating another secret
- `500`: Internal error - the secret could not be generated or stored, or the endpoint could not be read back; retry the request

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/connections/conn_133400101014998936/trigger-ingress/signing-secret/generate" \
  -H "Authorization: Bearer $TOKEN"
```

**Response**

```json
{
  "signing_secret": "skwh_Xq3vR8nT1bLm6KpZ2wYc9DfH4sJg7AeU0oNi5tGr1Bk",
  "url_with_secret": "https://your-env.scalekit.dev/triggers/v1/h3Lp8wQz1nRt6vYc4KmXb9/skwh_Xq3vR8nT1bLm6KpZ2wYc9DfH4sJg7AeU0oNi5tGr1Bk",
  "endpoint": {
    "id": "tie_149528599802681734",
    "connection_id": "conn_133400101014998936",
    "url": "https://your-env.scalekit.dev/triggers/v1/h3Lp8wQz1nRt6vYc4KmXb9",
    "signing_secret_configured": true,
    "masked_signing_secret": "********************************************r1Bk",
    "rotation_in_progress": false,
    "signing_secret_rotation_id": "0"
  }
}
```

**Python SDK:** `scalekit_client.actions.triggers.generate_signing_secret`

Generate a signing secret, for providers that use one Scalekit creates. The secret is returned in plaintext only in this response; it is left out of `repr()`. Not retried on `UNAVAILABLE`: a retry would replace the secret.

```python
scalekit_client.actions.triggers.generate_signing_secret(
    connection_id: str,
) -> GenerateTriggerSigningSecretResponse
```

Example:

```python
result = scalekit_client.actions.triggers.generate_signing_secret(
    connection_id="conn_133400101014998936",
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_id` | `str` | Yes | The connection (`conn_...`). |

Returns `GenerateTriggerSigningSecretResponse`: The endpoint, the secret and the URL that includes it.


Part of [Triggers](https://docs.scalekit.com/agentkit/reference/triggers/) in the [AgentKit API reference](https://docs.scalekit.com/agentkit/reference/). Authentication: https://docs.scalekit.com/agentkit/reference/authentication.md. Errors and rate limits: https://docs.scalekit.com/agentkit/reference/errors.md. Pagination: https://docs.scalekit.com/agentkit/reference/pagination.md


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
