---
title: "Create rules in bulk"
method: POST
path: "/api/alerting/v2/rules/_bulk_create"
tags: ["alerting-v2"]
---

# Create rules in bulk

`POST /api/alerting/v2/rules/_bulk_create`

**Spaces method and path for this operation:**

<div><span class="operation-verb post">post</span>&nbsp;<span class="operation-path">/s/{space_id}/api/alerting/v2/rules/_bulk_create</span></div>

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

Creates up to 100 rules in a single request. Each item can include a client-supplied `id`. Kibana generates an identifier when `id` is omitted. The request succeeds with HTTP 200 even when some rules fail. Created rules are returned in `items`. Failures are returned in `errors`. Check `errors` before treating the request as fully successful. To create a single rule, use POST /api/alerting/v2/rules.<br/><br/>[Required authorization] Route required privileges: manage_alerting-v2-rules.

## Headers

- `kbn-xsrf` string, required

## Request body

- KibanaHTTPAPIsAlertingBulkCreateRulesRequest
  - `rules` KibanaHTTPAPIsAlertingBulkCreateRuleItem[], required — The rules to create. Must contain between 1 and 100 rules.
    - `artifacts` KibanaHTTPAPIsAlertingRuleArtifact[] — 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.
      - `data` object, required — Structured artifact data.
      - `id` string, required — Artifact identifier.
      - `type` string, required — Artifact type.
    - `enabled` boolean — If `true` (default), the rule runs on its schedule after creation. If `false`, the rule is saved but does not run until you enable it.
    - `grouping` KibanaHTTPAPIsAlertingRuleGrouping — Grouping configuration.
      - `fields` string[], required — Fields to group alerts by, e.g. ["host.name", "service.name"]. Should match ES|QL GROUP BY fields.
    - `id` string — Optional rule ID. If omitted, Kibana generates one. IDs in the request must be unique.
    - `kind` union, required — Whether the rule creates alerts (`alert`) or only stores matching events (`signal`).
      - 'alert' — Creates an alert for each matching group and tracks it until it recovers. Use this when you want to detect a problem and notify or automate a response.
      - 'signal' — Stores each match as a rule event you can query. Alerts are not created and notifications are not sent.
    - `metadata` KibanaHTTPAPIsAlertingRuleMetadata, required — Rule metadata.
      - `builder_type` string — Identifies the rule builder that authored this rule (e.g. "threshold"). Absent for rules authored directly in ES|QL.
      - `description` string — Human-readable description of the rule.
      - `name` string, required — Rule name (must be unique within the space).
      - `tags` string[] — Tags for categorization, e.g. ["production", "infra"].
    - `no_data_strategy` union — How the rule behaves when it finds no data for a group. If you omit this field or set it to `none`, those runs are ignored. If you set `last_known_status` or `recover`, a standalone query (`query.format: standalone`) must include `query.no_data`. A composed query (`query.format: composed`) uses `query.base` to detect whether data is present. The `emit` value is not accepted when creating or updating rules.
      - 'last_known_status' — Keeps the alert's last status when the rule finds no data.
      - 'emit' — Not accepted when creating or updating rules. Do not send this value.
      - 'recover' — Marks the alert `inactive` the first time the rule finds no data for the alert.
      - 'none' — Ignores runs where the rule finds no data.
    - `query` union, required — Detection query configuration.
      - KibanaHTTPAPIsAlertingComposedRuleQuery — Composed query: a shared base with appendable breach and recovery segments.
        - `base` string, required — Base ES|QL query. Time filters are applied automatically via the lookback window.
        - `breach` object — Breach detection configuration. Omit to treat every base row as a breach.
          - `segment` string, required — A clause appended to the end of the rule's ES|QL query. Required in breach blocks.
        - `format` 'composed', required
        - `recovery` object — Recovery query segment. Required when recovery_strategy is "query".
          - `segment` string, required — Appendable ES|QL segment for recovery detection.
      - KibanaHTTPAPIsAlertingStandaloneRuleQuery — Standalone queries: independent full queries for breach, recovery, and no_data.
        - `breach` object, required — Breach detection configuration (required).
          - `query` string, required — Full ES|QL query for breach detection (required).
        - `format` 'standalone', required
        - `no_data` object — No-data detection query. Required when no_data_strategy is not "none".
          - `query` string, required — Full ES|QL query that detects presence of data.
        - `recovery` object — Recovery query. Required when recovery_strategy is "query".
          - `query` string, required — Full ES|QL query for recovery detection.
    - `recovery_strategy` union — The condition that marks an alert recovered. If omitted or set to `none`, recovery is disabled: the alert stays `active` even after the breach query stops returning matches, and `state_transition.recovering_count` / `recovering_timeframe` are not allowed. Set to `no_breach` to recover when the breach query stops returning matches. Set to `query` only when you also provide `query.recovery`.
      - 'no_breach' — Recovers an alert when the breach query no longer returns matches.
      - 'query' — Recovers an alert when a separate recovery query matches. Requires `query.recovery`.
      - 'none' — The rule never marks an alert as `recovered`, even after the breach query stops returning matches.
    - `schedule` KibanaHTTPAPIsAlertingRuleSchedule, required — Execution schedule configuration.
      - `every` string, required — Execution interval, e.g. 1m, 5m, 1h.
      - `lookback` string — Lookback window for the query, e.g. 5m, 1h. Can also be expressed in ES|QL.
    - `state_transition` object, nullable — Consecutive-match or time requirements before an alert becomes `active` or `inactive`. Applies only when `kind` is `alert`.
      - `pending_count` integer — Number of consecutive matches required before the alert becomes `active`.
      - `pending_operator` 'and' | 'or' — The operator that combines `pending_count` and `pending_timeframe`. `and` requires both. `or` requires either.
      - `pending_timeframe` string — Time window used with `pending_count`, for example `5m` or `15m`.
      - `recovering_count` integer — Number of consecutive recoveries required before the alert becomes `inactive`.
      - `recovering_operator` 'and' | 'or' — The operator that combines `recovering_count` and `recovering_timeframe`. `and` requires both. `or` requires either.
      - `recovering_timeframe` string — Time window used with `recovering_count`, for example `5m` or `15m`.
    - `time_field` string — Document field used as the event time when applying the lookback window. Defaults to `@timestamp`.

