Confirm a destructive action
Handle 412 confirmation_required: mint a confirmation token and replay the call with X-Trustvice-Confirmation.
The job
Your caller needs an action whose confirmationPolicy is "always", which covers every destructive and billing_impacting action. Trustvice refuses to run those until the request carries a fresh confirmation token: a human, or an explicit autonomy grant, must have said yes, recently, for this action.
Before you start
- Account
- A Trustvice workspace
- Credential
- You also need
- An OAuth access token, as in the first recipe
curl
The code reads secrets from environment variables. Keep them in your shell or your secret store, never in a file you commit. Action calls also send X-Workspace-Id.
Steps
Call the action
Call the gated action as usual. Without a token it answers
412with the codeconfirmation_required. The docs useprivacy.dsr.submitas the example.curl -sS -X POST https://api.trustvice.com/api/v1/actions/privacy.dsr.submit \ -H "Authorization: Bearer $TRUSTVICE_TOKEN" \ -H "X-Workspace-Id: ws_…" \ -H "Content-Type: application/json" \ -d '{ … }'{ "ok": false, "error": { "code": "confirmation_required", "message": "This action requires an explicit confirmation." } }Mint a confirmation token
Ask
POST /api/v1/confirmations/mintfor a token for that action id. The token is bound to the calling actor and to the action's audience, lives for seconds and is consumed on first use.curlcurl -sS -X POST https://api.trustvice.com/api/v1/confirmations/mint \ -H "Authorization: Bearer $TRUSTVICE_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "actionId": "privacy.dsr.submit" }'Replay the action
Send the same call again with the token's
jtiinX-Trustvice-Confirmation. The action now runs and returns its real result.curlcurl -sS -X POST https://api.trustvice.com/api/v1/actions/privacy.dsr.submit \ -H "Authorization: Bearer $TRUSTVICE_TOKEN" \ -H "X-Workspace-Id: ws_…" \ -H "X-Trustvice-Confirmation: cnf_…" \ -H "Content-Type: application/json" \ -d '{ … }'Let an agent act within limits
An agent that must call gated actions without a per-call human click holds an autonomy grant: time-boxed, with a safety ceiling, recorded against the workspace. Granting one needs a human confirmation token for the
agents.autonomy.grantaudience. While a covering grant is active, mint returnsautonomous: truetokens for in-scope actions.HTTPPOST /api/v1/autonomy/grant { "maxSafetyLevel": …, "ttlSeconds": … } POST /api/v1/autonomy/revoke GET /api/v1/autonomy/status
Copied from: /docs/confirmations
What comes back
The mint call returns the token in jti, the action it is bound to in audience and the time it expires.
{ "ok": true,
"jti": "cnf_…",
"audience": "privacy.dsr.submit",
"autonomous": false,
"expiresAt": "2026-09-14T13:20:37.675Z" }What you can rely on
You can rely on
- A confirmation token cannot be replayed or used for another action.
- A gated action never runs silently: each call needs a fresh token or a covering autonomy grant.
- Autonomy can never be created autonomously.
Do not assume
- That a second confirmed call is harmless: unsafe actions are not idempotent, so a second call is a second effect.
- That a token keeps working: it lives for seconds.
Every statement above comes from the Trustvice docs linked on this page. Where a docs page says more, it is the reference.
Next steps
Related recipes
Call an Agentic API action
Mint an OAuth access token, find an action in the public catalogue and call it at POST /api/v1/actions/<id>.
Connect an MCP client
Add the Trustvice MCP server at https://mcp.trustvice.com/mcp to Claude Code, Cursor or VS Code.
Verify a receipt in the browser
Paste a Trustvice signed receipt into /verify and check its Ed25519 signature in your own browser.
New recipes by email
One short email when we add recipes to the cookbook. No other mail, and you can unsubscribe from any message.
Start with the Agentic API.
One POST endpoint per registered action, with the same behaviour over REST and MCP. The docs list every action with its input and permissions.
