---
type: api
title: Enable a rule
description: **Spaces method and path for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/kibana-serverless/operation/operation-post-alerting-v2-rules-id-enable
resource: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/kibana-serverless/operation/operation-post-alerting-v2-rules-id-enable
products:
  - Kibana
---

# Enable a rule

Availability:

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

## Paths

- `POST` `/api/alerting/v2/rules/{id}/_enable`
- `POST` `/s/{space_id}/api/alerting/v2/rules/{id}/_enable`

- [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 identifier for the rule. 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.

Enable a rule by identifier.<br/><br/>[Required authorization] Route required privileges: manage_alerting-v2-rules.

## Responses

#### `200`

Returns the enabled rule.

`application/json`

- `artifacts` ([] object · min: 1 · max: 100)
  Optional objects attached to the rule, such as a runbook or a dashboard. Each item has `id`, `type`, and `data`. The shape of `data` depends on `type`. For example, a `runbook` uses `content` and a `dashboard` uses `dashboard_id`. Known types are validated against that shape. Unknown types are stored when `id`, `type`, and `data` are present. An empty array is rejected: omit `artifacts` on create, or send `null` on PATCH to clear.
  - `data` (map string to object)
    Structured artifact data.
  - `id` (string · min: 1 · max: 150)
    Artifact identifier.
  - `type` (string · min: 1 · max: 128)
    Artifact type.
- `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))$)
  ISO timestamp when the rule was created.
- `created_by` ({})
  Actor who created the rule.
  - `profile_uid` (string) — nullable
    User profile ID of the actor, or `null` when it cannot be resolved.
- `enabled` (boolean)
  Whether the rule is enabled.
- `grouping` ({})
  Grouping configuration.
  - `fields` ([] string · min: 1 · max: 16)
    Fields to group alerts by, e.g. ["host.name", "service.name"]. Should match ES|QL GROUP BY fields.
- `id` (string)
  Unique rule identifier.
- `kind` (enum)
  Whether the rule creates alerts (`alert`) or only stores matching events (`signal`).
  Values: `alert`, `signal`
- `metadata` ({})
  Rule metadata.
  - `builder` (object)
    Identifies the rule builder that authored this rule (e.g. "threshold"). Absent for rules authored directly in ES|QL; send `null` on PATCH to clear it.
    - `type` (string · min: 1 · max: 64)
      Rule builder type.
  - `description` (string · min: 1 · max: 1024)
    Human-readable description of the rule. Omit to leave it unset; send `null` on PATCH to clear it. An empty string is rejected.
  - `name` (string · min: 1 · max: 256)
    Rule name (must be unique within the space).
  - `routing_tags` ([] string · min: 1 · max: 20)
    Routing tags that link alerts from this rule to action policies. An action policy applies when its `matcher.tags` contains at least one of these tags. Only allowed when kind is "alert".
  - `tags` ([] string · min: 1 · max: 20)
    Tags for categorization, e.g. ["production", "infra"].
- `no_data` (union)
  What the rule does when a group has no data. Required when `kind` is `alert`. Not allowed when `kind` is `signal`. Any strategy other than `ignore` requires either `query.breach` or `no_data.query`, so that a group with no data can be told apart from one that stopped breaching.
  - **Kibana_HTTP_APIs_alerting_rule_no_data_ignore** (`strategy: ignore`)
    Does not check whether a group still has data. Missing groups do not produce `no_data` events.
    - `strategy` (enum)
      Values: `ignore`
  - **Kibana_HTTP_APIs_alerting_rule_no_data_keep_last** (`strategy: keep_last`)
    Holds the alert's current status when the rule finds no data.
    - `query` (string · min: 1 · max: 10000)
      Optional ES|QL query that checks whether a group has data. If omitted, `query.base` is used, which then has to be a presence query in its own right — so `query.breach` is required.
    - `strategy` (enum)
      Values: `keep_last`
  - **Kibana_HTTP_APIs_alerting_rule_no_data_resolve** (`strategy: resolve`)
    Closes the alert the first time the rule finds no data for a group.
    - `query` (string · min: 1 · max: 10000)
      Optional ES|QL query that checks whether a group has data. If omitted, `query.base` is used, which then has to be a presence query in its own right — so `query.breach` is required.
    - `strategy` (enum)
      Values: `resolve`
  - **Kibana_HTTP_APIs_alerting_rule_no_data_alert** (`strategy: alert`)
    Marks an existing alert `active` when the rule finds no data. It never opens an alert for a group that has not breached. Not accepted when creating or updating rules.
    - `query` (string · min: 1 · max: 10000)
      Optional ES|QL query that checks whether a group has data. If omitted, `query.base` is used, which then has to be a presence query in its own right — so `query.breach` is required.
    - `strategy` (enum)
      Values: `alert`
- `query` ({})
  ES|QL query the rule evaluates. `base` is required. `breach` is an optional clause appended to it.
  - `base` (string · min: 1 · max: 10000)
    ES|QL query that specifies the data to evaluate. Must include a `FROM` clause. Kibana applies the time filter from `schedule.lookback` using `time_field`.
  - `breach` ({})
    Optional ES|QL clause appended to `query.base`. If omitted, every row from `query.base` is a match, and a `no_data` strategy other than `ignore` then requires `no_data.query`.
    - `segment` (string · min: 1 · max: 10000)
      ES|QL clause appended to `query.base`, for example `WHERE avg_cpu > 0.85`. Don't include a `FROM` clause.
- `recovery` (union)
  When an alert recovers. Required when `kind` is `alert`. Not allowed when `kind` is `signal`.
  - **Kibana_HTTP_APIs_alerting_rule_recovery_no_breach** (`strategy: no_breach`)
    Recovers the alert when its group no longer appears in the breach results.
    - `strategy` (enum)
      Values: `no_breach`
  - **Kibana_HTTP_APIs_alerting_rule_recovery_condition** (`strategy: condition`)
    Recovers the alert when `query.base` plus `segment` returns the group. Requires `query.breach`.
    - `segment` (string · min: 1 · max: 10000)
      ES|QL clause appended to `query.base`, for example `WHERE avg_cpu < 0.60`. Don't include a `FROM` clause.
    - `strategy` (enum)
      Values: `condition`
  - **Kibana_HTTP_APIs_alerting_rule_recovery_query** (`strategy: query`)
    Recovers the alert when this separate query returns the group.
    - `query` (string · min: 1 · max: 10000)
      Independent ES|QL query, including its own `FROM` clause. A matching group recovers the alert.
    - `strategy` (enum)
      Values: `query`
  - **Kibana_HTTP_APIs_alerting_rule_recovery_manual** (`strategy: manual`)
    Does not recover automatically. Close the alert with a user action. `state_transition.recovering` has no effect.
    - `strategy` (enum)
      Values: `manual`
- `schedule` ({})
  Execution schedule configuration.
  - `every` (string · max: 32)
    Execution interval, e.g. 1m, 5m, 1h.
  - `lookback` (string · max: 32)
    Lookback window for the query, e.g. 5m, 1h. Can also be expressed in ES|QL.
- `state_transition` ({})
  Specifies how many consecutive matches, or how long a condition must hold, before an alert becomes `active` or `inactive`. Allowed only when `kind` is `alert`.
  - `pending` ({})
    - `count` (integer · min: 0 · max: 1000)
      Consecutive matches the alert spends in `pending` before it becomes `active` on the next match. For example, `2` opens it on the third consecutive match. Set to `0` to open it on the first match.
    - `operator` (enum)
      When both `count` and `timeframe` are set, `and` requires both and `or` requires either. Allowed only when both fields are present.
      Values: `and`, `or`
    - `timeframe` (string · max: 32)
      Duration the condition must hold, for example `5m`. Combine with `count` using `operator`.
  - `recovering` ({})
    - `count` (integer · min: 0 · max: 1000)
      Consecutive recoveries the alert spends in `recovering` before it becomes `inactive` on the next recovery. For example, `2` closes it on the third consecutive recovery. Set to `0` to close it on the first recovery.
    - `operator` (enum)
      When both `count` and `timeframe` are set, `and` requires both and `or` requires either. Allowed only when both fields are present.
      Values: `and`, `or`
    - `timeframe` (string · max: 32)
      Duration the condition must hold, for example `5m`. Combine with `count` using `operator`.
- `time_field` (string · min: 1 · max: 256 · default: @timestamp)
  Document field Kibana uses with `schedule.lookback` to time-filter `query.base`.
- `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))$)
  ISO timestamp when the rule was last updated.
