> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlrun.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# WebhookApprovalProvider

> Notify a human system on `APPROVAL_REQUESTED`, and let it answer (SPEC-v0.2 §7).

`ctrlrun.WebhookApprovalProvider` — class, defined at `src/ctrlrun/webhook.py:135`

```python theme={null}
class WebhookApprovalProvider()
    def __init__(store: ApprovalStore, url: str, secret: object, timeout: timedelta, retries: int, backoff: timedelta, replay_window: timedelta, public_url: str | None, allow_insecure: bool, clock: Callable[[], datetime])
```

Notify a human system on `APPROVAL_REQUESTED`, and let it answer (SPEC-v0.2 §7).

An `ApprovalProvider` (v0.1 §4.3): `request()` records the request and posts it, `wait()`
polls the store exactly as `LocalApprovalProvider` does — the answer arrives out of band,
whether from the gateway's inbound endpoint or from `ctrlrun approve`.

**An undelivered notification is not an approval.** If every attempt fails the request
stays `pending`, `ApprovalRequired` is raised as usual with a real `request_id` that
`ctrlrun approve` can still answer, and the failure is logged. The action is refused
either way, which is the only outcome that is safe when nobody was told.

## Next

* [Python API index](/reference/api/index).
* [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Approvals in Slack via webhook](/cookbook/slack-approvals.md)
- [Approve in Slack](/guides/approvals-in-slack.md)
- [Claims](/CLAIMS.md)
- [Python API](/reference/api/index.md)
- [Choosing between them](/get-started/choosing.md)
