---
title: "Set the tool-approval policy"
method: PUT
path: "/v1/actor-preferences/approval-policy"
tags: ["actor-preferences"]
---

# Set the tool-approval policy

`PUT /v1/actor-preferences/approval-policy`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/actor-preferences/approval-policy`
- Auth: HTTP bearer

Set an actor's tool-approval policy. Only the requester may change their Critical choice.

## Headers

- `X-Tenant-Id` string, nullable

## Request body

- ApprovalPolicyBody: Request body for setting an actor's approval policy (``PUT``). Inherits the shared ``mode``/``tiers`` fields + validation (a malformed body is a 4xx here, unlike the fail-closed read path) and adds the routing-only ``actor_id``. ``mode`` is required (no default) so a caller states intent explicitly. ``actor_id`` is optional and admin-only: when omitted the route targets the CALLER's own actor, so the dashboard never needs to know its own actor id.
  - `mode` 'default' | 'always' | 'never' | 'tiers', required: How a user's per-actor approval preference shapes the tool-approval gate. Pure runtime concept, NOT a code-table. It never appears as a ``*_code`` column; it is the ``mode`` field inside the JSON value of the ``approval_policy`` :class:`~models.preference.ActorPreference`, so it is validated by Pydantic (``models.approval_policy``) rather than seeded into a reference table. Explicit Read, Write and Critical choices outrank mode. An unset Critical choice keeps its tier card. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. Target-bound approval rules remain. Requester-bound cards remain unless you chose Always allow on that action's approval card.
  - `tiers` RiskTier[]: The risk tiers that ask for approval when mode is tiers.
  - `read_tier` 'always_allow' | 'always_ask': A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `write_tier` 'always_allow' | 'always_ask': A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `critical_tier` 'always_allow' | 'always_ask': A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `actor_id` string, uuid, nullable

## Response `200`

Successful Response

- ApprovalPolicyResponse: An actor's effective approval policy and its general-policy tier floor.
  - `actor_id` string, uuid, required
  - `mode` 'default' | 'always' | 'never' | 'tiers', required: How a user's per-actor approval preference shapes the tool-approval gate. Pure runtime concept, NOT a code-table. It never appears as a ``*_code`` column; it is the ``mode`` field inside the JSON value of the ``approval_policy`` :class:`~models.preference.ActorPreference`, so it is validated by Pydantic (``models.approval_policy``) rather than seeded into a reference table. Explicit Read, Write and Critical choices outrank mode. An unset Critical choice keeps its tier card. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. Target-bound approval rules remain. Requester-bound cards remain unless you chose Always allow on that action's approval card.
  - `tiers` RiskTier[], required
  - `floor_tiers` RiskTier[], required: The default tier approval floor. An explicit Critical Always allow choice can waive it.
  - `read_tier` 'always_allow' | 'always_ask', required: A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `write_tier` 'always_allow' | 'always_ask', required: A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `critical_tier` 'always_allow' | 'always_ask', required: A member's explicit Allow/Ask choice for Read, Write or Critical actions. Critical defaults to Ask. Always allow can skip the confirm card for Critical actions from built-in tools and from Composio actions with a valid output contract. Actions from MCP connections and other apps still ask first. Under this setting alone, actions whose names look credential-shaped, actions that request credential reveal, and actions with missing or unreadable evidence keep their cards. A member may change only their own Critical choice.
  - `explicit_tier_groups` string[], required: Which of read/write/critical above are YOUR OWN choice rather than a value synthesized from mode/tiers. Trust read_tier/write_tier/critical_tier as the actor's real, unambiguous decision only for a group listed here — for one that is not, mode/tiers can still disagree with part of the group even though this field reports one value for it. Transitional for PAT-1755's mode/tiers retirement: expect every actor to list all three groups, and this field to become a no-op, once that series removes mode/tiers.

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `409`: Conflict
- `422`: Validation error

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