- `updated_by` ({})
  Actor who last updated the rule.
  - `profile_uid` (string) — nullable
    User profile ID of the actor, or `null` when it cannot be resolved.
- `version` (integer · min: 1 · max: 9007199254740991)
  Monotonically increasing integer number representing a rule configuration version, incremented on every change. Used on generated rule events as `rule.version`.
#### `400`

Indicates the request is invalid, for example enabling the rule would exceed the configured schedule limit.

`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 to perform the request.

`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 a rule 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 rule 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
POST /api/alerting/v2/rules/{id}/_enable
```

#### curl

```curl
curl -X POST "https://{kibana_url}/api/alerting/v2/rules/{id}/_enable" \
  -H "kbn-xsrf: true"
```

## Response Examples

#### Enabled host CPU threshold rule

```json
{
  "created_at": "2026-01-15T12:00:00.000Z",
  "created_by": {
    "profile_uid": "u_elastic_0"
  },
  "enabled": true,
  "grouping": {
    "fields": [
      "host.name"
    ]
  },
  "id": "rule-1",
  "kind": "alert",
  "metadata": {
    "description": "Alerts when average CPU usage exceeds a threshold.",
    "name": "Host CPU high",
    "routing_tags": [
      "sre-oncall"
    ],
    "tags": [
      "production",
      "infra"
    ]
  },
  "no_data": {
    "strategy": "keep_last"
  },
  "query": {
    "base": "FROM metrics-* | STATS avg_cpu = AVG(host.cpu.usage) BY host.name",
    "breach": {
      "segment": "WHERE avg_cpu \u003E 0.9"
    }
  },
  "recovery": {
    "strategy": "no_breach"
  },
  "schedule": {
    "every": "1m",
    "lookback": "5m"
  },
  "state_transition": {
    "pending": {
      "count": 1
    },
    "recovering": {
      "count": 1
    }
  },
  "time_field": "@timestamp",
  "updated_at": "2026-01-15T12:00:00.000Z",
  "updated_by": {
    "profile_uid": "u_elastic_0"
  },
  "version": 1
}
```

#### Indicates the request is invalid, for example enabling the rule would exceed the configured schedule limit.

```json
{
  "code": "MAX_SCHEDULES_PER_MINUTE_EXCEEDED",
  "details": {
    "interval": "1m",
    "max_scheduled_per_minute": 400
  },
  "error": "Bad Request",
  "message": "Rule schedule of \u00221m\u0022 would exceed the limit of 400 rule runs per minute"
}
```

#### Request was not authenticated

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

#### Caller lacks required privileges

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

#### No rule exists for the given ID

```json
{
  "code": "RULE_NOT_FOUND",
  "details": {
    "rule_id": "rule-1"
  },
  "error": "Not Found",
  "message": "Rule with id \u0022rule-1\u0022 not found"
}
```

#### Indicates the rule was concurrently updated by another caller.

```json
{
  "code": "RULE_VERSION_CONFLICT",
  "details": {
    "rule_id": "rule-1"
  },
  "error": "Conflict",
  "message": "Rule with id \u0022rule-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."
}
```

