---
title: "Edit an alert rule"
method: PATCH
path: "/api/v1/public/alerts/{alert_id}"
tags: ["Alerts"]
---

# Edit an alert rule

`PATCH /api/v1/public/alerts/{alert_id}`

## Request

- Base URL: `https://app.traceroot.ai`
- URL: `https://app.traceroot.ai/api/v1/public/alerts/{alert_id}`
- Auth: HTTP bearer

Edit an alert's rule in a project the authenticated user can write to.

Requires MEMBER role or higher in the project's workspace (the write
service decides). The patch is validated merged with the stored rule; an
edit to any evaluated field resets the evaluation state, clears an open
page, and re-arms a parked alert — the response reports the first two.

Args:
    request (Request): Incoming request (rate-limit plumbing).
    response (Response): Outgoing response (rate-limit plumbing).
    auth (AccountStampedAuth): Account-scope user auth (session token or
        CLI access JWT); its resolved ``user_id`` becomes the actor.
    alert_id (str): The alert to edit.
    payload (UpdateAlertRequest): The project and the rule fields to change.
    _live (None): Write-path liveness gate (blocks a revoked JWT session).

Returns:
    UpdateAlertResponse: The updated alert, the changed fields, and the
        state flags.

Raises:
    HTTPException: The write service's 400/403/404 verbatim, or a 503
        when its response is ambiguous.

## Path parameters

- `alert_id` string, required

## Request body

- UpdateAlertRequest: Body for editing an alert rule (the ten rule fields, all optional). The write service validates the patch merged with the stored rule; an edit to any evaluated field resets the evaluation state (and clears an open page), which the response reports. Status has its own route.
  - `aggregation` 'sum' | 'avg' | 'count' | 'max' | 'min' | 'p50' | 'p75' | 'p90' | 'p95' | 'p99' | 'uniq'
  - `filters` AlertFilterItemRequest[]: Row predicates the measure is evaluated over
    - `field` string, required: A span field, e.g. model_name or metadata
    - `key` string: The map entry to compare; required for the metadata field
    - `op` '=' | 'contains', required
    - `value` union, required
      - string
      - number
  - `measure` string: A measure of the view, e.g. latency, cost, count
  - `name` string
  - `no_data_mode` 'HOLD' | 'ZERO' | 'NOTIFY': What a window that measured nothing means
  - `project_id` string, required
  - `renotify` AlertRenotifyRequest: How often an alert re-notifies while it stays in the alerting state.
    - `interval_minutes` integer: Minutes between repeat notifications; required when mode is EVERY
    - `mode` 'OFF' | 'EVERY', required
  - `threshold` number
  - `threshold_operator` '>' | '>=' | '<' | '<=' | '=' | '!='
  - `view` 'SPANS'
  - `window` '1m' | '5m' | '10m' | '30m' | '1h' | '2h'

## Response `200`

Successful Response

- UpdateAlertResponse: The updated alert with its full rule, plus what the edit did to its state.
  - `alert` AlertDetail, required: One alert with its full rule: the summary plus filters and gap handling.
    - `aggregation` string, required
    - `alerted_at` string, date-time, nullable, required
    - `create_time` string, date-time, required
    - `creator` string, nullable, required
    - `filters` AlertFilterItem[], required
      - `field` string, required
      - `key` string, nullable
      - `op` '=' | 'contains', required
      - `value` union, required
        - string
        - number
    - `id` string, required
    - `last_error` string, nullable, required
    - `last_error_at` string, date-time, nullable, required
    - `last_evaluated_at` string, date-time, nullable, required
    - `last_notify_at` string, date-time, nullable, required
    - `last_notify_error` string, nullable, required
    - `last_notify_status` string, nullable, required
    - `measure` string, required
    - `name` string, required
    - `no_data_mode` string, required
    - `renotify` AlertRenotify, required: How often an alert re-notifies while it stays in the alerting state. Kept a single-level object rather than a discriminated union, matching the request-side shape. The cross-field rule is enforced by a validator instead, so a contradictory stored rule fails the detail read closed rather than passing through half-typed.
      - `interval_minutes` integer, nullable
      - `mode` 'OFF' | 'EVERY', required
    - `severity` string, required
    - `severity_changed_at` string, date-time, nullable, required
    - `status` string, required
    - `threshold` number, required
    - `threshold_operator` string, required
    - `update_time` string, date-time, required
    - `view` string, required
    - `window` string, required
  - `changed` string[], required
  - `page_cleared` boolean: True when the alert was firing and the edit discarded that page
  - `state_reset` boolean: True when the edit voided the evaluation state and made the rule due now (any evaluated field changed, or the alert was resumed)
  - `updated` boolean, required

## Other responses

- `400`: Invalid request
- `401`: Authentication failed or session revoked
- `403`: Insufficient role or wrong credential kind
- `404`: Not found
- `422`: Validation Error
- `503`: Write service unavailable

---

[API](https://skmtc.dev/traceroot/apis/traceroot-public-api.md) - [All operations](https://skmtc.dev/traceroot/apis/traceroot-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/traceroot/apis/traceroot-public-api/revisions/ce6aef96c0d6?raw)