## Response `200`

Created rules are returned in `items`. Failures are returned in `errors`.

- KibanaHTTPAPIsAlertingBulkCreateRulesResponse
  - `errors` object[], required — Errors for rules that could not be created. Each entry includes the rule `id` and the error. Empty when every requested rule was created.
    - `error` object, required
      - `code` string, required — Stable error code you can branch on, for example `INVALID_SCHEDULE` or `RULE_ALREADY_EXISTS`.
      - `details` object — Optional extra information about the error, for example field validation issues or the `rule_id` when that ID already exists.
      - `message` string, required — A readable explanation of the error. The wording can change without notice. Do not parse this field.
    - `id` string, required — The identifier of the resource that failed.
  - `items` KibanaHTTPAPIsAlertingRuleResponse[], required — Rules that were created. Rules listed in `errors` are not included.
    - `artifacts` KibanaHTTPAPIsAlertingRuleArtifact[] — 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.
      - `data` object, required — Structured artifact data.
      - `id` string, required — Artifact identifier.
      - `type` string, required — Artifact type.
    - `created_at` string, date-time, required — ISO timestamp when the rule was created.
    - `created_by` KibanaHTTPAPIsAlertingActor, required — Identity that performed the write.
      - `profile_uid` string, nullable, required — User profile ID of the actor, or `null` when it cannot be resolved.
    - `enabled` boolean, required — Whether the rule is enabled.
    - `grouping` KibanaHTTPAPIsAlertingRuleGrouping — Grouping configuration.
      - `fields` string[], required — Fields to group alerts by, e.g. ["host.name", "service.name"]. Should match ES|QL GROUP BY fields.
    - `id` string, required — Unique rule identifier.
    - `kind` union, required — Whether the rule creates alerts (`alert`) or only stores matching events (`signal`).
      - 'alert' — Creates an alert for each matching group and tracks it until it recovers. Use this when you want to detect a problem and notify or automate a response.
      - 'signal' — Stores each match as a rule event you can query. Alerts are not created and notifications are not sent.
    - `metadata` KibanaHTTPAPIsAlertingRuleResponseMetadata, required
      - `builder_type` string — Identifies the rule builder that authored this rule (e.g. "threshold"). Absent for rules authored directly in ES|QL.
      - `description` string — Human-readable description of the rule.
      - `name` string, required — Rule name (must be unique within the space).
      - `tags` string[] — Tags for categorization, e.g. ["production", "infra"].
      - `version` integer, required — Monotonically increasing integer number representing a rule configuration version, incremented on every change. Used on generated rule events as `rule.version`.
    - `no_data_strategy` union — How the rule behaves when it finds no data for a group. If you omit this field or set it to `none`, those runs are ignored. If you set `last_known_status` or `recover`, a standalone query (`query.format: standalone`) must include `query.no_data`. A composed query (`query.format: composed`) uses `query.base` to detect whether data is present. The `emit` value is not accepted when creating or updating rules.
      - 'last_known_status' — Keeps the alert's last status when the rule finds no data.
      - 'emit' — Not accepted when creating or updating rules. Do not send this value.
      - 'recover' — Marks the alert `inactive` the first time the rule finds no data for the alert.
      - 'none' — Ignores runs where the rule finds no data.
    - `query` union, required — Detection query configuration.
      - KibanaHTTPAPIsAlertingComposedRuleQuery — Composed query: a shared base with appendable breach and recovery segments.
        - `base` string, required — Base ES|QL query. Time filters are applied automatically via the lookback window.
        - `breach` object — Breach detection configuration. Omit to treat every base row as a breach.
          - `segment` string, required — A clause appended to the end of the rule's ES|QL query. Required in breach blocks.
        - `format` 'composed', required
        - `recovery` object — Recovery query segment. Required when recovery_strategy is "query".
          - `segment` string, required — Appendable ES|QL segment for recovery detection.
      - KibanaHTTPAPIsAlertingStandaloneRuleQuery — Standalone queries: independent full queries for breach, recovery, and no_data.
        - `breach` object, required — Breach detection configuration (required).
          - `query` string, required — Full ES|QL query for breach detection (required).
        - `format` 'standalone', required
        - `no_data` object — No-data detection query. Required when no_data_strategy is not "none".
          - `query` string, required — Full ES|QL query that detects presence of data.
        - `recovery` object — Recovery query. Required when recovery_strategy is "query".
          - `query` string, required — Full ES|QL query for recovery detection.
    - `recovery_strategy` union — The condition that marks an alert recovered. If omitted or set to `none`, recovery is disabled: the alert stays `active` even after the breach query stops returning matches, and `state_transition.recovering_count` / `recovering_timeframe` are not allowed. Set to `no_breach` to recover when the breach query stops returning matches. Set to `query` only when you also provide `query.recovery`.
      - 'no_breach' — Recovers an alert when the breach query no longer returns matches.
      - 'query' — Recovers an alert when a separate recovery query matches. Requires `query.recovery`.
      - 'none' — The rule never marks an alert as `recovered`, even after the breach query stops returning matches.
    - `schedule` KibanaHTTPAPIsAlertingRuleSchedule, required — Execution schedule configuration.
      - `every` string, required — Execution interval, e.g. 1m, 5m, 1h.
      - `lookback` string — Lookback window for the query, e.g. 5m, 1h. Can also be expressed in ES|QL.
    - `state_transition` object, nullable — Consecutive-match or time requirements before an alert becomes `active` or `inactive`. Applies only when `kind` is `alert`.
      - `pending_count` integer — Number of consecutive matches required before the alert becomes `active`.
      - `pending_operator` 'and' | 'or' — The operator that combines `pending_count` and `pending_timeframe`. `and` requires both. `or` requires either.
      - `pending_timeframe` string — Time window used with `pending_count`, for example `5m` or `15m`.
      - `recovering_count` integer — Number of consecutive recoveries required before the alert becomes `inactive`.
      - `recovering_operator` 'and' | 'or' — The operator that combines `recovering_count` and `recovering_timeframe`. `and` requires both. `or` requires either.
      - `recovering_timeframe` string — Time window used with `recovering_count`, for example `5m` or `15m`.
    - `time_field` string — Document field used as the event time when applying the lookback window. Defaults to `@timestamp`.
    - `updated_at` string, date-time, required — ISO timestamp when the rule was last updated.
    - `updated_by` KibanaHTTPAPIsAlertingActor, required — Identity that performed the write.
      - `profile_uid` string, nullable, required — User profile ID of the actor, or `null` when it cannot be resolved.
    - `version` string — The saved object version token of the rule, used for optimistic concurrency control.

