---
title: "POST confirmation.denied"
method: POST
path: "confirmation.denied"
---

# POST confirmation.denied

`POST confirmation.denied` (webhook)

Fired when a confirmation is denied — by an approver, or by the system (`response.channel` `system`) on a timeout (`response.text` `timeout`), a key rotation or an archived config.

## Payload

- ConfirmationWebhookPayload: Body of `confirmation.approved` / `confirmation.denied`. A timeout is `confirmation.denied` with `response.channel` `system` and `response.text` `timeout`.
  - `event` 'confirmation.approved' | 'confirmation.denied', required: The event type — the same value as the `X-Proof-Event` header
  - `confirmation_id` string, required: MongoDB ObjectId
  - `hitl_id` string, required: HITL configuration the confirmation was sent through
  - `status` 'approved' | 'denied', required
  - `message` string, required: The stored ciphertext envelope, echoed back verbatim. The server never sees the plaintext, so this is never the human sentence — the approver decrypts it in their browser.
  - `response` object, nullable: Approver response details (null while pending)
    - `action` 'approve' | 'deny', required
    - `text` string, nullable: The approver's optional comment, encrypted in the browser by the approval page: a ciphertext envelope (JSON), not plaintext. When `channel` is `system` no approver acted — the confirmation was denied by a timeout, a key rotation or an archived config — and this is that plaintext reason (`timeout`, `key_rotated`, `config_archived`). Null otherwise.
    - `channel` string, nullable
    - `at` string, date-time, required
    - `authorization_id` string, nullable: The enrolled approver's Authorization that resolved this confirmation, verified server-side; null when the decision is not attributable to one approver
  - `proof_token` string: Signed proof of the approver's decision; absent for a system denial (`response.channel` `system`)
  - `encrypted` boolean, required: Whether `message` is a ciphertext envelope — derived from the message, not asserted
  - `resolved_at` string, date-time

## Acknowledgement `200`

Webhook received

---

[API](https://skmtc.dev/proof/apis/proof-holdings-api.md) · [All operations](https://skmtc.dev/proof/apis/proof-holdings-api/llms.txt) · [OpenAPI document](https://skmtc.dev/proof/apis/proof-holdings-api/revisions/6b8d61ee354f?raw)
