Claude
Skills
Sign in
Back

kibana-alerting-rules

Included with Lifetime
$97 forever

Create and manage Kibana alerting rules via REST API or Terraform. Use when creating, updating, or managing rule lifecycle (enable, disable, mute, snooze) or rules-as-code workflows.

Backend & APIs

What this skill does


# Kibana Alerting Rules

## Core Concepts

A rule has three parts: **conditions** (what to detect), **schedule** (how often to check), and **actions** (what
happens when conditions are met). When conditions are met, the rule creates **alerts**, which trigger **actions** via
**connectors**.

## Authentication

All alerting API calls require either API key auth or Basic auth. Every mutating request must include the `kbn-xsrf`
header.

```http
kbn-xsrf: true
```

## Required Privileges

- `all` privileges for the appropriate Kibana feature (e.g., Stack Rules, Observability, Security)
- `read` privileges for Actions and Connectors (to attach actions to rules)

## API Reference

Base path: `<kibana_url>/api/alerting` (or `/s/<space_id>/api/alerting` for non-default spaces).

| Operation         | Method | Endpoint                                                   |
| ----------------- | ------ | ---------------------------------------------------------- |
| Create rule       | POST   | `/api/alerting/rule/{id}`                                  |
| Update rule       | PUT    | `/api/alerting/rule/{id}`                                  |
| Get rule          | GET    | `/api/alerting/rule/{id}`                                  |
| Delete rule       | DELETE | `/api/alerting/rule/{id}`                                  |
| Find rules        | GET    | `/api/alerting/rules/_find`                                |
| List rule types   | GET    | `/api/alerting/rule_types`                                 |
| Enable rule       | POST   | `/api/alerting/rule/{id}/_enable`                          |
| Disable rule      | POST   | `/api/alerting/rule/{id}/_disable`                         |
| Mute all alerts   | POST   | `/api/alerting/rule/{id}/_mute_all`                        |
| Unmute all alerts | POST   | `/api/alerting/rule/{id}/_unmute_all`                      |
| Mute alert        | POST   | `/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute`      |
| Unmute alert      | POST   | `/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute`    |
| Update API key    | POST   | `/api/alerting/rule/{id}/_update_api_key`                  |
| Create snooze     | POST   | `/api/alerting/rule/{id}/snooze_schedule`                  |
| Delete snooze     | DELETE | `/api/alerting/rule/{ruleId}/snooze_schedule/{scheduleId}` |
| Health check      | GET    | `/api/alerting/_health`                                    |

## Creating a Rule

### Required Fields

| Field          | Type   | Description                                                                                                                                           |
| -------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`         | string | Display name (does not need to be unique)                                                                                                             |
| `rule_type_id` | string | The rule type (e.g., `.es-query`, `.index-threshold`)                                                                                                 |
| `consumer`     | string | Owning app: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, `uptime` |
| `params`       | object | Rule-type-specific parameters                                                                                                                         |
| `schedule`     | object | Check interval, e.g., `{"interval": "5m"}`                                                                                                            |

### Optional Fields

| Field         | Type        | Description                                                                                         |
| ------------- | ----------- | --------------------------------------------------------------------------------------------------- |
| `actions`     | array       | Actions to run when conditions are met (each references a connector)                                |
| `tags`        | array       | Tags for organizing rules                                                                           |
| `enabled`     | boolean     | Whether the rule runs immediately (default: true)                                                   |
| `notify_when` | string      | `onActionGroupChange`, `onActiveAlert`, or `onThrottleInterval` (prefer setting per-action instead) |
| `alert_delay` | object      | Alert only after N consecutive matches, e.g., `{"active": 3}`                                       |
| `flapping`    | object/null | Override flapping detection settings                                                                |

### Example: Create an Elasticsearch Query Rule

```bash
curl -X POST "https://my-kibana:5601/api/alerting/rule/my-rule-id" \
  -H "kbn-xsrf: true" \
  -H "Content-Type: application/json" \
  -H "Authorization: ApiKey <your-api-key>" \
  -d '{
    "name": "High error rate",
    "rule_type_id": ".es-query",
    "consumer": "stackAlerts",
    "schedule": { "interval": "5m" },
    "params": {
      "index": ["logs-*"],
      "timeField": "@timestamp",
      "esQuery": "{\"query\":{\"match\":{\"log.level\":\"error\"}}}",
      "threshold": [100],
      "thresholdComparator": ">",
      "timeWindowSize": 5,
      "timeWindowUnit": "m",
      "size": 100
    },
    "actions": [
      {
        "id": "my-slack-connector-id",
        "group": "query matched",
        "params": {
          "message": "Alert: {{rule.name}} - {{context.hits}} hits detected"
        },
        "frequency": {
          "summary": false,
          "notify_when": "onActionGroupChange"
        }
      }
    ],
    "tags": ["production", "errors"]
  }'
```

The same structure applies to other rule types — set the appropriate `rule_type_id` (e.g., `.index-threshold`,
`.es-query`) and provide the matching `params` object. Use `GET /api/alerting/rule_types` to discover params schemas.

## Updating a Rule

`PUT /api/alerting/rule/{id}` — send the complete rule body. `rule_type_id` and `consumer` are immutable after creation.
Returns **409 Conflict** if another user updated the rule concurrently; re-fetch and retry.

## Finding Rules

```bash
curl -X GET "https://my-kibana:5601/api/alerting/rules/_find?per_page=20&page=1&search=cpu&sort_field=name&sort_order=asc" \
  -H "Authorization: ApiKey <your-api-key>"
```

Query parameters: `per_page`, `page`, `search`, `default_search_operator`, `search_fields`, `sort_field`, `sort_order`,
`has_reference`, `fields`, `filter`, `filter_consumers`.

Use the `filter` parameter with KQL syntax for advanced queries:

```text
filter=alert.attributes.tags:"production"
```

## Lifecycle Operations

```bash
# Enable
curl -X POST ".../api/alerting/rule/{id}/_enable" -H "kbn-xsrf: true"

# Disable
curl -X POST ".../api/alerting/rule/{id}/_disable" -H "kbn-xsrf: true"

# Mute all alerts
curl -X POST ".../api/alerting/rule/{id}/_mute_all" -H "kbn-xsrf: true"

# Mute specific alert
curl -X POST ".../api/alerting/rule/{rule_id}/alert/{alert_id}/_mute" -H "kbn-xsrf: true"

# Delete
curl -X DELETE ".../api/alerting/rule/{id}" -H "kbn-xsrf: true"
```

## Terraform Provider

Use the `elasticstack` provider resource `elasticstack_kibana_alerting_rule`.

```hcl
terraform {
  required_providers {
    elasticstack = {
      source  = "elastic/elasticstack"
    }
  }
}

provider "elasticstack" {
  kibana {
    endpoints = ["https://my-kibana:5601"]
    api_key   = var.kibana_api_key
  }
}

resource "elasticstack_kibana_alerting_rule" "cpu_alert" {
  name         = "CPU usage critical"
  consumer     = "stackAlerts"
  rule_type_id = ".index-threshold"
  interval     = "1m"
  enabled      = true

  params = jsonencode({
    index              = ["metrics-*"]
    timeField          = "@timestamp"
    aggType            = "avg"
    a

Related in Backend & APIs