## Other responses

- `400` — Indicates an invalid schema or parameters.
- `401` — Indicates the request was not authenticated.
- `403` — Indicates the user does not have the required privileges to perform the request.
- `500` — Indicates an unexpected server-side error.
- `503` — Indicates the alerting engine is disabled by the `alerting:v2:enabled` advanced setting.

## Changes

> 176 revisions in range; 20 not diffed.

- **2026-09-17** `883cd57e9ac7` — 4 warning
  - the `rules/items/schedule/every` request property's maxLength was set to `32`
  - the `rules/items/schedule/lookback` request property's maxLength was set to `32`
  - the `rules/items/state_transition/pending_timeframe` request property's maxLength was set to `32`
  - the `rules/items/state_transition/recovering_timeframe` request property's maxLength was set to `32`
- **2026-09-16** `e2104277117c` — 3 breaking, 9 info
  - removed `subschema #1, subschema #2` from the `rules/items/kind` request property `anyOf` list
  - removed `subschema #1, subschema #2, subschema #3` from the `rules/items/recovery_strategy` request property `anyOf` list
  - removed `subschema #1, subschema #2, subschema #3, subschema #4` from the `rules/items/no_data_strategy` request property `anyOf` list
  - added `subschema #1, subschema #2` to the `rules/items/kind` request property `anyOf` list
  - …8 more
- **2026-09-15** `d83bbb7d049a` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/elastic/apis/kibana-apis/changes/api/alerting/v2/rules/_bulk_create/post.md)

---

[API](https://skmtc.dev/elastic/apis/kibana-apis.md) · [All operations](https://skmtc.dev/elastic/apis/kibana-apis/llms.txt) · [OpenAPI document](https://skmtc.dev/elastic/apis/kibana-apis/revisions/84f30e7da461?raw)
