---
title: "Update a policy"
method: PUT
path: "/api/v1/policies/{id}"
tags: ["Policies"]
deprecated: true
---

# Update a policy

`PUT /api/v1/policies/{id}`

## Request

- Base URL: `https://agent.getaxonflow.com`
- URL: `https://agent.getaxonflow.com/api/v1/policies/{id}`
- Auth: none declared. Required headers: `X-Tenant-ID`
- TypeScript: <https://skmtc.dev/getaxonflow/apis/axonflow-policy-management-api/docs/api/v1/policies/:id/put.ts> (a function with typed inputs; its response is checked against the schema)

> **Deprecated.**

Update an existing policy. Only provided fields are updated.

## Headers

- `X-User-ID` string

## Request body

- UpdatePolicyRequest
  - `name` string
  - `description` string
  - `type` 'content' | 'user' | 'risk' | 'cost' | 'context_aware' | 'media' | 'rate-limit' | 'budget' | 'time-access' | 'role-access' | 'mcp' | 'connector': Policy type determines evaluation context: - `content`: Evaluates request/response content - `user`: Evaluates user attributes - `risk`: Evaluates risk scores - `cost`: Evaluates cost estimates - `context_aware`: Context-aware controls (tenant isolation, debug restriction, sensitive-data control) - `media`: Media governance policies (multimodal image governance) - `rate-limit`, `budget`, `time-access`: MCP rate/budget controls - `role-access`, `mcp`, `connector`: MCP access controls
  - `category` string: Policy category. Only changeable on non-system policies.
  - `conditions` PolicyCondition[]
    - `field` 'query' | 'response' | 'user.email' | 'user.role' | 'user.department' | 'user.tenant_id' | 'risk_score' | 'request_type' | 'connector' | 'cost_estimate' | 'media.has_faces' | 'media.face_count' | 'media.has_biometric_data' | 'media.nsfw_score' | 'media.violence_score' | 'media.content_safe' | 'media.document_type' | 'media.is_sensitive_document' | 'media.has_pii' | 'media.pii_types' | 'media.has_extracted_text' | 'media.extracted_text_length' | 'step.gate_count' | 'step.completion_count' | 'step.prior_completion_status' | 'step.prior_output_available' | 'step.last_decision' | 'step.first_attempt_age_seconds' | 'step.idempotency_key', required: Field to evaluate. `media.*` fields apply to media governance policies (multimodal image governance); `step.*` fields are retry-aware workflow step fields for WCP policies.
    - `operator` 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'contains_any' | 'regex' | 'greater_than' | 'less_than' | 'in' | 'not_in', required: Comparison operator for conditions
    - `value` union, required: Value to compare against
      - string
      - number
      - boolean
      - string[]
  - `actions` PolicyAction[]
    - `type` 'block' | 'require_approval' | 'redact' | 'warn' | 'alert' | 'log' | 'route' | 'modify_risk', required: Action to take when policy matches: - `block`: Block the request with message - `require_approval`: Hold the request for human approval (HITL) - `redact`: Redact sensitive content from response - `warn`: Allow the request but attach a warning - `alert`: Send alert to configured channel - `log`: Log to audit trail - `route`: Route to specific provider - `modify_risk`: Adjust risk score
    - `config` object: Action-specific configuration
  - `priority` integer
  - `enabled` boolean
  - `tags` string[]: Tags for categorization

## Response `200`

Policy updated

