---
title: "Create a new anomaly detection configuration"
method: POST
path: "/api/{org_id}/anomaly_detection"
tags: ["Anomaly Detection"]
---

# Create a new anomaly detection configuration

`POST /api/{org_id}/anomaly_detection`

## Request

- Base URL: `https://api.openobserve.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.openobserve.ai/api/{org_id}/anomaly_detection`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/openobserve/apis/openobserve-api-http/docs/api/:org_id/anomaly_detection/post.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `org_id` string, required

## Request body

- CreateAnomalyConfigRequest
  - `alert_budget_per_day` number, double, nullable: Delivered-alert budget per day; mutually exclusive with `percentile` in one request.
  - `alert_destinations` string[]
  - `alert_direction` string, nullable: `both`, `above` or `below`; absent means both.
  - `alert_enabled` boolean, nullable
  - `alert_window_buckets` integer, nullable: Window-share length in buckets, at least 1 and at most 24h of buckets; absent means 1.
  - `alert_window_fire_pct` number, double, nullable: Percent of the window out of band that fires; absent means 100.
  - `alert_window_recover_pct` number, double, nullable: Percent of the window out of band below which it recovers; absent means the fire percent.
  - `band_width` number, double, nullable: Manual band half-width k in sigmas, 1 to 10; absent uses the trained k (3 to 6).
  - `custom_sql` string, nullable
  - `description` string, nullable
  - `detection_function` string, required
  - `detection_function_field` string, nullable
  - `detection_window_seconds` integer, required: At most 100,000 histogram buckets; a stored row over the limit runs clamped to it.
  - `enabled` boolean, nullable
  - `filters` unknown
  - `folder_id` string, nullable
  - `histogram_interval` string, required
  - `level_half_width_seconds` integer, nullable: Accepted and stored, but ignored by the band model.
  - `name` string, required
  - `owner` string, nullable
  - `percentile` number, double, nullable: Legacy, read back as `threshold` for read-modify-write; k trains at p99, within 3 to 6.
  - `priority` integer, nullable: Triage priority P1..P5 (Feature 2, PT-1). Anomaly configs appear in the same alert list as scheduled/realtime alerts, so they carry the same metadata. Absent = unset.
  - `query_mode` string, required
  - `rcf_num_trees` integer, nullable
  - `rcf_shingle_size` integer, nullable
  - `rcf_tree_size` integer, nullable
  - `retrain_interval_days` integer, nullable
  - `schedule_interval` string, required: At least 1 minute; a stored row below it runs every minute.
  - `stream_name` string, required: The stream the detector reads. Required in filters mode. In custom_sql mode it can be left blank when the SQL reads exactly one stream, which then names it.
  - `stream_type` string, required
  - `tags` string[]: Selection tags (PT-6), normalized and validated on save exactly as for alerts — one `normalize_tags` serves both.
  - `template` string, nullable: Template override for this config's messages; absent, null or "" uses the destination's.
  - `training_window_days` integer, nullable: At most 3,000,000 histogram buckets; a stored row over the limit trains clamped to it.

## Response `200`

Created

- AnomalyConfigResponse

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `500`: Internal Server Error

---

[API](https://skmtc.dev/openobserve/apis/openobserve-api-http.md) - [All operations](https://skmtc.dev/openobserve/apis/openobserve-api-http/llms.txt) - [OpenAPI document](https://skmtc.dev/openobserve/apis/openobserve-api-http/revisions/0529b8a10252?raw)
