---
type: api
title: Partially update an action policy.
description: **Spaces method and path for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/kibana-serverless/operation/operation-patch-alerting-v2-action-policies-id
resource: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/kibana-serverless/operation/operation-patch-alerting-v2-action-policies-id
products:
  - Kibana
---

# Partially update an action policy.

Availability:

- Server: `https://{kibana_url}`

## Paths

- `PATCH` `/api/alerting/v2/action_policies/{id}`
- `PATCH` `/s/{space_id}/api/alerting/v2/action_policies/{id}`

- [Api key auth](/elastic/docs-builder/docs/4371/api/doc/kibana-serverless/authentication#apikeyauth)

#### Path Parameters

- `id` (string · min: 1 · max: 150 · pattern: ^[a-zA-Z0-9_-]+$)
  The ID of the action policy. Copy it from the response when you create a policy, fetch one policy, or fetch the policy list. Chosen at creation and permanent — it cannot be changed afterwards. Re-using the id of a deleted resource is allowed but discouraged: execution history, change history, and alert episodes recorded under that id are retained and are attributed to the new resource. Ids appear in URLs and logs, so keep them free of sensitive data.

## Description

Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information.

Apply a partial update. A field you omit keeps its stored value, and that applies at every level: send `{"matcher": {"tags": ["prod"]}}` to change one leaf while leaving its siblings alone. Send `null` to clear a field, again at any level: `{"matcher": {"expression": null}}` clears a single leaf, while `{"matcher": null}` clears a whole object. Lists and variant objects are replaced as a unit rather than merged, since a partly-sent variant could never be valid. The merged result is validated as a whole, so a patch that would leave the resource invalid is rejected with a `400` and nothing is stored.<br/><br/>[Required authorization] Route required privileges: manage_alerting-v2-action-policies AND read_alerting-v2-rules.

## Request Body

`application/json`

- `description` (string · min: 1 · max: 1024) — optional — nullable
  A description of the action policy. Absent when the policy has none; send `null` on PATCH to clear it.
- `destinations` ([] union  · min: 1 · max: 10) — optional
  The list of destinations. At least one is required.
  - **Kibana_HTTP_APIs_alerting_workflow_action_policy_destination**
    - `id` (string · min: 1 · max: 150) — required
      The workflow identifier.
    - `type` (enum) — required
      The destination type.
      Values: `workflow`
- `grouping` (object) — optional
  How matched alerts are batched into notifications. Absent falls back to `per_alert`; send `null` on PATCH to clear it. The mode decides the rest of the block, so a PATCH replaces it whole: send the complete mode variant rather than a single field.
- `matcher` (object) — optional — nullable
  Selects the alerts this policy applies to. Set `tags` to match alerts from rules with those routing tags. Set `expression` to a KQL query, which will be evaluated against each alert. <br/><br/> If you set both `tags` and `expression`, an alert must match the tags and the expression for the policy to apply. Omit `matcher` to keep the stored matcher, or set it to `null` for a catch-all policy that applies to all alerts. An empty `matcher` names no leaf and so changes nothing; clearing the last of `tags` and `expression` clears the matcher itself, which is also a catch-all.
  - `expression` (string · min: 1 · max: 4096) — optional — nullable
    A KQL query that's evaluated against each alert. Supported fields are: `alert_id`, `alert_status`, `group_hash`, `last_event_timestamp`, `severity`, and your rule's query output columns under `data.*` (for example, `data.host.name`). Referencing other fields won't work. Omit `matcher.expression` to keep the stored expression, or set it to `null` to clear it and match on `tags` alone.
  - `tags` ([] string · min: 1 · max: 50) — optional — nullable
    Routing tags this policy should match. The policy applies to alerts from any rule whose `metadata.routing_tags` include at least one of these tags. An empty array is not accepted. Omit `matcher.tags` to keep the stored tags, or set it to `null` to clear them and match on `matcher.expression` alone.
- `name` (string · min: 1 · max: 256) — optional
  The name of the action policy.
- `throttle` (object) — optional
  The throttle configuration for notifications. Absent when notifications are not throttled; send `null` on PATCH to clear it. The strategy decides the rest of the block, so a PATCH replaces it whole: send the complete strategy variant rather than a single field.

## Responses

#### `200`

Returns the updated action policy.

`application/json`

- `created_at` (string · pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$)
  The ISO datetime when the action policy was created.
- `created_by` ({})
  The actor who created the action policy.
  - `profile_uid` (string) — nullable
    User profile ID of the actor, or `null` when it cannot be resolved.
- `description` (string)
  A description of the action policy. Omitted when the policy has none.
- `destinations` ([] union)
  The list of destinations.
  - **Kibana_HTTP_APIs_alerting_workflow_action_policy_destination**
    - `id` (string · min: 1 · max: 150)
      The workflow identifier.
    - `type` (enum)
      The destination type.
      Values: `workflow`
- `enabled` (boolean)
  Whether the action policy is enabled.
- `grouping` (union)
  - **Kibana_HTTP_APIs_alerting_action_policy_grouping_per_alert** (`mode: per_alert`)
    one notification per alert lifecycle (default).
    - `mode` (enum)
      Values: `per_alert`
  - **Kibana_HTTP_APIs_alerting_action_policy_grouping_all** (`mode: all`)
    a single notification for all matching alerts.
    - `mode` (enum)
      Values: `all`
  - **Kibana_HTTP_APIs_alerting_action_policy_grouping_per_field** (`mode: per_field`)
    group by the specified `fields`.
    - `fields` ([] string · min: 1 · max: 16)
      The fields alerts are grouped by. At least one is required, and no other mode accepts them.
    - `mode` (enum)
      Values: `per_field`
- `id` (string)
  The unique identifier for the action policy.
- `matcher` (object)
  Selects the alerts this policy applies to. Set `tags` to match alerts from rules with those routing tags. Set `expression` to a KQL query, which will be evaluated against each alert. <br/><br/> If you set both `tags` and `expression`, an alert must match the tags and the expression for the policy to apply. At least one of `tags` and `expression` must be set, so an empty `matcher` is rejected. Omit `matcher` entirely for a catch-all policy that applies to all alerts.
  - `expression` (string · min: 1 · max: 4096)
    A KQL query that's evaluated against each alert. Supported fields are: `alert_id`, `alert_status`, `group_hash`, `last_event_timestamp`, `severity`, and your rule's query output columns under `data.*` (for example, `data.host.name`). Referencing other fields won't work. Omit `matcher.expression` to match on `tags` alone.
  - `tags` ([] string · min: 1 · max: 50)
    Routing tags this policy should match. The policy applies to alerts from any rule whose `metadata.routing_tags` include at least one of these tags. An empty array is not accepted. Omit `matcher.tags` to match on `matcher.expression` alone.
- `name` (string)
  The name of the action policy.
- `snoozed_until` (string)
  The ISO datetime until which the policy is snoozed. Omitted when the policy is not snoozed.
- `throttle` (union)
  - **Kibana_HTTP_APIs_alerting_action_policy_throttle_on_status_change** (`strategy: on_status_change`)
    notify only on alert status transitions (default for `per_alert`).
    - `strategy` (enum)
      Values: `on_status_change`
  - **Kibana_HTTP_APIs_alerting_action_policy_throttle_per_status_interval** (`strategy: per_status_interval`)
    notify on transitions and at regular intervals.
    - `interval` (string · max: 32)
      The throttle interval duration (e.g. 5m, 1h) that sets the notification cadence.
    - `strategy` (enum)
      Values: `per_status_interval`
  - **Kibana_HTTP_APIs_alerting_action_policy_throttle_time_interval** (`strategy: time_interval`)
    notify at regular intervals regardless of status (default for `all`/`per_field`).
    - `interval` (string · max: 32)
      The throttle interval duration (e.g. 5m, 1h) that sets the notification cadence.
    - `strategy` (enum)
      Values: `time_interval`
  - **Kibana_HTTP_APIs_alerting_action_policy_throttle_every_time** (`strategy: every_time`)
    notify on every evaluation cycle (high volume).
    - `strategy` (enum)
      Values: `every_time`
- `updated_at` (string · pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$)
  The ISO datetime when the action policy was last updated.
- `updated_by` ({})
  The actor who last updated the action policy.
  - `profile_uid` (string) — nullable
    User profile ID of the actor, or `null` when it cannot be resolved.
#### `400`

Indicates an invalid schema or parameters.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `401`

Indicates the request was not authenticated.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `403`

Indicates the user does not have the required privileges, or the current license does not support action policies. Creating, updating, and enabling action policies requires an active Enterprise license.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `404`

Indicates an action policy with the given ID does not exist.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `409`

Indicates the action policy was concurrently updated by another caller.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `500`

Indicates an unexpected server-side error.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
#### `503`

Indicates the alerting engine is disabled by the `alerting:v2:enabled` advanced setting.

`application/json`

- `code` (string)
  Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
- `details` (map string to object)
  Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
- `error` (string)
  A short human-readable summary of the error category (e.g., "Not Found", "Bad Request"). Subject to change without notice. Do not parse or rely on its content.
- `message` (string)
  A readable explanation of the error. The wording can change without notice. Do not parse this field.
## Code Examples

#### Console

```console
PATCH /api/alerting/v2/action_policies/{id}
{
  "description": "Updated description.",
  "matcher": {
    "expression": "null",
    "tags": [
      "production"
    ]
  },
  "name": "Notify on production alerts (updated)"
}
```

#### curl

```curl
curl -X PATCH "https://{kibana_url}/api/alerting/v2/action_policies/{id}" \
  -H "kbn-xsrf: true" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "Updated description.",
  "matcher": {
    "expression": "null",
    "tags": [
      "production"
    ]
  },
  "name": "Notify on production alerts (updated)"
}'
```

## Response Examples

#### Updated action policy

```json
{
  "created_at": "2026-01-15T12:00:00.000Z",
  "created_by": {
    "profile_uid": "u_elastic_0"
  },
  "description": "Updated description.",
  "destinations": [
    {
      "id": "workflow-1",
      "type": "workflow"
    }
  ],
  "enabled": true,
  "grouping": {
    "mode": "per_alert"
  },
  "id": "action-policy-1",
  "matcher": {
    "tags": [
      "production"
    ]
  },
  "name": "Notify on production alerts (updated)",
  "throttle": {
    "strategy": "on_status_change"
  },
  "updated_at": "2026-01-15T12:00:00.000Z",
  "updated_by": {
    "profile_uid": "u_elastic_0"
  }
}
```

#### Indicates an invalid schema or parameters.

```json
{
  "code": "INVALID_ACTION_POLICY_DATA",
  "details": {
    "context": "update",
    "errors": {
      "errors": [],
      "properties": {
        "name": {
          "errors": [
            "Invalid input: expected string, received undefined"
          ]
        }
      }
    }
  },
  "error": "Bad Request",
  "message": "Error validating update action policy data - name: Invalid input: expected string, received undefined"
}
```

#### Request was not authenticated

```json
{
  "code": "UNAUTHORIZED",
  "error": "Unauthorized",
  "message": "Authentication required to access this API."
}
```

#### The current license does not support action policies

```json
{
  "code": "ACTION_POLICY_LICENSE_NOT_SUPPORTED",
  "details": {
    "current_license": "basic",
    "license_status": "active",
    "required_license": "enterprise"
  },
  "error": "Forbidden",
  "message": "Action policies require an active enterprise license"
}
```

#### Caller lacks required privileges

```json
{
  "code": "FORBIDDEN",
  "error": "Forbidden",
  "message": "The current user does not have the required privileges for this request."
}
```

#### Indicates an action policy with the given ID does not exist.

```json
{
  "code": "ACTION_POLICY_NOT_FOUND",
  "details": {
    "action_policy_id": "action-policy-1"
  },
  "error": "Not Found",
  "message": "Action policy with ID \u0022action-policy-1\u0022 not found"
}
```

#### Indicates the action policy was concurrently updated by another caller.

```json
{
  "code": "ACTION_POLICY_VERSION_CONFLICT",
  "details": {
    "action_policy_id": "action-policy-1"
  },
  "error": "Conflict",
  "message": "Action policy with ID \u0022action-policy-1\u0022 has already been updated by another user"
}
```

#### Unexpected server-side error

```json
{
  "code": "INTERNAL_SERVER_ERROR",
  "error": "Internal Server Error",
  "message": "An unexpected error occurred."
}
```

#### Alerting V2 is disabled

```json
{
  "code": "ALERTING_DISABLED",
  "error": "Service Unavailable",
  "message": "Alerting is disabled."
}
```