- PolicyResponse
  - `policy` PolicyResource
    - `id` string: Unique policy identifier
    - `name` string: Human-readable policy name
    - `description` string: Detailed policy description
    - `type` 'content' | 'user' | 'risk' | 'cost' | 'context_aware' | 'media' | 'rate-limit' | 'budget' | 'time-access' | 'role-access' | 'mcp' | 'connector': Policy type determines evaluation context: - `content`: Evaluates request/response content - `user`: Evaluates user attributes - `risk`: Evaluates risk scores - `cost`: Evaluates cost estimates - `context_aware`: Context-aware controls (tenant isolation, debug restriction, sensitive-data control) - `media`: Media governance policies (multimodal image governance) - `rate-limit`, `budget`, `time-access`: MCP rate/budget controls - `role-access`, `mcp`, `connector`: MCP access controls
    - `category` string: Policy category (dynamic-risk, dynamic-compliance, media-safety, etc.)
    - `tier` 'system' | 'organization' | 'tenant': Policy tier in the hierarchy (system policies are immutable)
    - `conditions` PolicyCondition[]: Conditions that must all match (AND logic)
      - `field` 'query' | 'response' | 'user.email' | 'user.role' | 'user.department' | 'user.tenant_id' | 'risk_score' | 'request_type' | 'connector' | 'cost_estimate' | 'media.has_faces' | 'media.face_count' | 'media.has_biometric_data' | 'media.nsfw_score' | 'media.violence_score' | 'media.content_safe' | 'media.document_type' | 'media.is_sensitive_document' | 'media.has_pii' | 'media.pii_types' | 'media.has_extracted_text' | 'media.extracted_text_length' | 'step.gate_count' | 'step.completion_count' | 'step.prior_completion_status' | 'step.prior_output_available' | 'step.last_decision' | 'step.first_attempt_age_seconds' | 'step.idempotency_key', required: Field to evaluate. `media.*` fields apply to media governance policies (multimodal image governance); `step.*` fields are retry-aware workflow step fields for WCP policies.
      - `operator` 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'contains_any' | 'regex' | 'greater_than' | 'less_than' | 'in' | 'not_in', required: Comparison operator for conditions
      - `value` union, required: Value to compare against
        - string
        - number
        - boolean
        - string[]
    - `actions` PolicyAction[]: Actions to execute when policy matches
      - `type` 'block' | 'require_approval' | 'redact' | 'warn' | 'alert' | 'log' | 'route' | 'modify_risk', required: Action to take when policy matches: - `block`: Block the request with message - `require_approval`: Hold the request for human approval (HITL) - `redact`: Redact sensitive content from response - `warn`: Allow the request but attach a warning - `alert`: Send alert to configured channel - `log`: Log to audit trail - `route`: Route to specific provider - `modify_risk`: Adjust risk score
      - `config` object: Action-specific configuration
    - `priority` integer: Higher priority policies are evaluated first
    - `enabled` boolean: Whether the policy is active
    - `version` integer: Policy version number, incremented on each update
    - `tenant_id` string: Owning tenant ID
    - `organization_id` string: The organisation that owns this policy. Since #3490 the organisation is what SELECTS a policy row, at every tier -- this is not an organization-tier-only field, and the previous wording described the retired organization_id COLUMN rather than this resource field.
    - `tags` string[]: Tags for categorization
    - `created_at` string, date-time: Creation timestamp
    - `updated_at` string, date-time: Last update timestamp
    - `created_by` string: User who created the policy
    - `updated_by` string: User who last updated the policy
    - `deleted_at` string, date-time: Soft-delete timestamp (present only on deleted policies)

## Other responses

- `400`: Request validation failed
- `401`: Missing or invalid tenant ID
- `404`: Policy not found
- `409`: The legacy policy tables are read-only. `migrations/core/172` revoked INSERT, UPDATE, DELETE and TRUNCATE on `static_policies` and `dynamic_policies` from the application roles, and this endpoint writes them, so the write is refused permanently rather than transiently. It is not an entitlement fact: no licence, edition or upgrade changes it. Author policies through the typed authoring route (`/api/v1/typed-policies`, in `orchestrator-api.yaml`) instead. Reads on this endpoint are unaffected. A deployment whose connection may still write the tables (the database owner; a property of the connection, not of `AXONFLOW_DB_USE_APP_ROLE` alone) is not bound by the revoke and does not receive this response. Where the connection cannot write them, the create, update and bulk-import routes answer this before reading the request body, whatever it contains.
- `500`: Internal server error

---

[API](https://skmtc.dev/getaxonflow/apis/axonflow-policy-management-api.md) - [All operations](https://skmtc.dev/getaxonflow/apis/axonflow-policy-management-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaxonflow/apis/axonflow-policy-management-api/revisions/302fbde24320?raw)
