> For the complete documentation index, see [llms.txt](https://docs.stackai.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stackai.com/stackai-api/stackai-api-developer-guide/webhooks-and-signed-event-delivery.md).

# Webhooks and signed event delivery

#### Register and store the secret

POST `/v2/webhooks/subscriptions` with your HTTPS URL and desired event types:

```json
{
  "url":"https://your-service.example.com/webhooks/stackai",
  "event_types":["run.succeeded","run.failed"]
}
```

Use an authorized credential with `org.webhooks.manage`. Store the signing secret returned at creation immediately; list responses cannot recover it. To replace a lost secret, create a replacement subscription and retire the old one carefully. There is no PATCH subscription operation in this contract.

#### Completion notifications and availability

Use `GET /v2/runs/{run_id}` as the supported way to observe a workflow's completion. Creating a webhook subscription stores its URL and selected event names; it does not enable run-event delivery. Do not replace polling with a subscription when building a run-status integration.

| Capability                                    | What you can rely on                                                                                    |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Create, list, and delete subscriptions        | Manage the URL and accepted event types through the subscription endpoints                              |
| Observe completion of a run                   | Poll the run until it reaches a terminal status                                                         |
| Receive a run lifecycle notification          | Subscription creation alone does not establish this capability; it is not a replacement for run polling |
| Replay a delivery or inspect delivery history | No public replay or delivery-history endpoint is provided                                               |

Accepted subscription event names are `run.started`, `run.step.succeeded`, `run.step.failed`, `run.succeeded`, `run.failed`, and `run.cancelled`. These names describe subscription filters, not a guarantee that an event will be produced for every run. The receiver guidance below applies when webhook deliveries are enabled for your deployment.

#### Authenticate deliveries, then deduplicate

Deliveries use the Standard Webhooks headers `webhook-id`, `webhook-timestamp`, and `webhook-signature`. Verify against the exact raw request body and the subscription's `whsec_...` secret before parsing or processing. Use a Standard Webhooks verifier with timestamp validation; JSON reserialization changes the bytes and can break verification.

Conceptual Python handler logic with the `standardwebhooks` package:

```python
from standardwebhooks.webhooks import Webhook

# raw_body and headers come from your HTTP framework.
# secret comes from your secret manager, never from the incoming request.
verified_event = Webhook(secret).verify(raw_body, headers)
event_id = headers["webhook-id"]
# Atomically persist event_id and enqueue work only if it is new.
# Return 2xx after durable acceptance; process the work asynchronously.
```

Catch verification errors and reject invalid requests. Use durable, atomic deduplication; an in-memory set is insufficient across workers or restarts. Preserve the verified event's ID with your processing record. Retries reuse the same event ID and body. Do not assume event order or exactly-once delivery.

Successful 2xx responses acknowledge delivery. Redirects are not followed. Retryable client/server failures and transport failures can be retried; the current implementation has a bounded ladder of up to ten attempts with jitter. Return a suitable transient failure when you cannot durably accept work, rather than 200 and silently losing it. A 503 with numeric Retry-After can influence retry timing within server limits.

GET subscriptions to inventory active endpoints; DELETE a subscription to stop deliveries and remove it from that list. There is no public delivery-history or replay endpoint in this contract.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.stackai.com/stackai-api/stackai-api-developer-guide/webhooks-and-signed-event-delivery.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
