---
title: "Update an existing anomaly detection configuration"
method: PUT
path: "/api/{org_id}/anomaly_detection/{config_id}"
tags: ["Anomaly Detection"]
---

# Update an existing anomaly detection configuration

`PUT /api/{org_id}/anomaly_detection/{config_id}`

## 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/{config_id}`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/openobserve/apis/openobserve-api-http/docs/api/:org_id/anomaly_detection/:config_id/put.ts> (a function with typed inputs; its response is checked against the schema)

## Path parameters

- `org_id` string, required
- `config_id` string, required

## Request body

- UpdateAnomalyConfigRequest: A new `query_mode`, `filters`, `custom_sql`, `detection_function` or `histogram_interval` resets the model, and detection pauses until retraining ends; an unchanged value does not.
  - `alert_budget_per_day` number, double, nullable: Double-option like `priority`: `None` leaves the stored budget, `Some(None)` clears it (back to the trained k), `Some(Some(b))` sets it. A plain Option could never clear.
  - `alert_destinations` string[], nullable
  - `alert_direction` string, nullable: `both`, `above` or `below`; `null` clears to both.
  - `alert_enabled` boolean, nullable
  - `alert_window_buckets` integer, nullable: Window-share length in buckets, at least 1 and at most 24h of buckets; `null` clears to 1.
  - `alert_window_fire_pct` number, double, nullable: Percent of the window out of band that fires; `null` clears to 100.
  - `alert_window_recover_pct` number, double, nullable: Out-of-band percent below which the window recovers; `null` clears to the fire percent.
  - `band_width` number, double, nullable: Double-option like the budget: `null` clears back to the trained k.
  - `custom_sql` string, nullable
  - `description` string, nullable
  - `detection_function` string, nullable
  - `detection_function_field` string, nullable
  - `detection_window_seconds` integer, nullable: 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, nullable
  - `level_half_width_seconds` integer, nullable: Accepted and stored, but ignored by the band model.
  - `name` string, nullable
  - `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: Double-option so "absent" and "explicit null" stay distinguishable (same shape as `TimedAnnotationUpdate::end_time`): * `None` — field not supplied, leave the stored value * `Some(None)` — clear the priority * `Some(Some(p))` — set it A plain `Option` cannot express "clear", which made priority the only field on an anomaly config that could be set but never unset — and inconsistent with alerts, where clearing works.
  - `query_mode` string, nullable
  - `retrain_interval_days` integer, nullable
  - `schedule_interval` string, nullable: At least 1 minute; a stored row below it runs every minute.
  - `tags` string[], nullable: `None` leaves stored tags untouched; `Some(vec![])` clears them.
  - `template` string, nullable: Absent leaves the stored override; null or "" clears it.
  - `training_window_days` integer, nullable: At most 3,000,000 histogram buckets; a stored row over the limit trains clamped to it.

## Response `200`

Success

- AnomalyConfigResponse

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found
- `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)
