> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashduty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update alert rule (V2)

> Replace an alert rule's V2 configuration in full by ID. Returns the updated rule.

## Restrictions

| Aspect      | Value                                                       |
| ----------- | ----------------------------------------------------------- |
| Rate limits | **300 requests/minute**; **20 requests/second** per account |
| Permissions | **Alerting Rules Manage** (`monit`)                         |

## Usage

* `id` is required and the rule must already exist; otherwise the call returns `InvalidParameter`.
* This is a full-field replacement: except for the cases below, fields you omit are stored as zero values. Fetch the full configuration via `/monit/rule/v2/info` before modifying it.
* `enabled` must be passed explicitly (including `false`); omitting it returns `InvalidParameter`. Setting it to `false` clears the rule's active alerts.
* `investigation_targets` is the exception: omit it to keep the current value, pass `[]` to clear, or pass a value to replace it entirely.
* `folder_id` cannot be changed through this operation; use `/monit/rule/move` to move the rule to another folder.
* `account_id`, `creator_*`, `updater_*`, `created_at`, and `updated_at` are maintained by the server; client-supplied values are ignored.
* `name` must be unique within `folder_id`; a duplicate returns `InvalidParameter`.
* The request body tolerates additional unknown fields (forward compatibility); they are ignored.
* Every call is recorded in the account audit log. Don't put secrets in request fields.


## OpenAPI

````yaml /api-reference/monitors.openapi.en.json post /monit/rule/v2/update
openapi: 3.1.0
info:
  title: Flashduty Open API
  description: >-
    Public HTTP API for the Flashduty incident management platform — incidents,
    notification templates, channels, schedules, monitors, RUM, and platform
    administration. Every operation is authenticated with an `app_key` query
    parameter issued from the Flashduty console under Account → APP Keys.
    Responses follow a uniform envelope: `{ request_id, data }` on success, `{
    request_id, error }` on failure.
  version: 1.0.0
servers:
  - url: https://api.flashcat.cloud
    description: Flashduty Open API
security:
  - AppKeyAuth: []
tags:
  - name: Monitors/Alert rules
    description: >-
      Create, manage, and export monitor alert rules. Query rule counters and
      audit history.
  - name: Monitors/Data sources
    description: Manage monitoring data sources used by alert rules to query metrics.
  - name: Monitors/Diagnostics
    description: >-
      Diagnostic and query endpoints used by Flashduty AI SRE — ad-hoc data
      source queries, log/metric diagnostics, and target-side tool invocation.
  - name: Monitors/Monitor utilities
    description: Monitors service activation and data preview utilities.
paths:
  /monit/rule/v2/update:
    post:
      tags:
        - Monitors/Alert rules
      summary: Update alert rule (V2)
      description: >-
        Replace an alert rule's V2 configuration in full by ID. Returns the
        updated rule.
      operationId: monit-rule-write-update-v2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AlertRuleV2'
            example:
              folder_id: 100
              name: CPU High
              ds_type: prometheus
              ds_list:
                - prometheus*
              enabled: true
              cron_pattern: 0 * * * * *
              channel_ids:
                - 20001
              rule_configs:
                queries:
                  - name: A
                    expr: 100 - avg(cpu_usage_idle)
                check_threshold:
                  enabled: true
                  alerting_check_times: 3
                  alerting_window_size: 5
                  recovery_check_times: 2
                  critical: $A > 95
                  warning: $A > 80
                  recovery_mode: condition_clear
              id: 50001
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessEnvelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/AlertRuleV2'
              example:
                request_id: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
                data:
                  id: 50001
                  account_id: 888
                  folder_id: 100
                  name: CPU High
                  labels: {}
                  ds_type: prometheus
                  ds_list:
                    - prometheus*
                  ds_ids: []
                  enabled: true
                  debug_log_enabled: false
                  rule_configs:
                    queries:
                      - name: A
                        expr: 100 - avg(cpu_usage_idle)
                    check_threshold:
                      enabled: true
                      alerting_check_times: 3
                      alerting_window_size: 5
                      recovery_check_times: 2
                      critical: $A > 95
                      warning: $A > 80
                      recovery_mode: condition_clear
                  cron_pattern: 0 * * * * *
                  timezone: Asia/Shanghai
                  delay_seconds: 0
                  enabled_times:
                    - days:
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
                        - 6
                        - 0
                      stime: '00:00'
                      etime: '23:59'
                  annotations: {}
                  description_type: text
                  description: ''
                  channel_ids:
                    - 20001
                  repeat_interval: 3600
                  repeat_total: 3
                  investigation_targets: []
                  creator_id: 66
                  creator_name: zhangsan
                  updater_id: 66
                  updater_name: zhangsan
                  created_at: 1712000000
                  updated_at: 1712003600
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    AlertRuleV2:
      type: object
      description: >-
        Complete V2 alert rule configuration. The core difference from V1 lives
        in `rule_configs`: the three checkers describe recovery and ending
        semantics with the lifecycle v2 `recovery_mode`/`end_mode` enums.
      properties:
        id:
          type: integer
          format: uint64
          description: >-
            Rule ID. Required on update; omit on create (assigned by the
            server).
        account_id:
          type: integer
          format: uint64
          description: >-
            Account ID, filled by the server from the authentication context;
            any client-supplied value is ignored.
        folder_id:
          type: integer
          format: uint64
          description: >-
            ID of the folder the rule belongs to; list folders via `POST
            /monit/folder/list`. Cannot be changed through the update API — use
            `/monit/rule/move` instead.
        name:
          type: string
          description: >-
            Rule name. Must be unique within the folder and at most 128
            characters.
        labels:
          type: object
          additionalProperties:
            type: string
          description: Custom labels.
        ds_type:
          type: string
          description: Datasource type identifier (e.g. `prometheus`, `elasticsearch`).
        ds_list:
          type: array
          items:
            type: string
          description: >-
            Datasource name match patterns (wildcards supported). At least one
            of `ds_list` / `ds_ids` must be non-empty; both are merged to decide
            which datasources the rule monitors.
        ds_ids:
          type: array
          items:
            type: integer
            format: uint64
          description: >-
            Datasource ID list, merged with `ds_list` to decide the monitored
            datasources; IDs survive datasource renames. At least one of
            `ds_list` / `ds_ids` must be provided.
        enabled:
          type: boolean
          description: >-
            Whether the rule is enabled. Required — the server enforces an
            explicit value (including `false`) while decoding. Setting it to
            `false` on update clears the rule's active alerts.
        debug_log_enabled:
          type: boolean
          description: >-
            Enable debug logging; the edge then emits detailed evaluation logs
            for this rule, useful when the rule does not trigger as expected.
        rule_configs:
          $ref: '#/components/schemas/AlertRuleConfigsV2'
          description: >-
            Detection configuration: query list plus trigger/recovery
            conditions. See `AlertRuleConfigsV2`.
        cron_pattern:
          type: string
          description: >-
            Schedule expression: a 6-field cron (with seconds) or an `@every
            30s` interval. Must not start with `CRON_TZ=` or `TZ=`; set the
            timezone in the `timezone` field instead.
        timezone:
          type: string
          default: Asia/Shanghai
          description: >-
            Timezone the rule runs in; it decides how the cron schedule and
            enabled time windows are interpreted. Only IANA names are accepted
            (e.g. `Asia/Shanghai`, `UTC`, `Europe/London`); abbreviations or
            offsets like `Local`, `UTC+8`, `CST` are rejected. Empty falls back
            to `Asia/Shanghai`.
        delay_seconds:
          type: integer
          description: >-
            Seconds the evaluation query window is shifted back, compensating
            for data ingestion latency.
        enabled_times:
          type: array
          description: >-
            Time windows during which the rule is in effect. When omitted or
            empty, the rule is active 00:00–23:59 every day.
          default:
            - days:
                - 1
                - 2
                - 3
                - 4
                - 5
                - 6
                - 0
              stime: '00:00'
              etime: '23:59'
          items:
            type: object
            properties:
              days:
                type: array
                items:
                  type: integer
                description: Days of week (0=Sunday).
              stime:
                type: string
                description: Start time, e.g. `09:00`.
              etime:
                type: string
                description: End time, e.g. `18:00`.
        annotations:
          type: object
          additionalProperties:
            type: string
          description: >-
            Extra annotation key-value pairs delivered with alert events; keys
            must not start with `$` (reserved for query fields).
        description_type:
          type: string
          enum:
            - text
            - markdown
          default: text
          description: >-
            Format of the description content. Empty or omitted defaults to
            `text`. `text` = plain text; `markdown` = Markdown, rendered as such
            in alert details.
        description:
          type: string
          description: Rule description, Markdown format.
        channel_ids:
          type: array
          items:
            type: integer
            format: uint64
          description: >-
            Collaboration space IDs alerts are sent to. May be empty; alerts
            then route through the global integration.
        repeat_interval:
          type: integer
          format: int64
          description: >-
            Notification repeat interval in seconds. Values below 1 fall back to
            the default 3600.
        repeat_total:
          type: integer
          format: int64
          description: >-
            Maximum number of repeat notifications. Values below 1 fall back to
            the default 3.
        investigation_targets:
          type: array
          items:
            $ref: '#/components/schemas/InvestigationTarget'
          description: >-
            Drill-down entries linked from the alert event detail page; at most
            20 items, duplicates rejected. On update the field is
            presence-based: omit it to keep the current value, pass `[]` to
            clear.
          x-flashduty-preserve-absence: true
        creator_id:
          type: integer
          format: uint64
          description: >-
            Creator member ID, filled by the server from the current user; any
            client-supplied value is ignored.
        creator_name:
          type: string
          description: >-
            Creator name, filled by the server; any client-supplied value is
            ignored.
        updater_id:
          type: integer
          format: uint64
          description: >-
            ID of the member who last updated the rule, filled by the server;
            any client-supplied value is ignored.
        updater_name:
          type: string
          description: >-
            Name of the member who last updated the rule, filled by the server;
            any client-supplied value is ignored.
        created_at:
          type: integer
          format: int64
          description: >-
            Creation time as a Unix timestamp in seconds, generated by the
            server; any client-supplied value is ignored.
        updated_at:
          type: integer
          format: int64
          description: >-
            Last update time as a Unix timestamp in seconds, generated by the
            server; any client-supplied value is ignored.
      required:
        - folder_id
        - name
        - ds_type
        - enabled
        - cron_pattern
        - rule_configs
    SuccessEnvelope:
      type: object
      description: >-
        Success response envelope. On every 2xx response, `request_id`
        identifies the call (also mirrored in the `Flashcat-Request-Id` header)
        and `data` holds the endpoint-specific payload. Failure responses use a
        different shape — see `ErrorResponse`.
      properties:
        request_id:
          type: string
          description: >-
            Unique ID for this request. Mirrored in the Flashcat-Request-Id
            response header. Include it when reporting issues.
          example: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
        data:
          description: Endpoint-specific payload. See each operation's 200 response schema.
      required:
        - request_id
        - data
    AlertRuleConfigsV2:
      type: object
      description: V2 rule evaluation configuration.
      properties:
        queries:
          type: array
          description: >-
            Query list with at least one entry; each needs a unique `name` (`R`
            and `__all__` are reserved) and a non-empty, non-duplicated `expr`.
          items:
            type: object
            properties:
              name:
                type: string
                description: >-
                  Query identifier (e.g. `A`), must match
                  `[A-Za-z][A-Za-z0-9_]*`; `R` and `__all__` are reserved and
                  cannot be used.
              expr:
                type: string
                description: Query expression.
              label_fields:
                type: array
                items:
                  type: string
                description: >-
                  Result fields used as alert event labels; rows with the same
                  label set form one alert. Must not overlap `value_fields`;
                  applies to tabular results (SQL/ES-like datasources).
              value_fields:
                type: array
                items:
                  type: string
                description: >-
                  Numeric result fields evaluated by threshold expressions
                  (referenced as `$A.<field>`); required for threshold checks
                  when the datasource is not `prometheus`/`loki`/`victorialogs`.
                  Field names must not contain `.`.
              args:
                type: object
                additionalProperties:
                  type: string
                description: >-
                  Datasource-specific query parameters; keys follow the
                  `<datasource>.<param>` convention (e.g. `es.type`,
                  `tencent_cls.limit`). Most datasources need none.
        relate_queries:
          type: array
          description: >-
            Optional auxiliary queries whose results attach to alert events as
            context. Each entry needs a unique `name` (not colliding with any
            query name) and a non-empty `expr`.
          items:
            type: object
            properties:
              name:
                type: string
                description: Auxiliary query identifier.
              expr:
                type: string
                description: Query expression.
              args:
                type: object
                additionalProperties:
                  type: string
                description: >-
                  Datasource-specific parameters for the auxiliary query; same
                  convention as `queries[].args`.
        check_threshold:
          $ref: '#/components/schemas/AlertRuleThresholdV2'
          description: Threshold check configuration. See `AlertRuleThresholdV2`.
        check_anydata:
          $ref: '#/components/schemas/AlertRuleAnyDataV2'
          description: >-
            Any-data check configuration: fires when a query returns any data
            row. See `AlertRuleAnyDataV2`.
        check_nodata:
          $ref: '#/components/schemas/AlertRuleNoDataV2'
          description: No-data check configuration. See `AlertRuleNoDataV2`.
      required:
        - queries
    InvestigationTarget:
      type: object
      description: >-
        Drill-down entry linked to alert events. A deliberately closed tagged
        union: new kinds require explicit server support.
      properties:
        kind:
          type: string
          enum:
            - dashboard
          description: Entry type; currently only `dashboard` is supported.
        dashboard:
          $ref: '#/components/schemas/DashboardInvestigationTarget'
          description: >-
            Configuration for the `dashboard` kind; required when `kind` is
            `dashboard`.
      required:
        - kind
    ErrorResponse:
      type: object
      description: Response envelope for errors. `error` is required; `data` is absent.
      properties:
        request_id:
          type: string
          example: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
          description: >-
            Unique trace ID of this request; include it when reporting issues so
            logs can be located.
        error:
          $ref: '#/components/schemas/DutyError'
      required:
        - request_id
        - error
    AlertRuleThresholdV2:
      type: object
      description: Threshold check configuration (lifecycle v2).
      properties:
        enabled:
          type: boolean
          description: Whether the threshold check is enabled.
        alerting_check_times:
          type: integer
          description: >-
            Fire after the alert condition is met this many times; when enabled,
            minimum 1 and maximum 10000. Combined with `alerting_window_size` it
            means at least N hits within the last M evaluations.
        alerting_window_size:
          type: integer
          description: >-
            Optional sliding window size M: fire only when the condition is met
            at least `alerting_check_times` times within the last M evaluations.
            Omit for consecutive mode (N consecutive hits). Must satisfy
            `alerting_check_times` <= M <= 10000.
        recovery_check_times:
          type: integer
          description: >-
            Recover after the recovery condition is met this many times; minimum
            1 when enabled.
        critical:
          type: string
          description: >-
            Critical threshold expression referencing query results as
            `$<query>` or `$<query>.<value_field>`, e.g. `$A > 90`; when enabled
            at least one of the three severities must be set.
        warning:
          type: string
          description: Warning threshold expression; same syntax as `critical`.
        info:
          type: string
          description: Info threshold expression; same syntax as `critical`.
        recovery_mode:
          type: string
          enum:
            - condition_clear
            - expression_match
            - recovery_query_match
            - manual
          description: >-
            How recovery is decided (lifecycle v2); required when enabled.
            `condition_clear` = recover once the alert expression no longer
            holds; `recovery` is not allowed. `expression_match` = recover when
            the `recovery.expr` threshold expression holds.
            `recovery_query_match` = recover when the `recovery.expr` query
            expression evaluates true. `manual` = never recover automatically;
            alerts need manual handling, no recovery event is pushed, and
            `recovery` is not allowed.
        recovery:
          $ref: '#/components/schemas/AlertRuleRecoveryQueryV2'
          description: >-
            Recovery evaluation config. Required (with non-empty
            `recovery.expr`) only when `recovery_mode` is `expression_match` or
            `recovery_query_match`; must be omitted for the other modes.
    AlertRuleAnyDataV2:
      type: object
      description: >-
        Any-data check configuration (lifecycle v2). Fires when a query returns
        any data row.
      properties:
        enabled:
          type: boolean
          description: >-
            Whether the any-data check is enabled: any returned data row
            triggers an alert.
        alerting_check_times:
          type: integer
          description: >-
            Fire after the alert condition is met this many times; when enabled,
            minimum 1 and maximum 10000. Combined with `alerting_window_size` it
            means at least N hits within the last M evaluations.
        alerting_window_size:
          type: integer
          description: >-
            Optional sliding window size M: fire only when the condition is met
            at least `alerting_check_times` times within the last M evaluations.
            Omit for consecutive mode. Must satisfy `alerting_check_times` <= M
            <= 10000.
        recovery_check_times:
          type: integer
          description: >-
            Recover after the recovery condition is met this many times; minimum
            1 when enabled.
        severity:
          type: string
          enum:
            - Critical
            - Warning
            - Info
          description: Severity of any-data alerts, case-sensitive; required when enabled.
        recovery_mode:
          type: string
          enum:
            - data_absent
            - recovery_query_match
            - manual
          description: >-
            How recovery is decided (lifecycle v2); required when enabled.
            `data_absent` = recover when the query returns no data; `recovery`
            is not allowed. `recovery_query_match` = recover when the
            `recovery.expr` query expression evaluates true; only a single query
            (`name=A`) is allowed. `manual` = never recover automatically;
            alerts need manual handling, no recovery event is pushed, and
            `recovery` is not allowed.
        recovery:
          $ref: '#/components/schemas/AlertRuleRecoveryQueryV2'
          description: >-
            Recovery evaluation config. Required (with non-empty
            `recovery.expr`) only when `recovery_mode` is
            `recovery_query_match`; must be omitted for the other modes.
    AlertRuleNoDataV2:
      type: object
      description: No-data check configuration (lifecycle v2).
      properties:
        enabled:
          type: boolean
          description: >-
            Whether the per-series no-data check is enabled: series that
            previously reported data trigger an alert when data disappears.
        severity:
          type: string
          enum:
            - Critical
            - Warning
            - Info
          description: >-
            Severity of no-data alerts, case-sensitive; required when the
            per-series check is enabled.
        alert_on_empty_result:
          type: boolean
          description: >-
            Whether to alert when all queries return empty results (global
            empty-result check).
        alert_on_empty_result_severity:
          type: string
          enum:
            - Critical
            - Warning
            - Info
          description: >-
            Severity of empty-result alerts, case-sensitive; only takes effect
            and is required when `alert_on_empty_result` is on.
        alerting_check_times:
          type: integer
          description: >-
            Fire after the alert condition is met this many times; when enabled,
            minimum 1 and maximum 10000. Combined with `alerting_window_size` it
            means at least N hits within the last M evaluations.
        alerting_window_size:
          type: integer
          description: >-
            Optional sliding window size M: fire only when the condition is met
            at least `alerting_check_times` times within the last M evaluations.
            Omit for consecutive mode. Must satisfy `alerting_check_times` <= M
            <= 10000.
        recovery_check_times:
          type: integer
          description: >-
            Recover after the recovery condition is met this many times; minimum
            1 when enabled.
        end_mode:
          type: string
          enum:
            - data_reappears
            - data_reappears_or_timeout
            - manual
          description: >-
            How a no-data alert ends (lifecycle v2); required when enabled.
            `data_reappears` = recover when data reappears.
            `data_reappears_or_timeout` = end when data reappears or after
            `auto_close_after_seconds` seconds, whichever comes first; requires
            the per-series no-data check and a positive
            `auto_close_after_seconds`. `manual` = never end automatically;
            alerts need manual handling and no recovery event is pushed. For
            `data_reappears` and `manual`, `auto_close_after_seconds` must be 0.
        auto_close_after_seconds:
          type: integer
          format: int64
          description: >-
            Seconds to wait before auto-closing. Allowed and required to be
            positive only when `end_mode` is `data_reappears_or_timeout`; must
            be 0 for the other modes.
    DashboardInvestigationTarget:
      type: object
      description: Configuration of a dashboard drill-down entry.
      properties:
        dashboard_id:
          type: string
          description: Target dashboard ID; must be a canonical UUIDv7.
        target_id:
          type: string
          description: Panel ID inside the dashboard; must be a canonical UUIDv7. Optional.
        variable_bindings:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/InvestigationVariableBinding'
          description: Dashboard variable bindings, keyed by dashboard variable name.
      required:
        - dashboard_id
    DutyError:
      type: object
      description: >-
        Error payload inside the response envelope. Present only on non-2xx
        responses.
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: >-
            Human-readable error message, localized by the caller's
            Accept-Language. May contain field names, IDs, or other context from
            the failing request.
          example: The specified parameter template_id is not valid.
        reason:
          description: >-
            Optional machine-readable rejection reason, including datasource
            tool failures. Inspect alongside HTTP status and code.
          type: string
          x-flashduty-preserve-absence: true
      required:
        - code
        - message
    AlertRuleRecoveryQueryV2:
      type: object
      description: Recovery evaluation configuration for lifecycle v2.
      properties:
        expr:
          type: string
          description: >-
            Recovery condition expression: a threshold expression (e.g. `$A <
            90`) in `expression_match` mode, a query expression in
            `recovery_query_match` mode. Required and non-empty when the
            corresponding mode is enabled.
        value_fields:
          type: array
          items:
            type: string
          description: >-
            Numeric result fields the recovery expression references as
            `$A.<field>`; same semantics as a query's `value_fields`. Not
            returned when empty.
        args:
          type: object
          additionalProperties:
            type: string
          description: >-
            Datasource-specific parameters for the recovery query; keys follow
            the same `<datasource>.<param>` convention as a query's `args`. Not
            returned when empty.
    InvestigationVariableBinding:
      type: object
      description: Binding between a dashboard variable and alert event data.
      properties:
        source:
          type: string
          enum:
            - event_label
          description: >-
            Where the bound value comes from; currently only `event_label` (the
            alert event's label value) is supported.
        key:
          type: string
          description: >-
            Alert event label name; must follow Prometheus label naming rules
            and must not be a reserved label.
      required:
        - source
        - key
    ErrorCode:
      type: string
      description: >-
        Flashduty error code enum. Every failed API response sets `error.code`
        to one of these stable wire strings. HTTP status is informational — the
        authoritative signal is the enum value.


        | Code | HTTP | Meaning |

        |---|---|---|

        | `OK` | 200 | Reserved — not returned on real errors. |

        | `InvalidParameter` | 400 | A required parameter is missing or failed
        validation. |

        | `BadRequest` | 400 | Generic 400 used when no more specific code fits.
        |

        | `InvalidContentType` | 400 | The `Content-Type` header is not
        `application/json`. |

        | `ResourceNotFound` | 400 | The referenced resource does not exist.
        Note: returned as HTTP 400, not 404 (historical choice). |

        | `NoLicense` | 400 | The feature is license-gated and no active license
        was found. |

        | `ReferenceExist` | 400 | Deletion blocked — other entities still
        reference this resource. |

        | `Unauthorized` | 401 | `app_key` is missing, invalid, or expired. |

        | `BalanceNotEnough` | 402 | Billing-gated operation with insufficient
        account balance. |

        | `AccessDenied` | 403 | Authenticated but lacking the permission
        required for this operation. |

        | `RouteNotFound` | 404 | The request URL path is not a known route. |

        | `MethodNotAllowed` | 405 | The HTTP method is not allowed on this
        otherwise-known path. |

        | `UndonedOrderExist` | 409 | An outstanding billing order blocks this
        new one. Wait and retry. |

        | `RequestLocked` | 423 | Operation temporarily locked due to repeated
        failures. |

        | `EntityTooLarge` | 413 | Request body exceeds the configured max size.
        |

        | `RequestTooFrequently` | 429 | Rate limit hit — API-global,
        per-account, or per-integration. |

        | `RequestVerifyRequired` | 428 | Second-factor verification required
        but not supplied. |

        | `DangerousOperation` | 428 | High-risk operation requires MFA
        verification. |

        | `InternalError` | 500 | Unhandled server-side error. Include
        `request_id` in the bug report. |

        | `ServiceUnavailable` | 503 | A backend dependency is unavailable. Try
        again later. |
      enum:
        - OK
        - InvalidParameter
        - BadRequest
        - InvalidContentType
        - ResourceNotFound
        - NoLicense
        - ReferenceExist
        - Unauthorized
        - BalanceNotEnough
        - AccessDenied
        - RouteNotFound
        - MethodNotAllowed
        - UndonedOrderExist
        - RequestLocked
        - EntityTooLarge
        - RequestTooFrequently
        - RequestVerifyRequired
        - DangerousOperation
        - InternalError
        - ServiceUnavailable
      x-enumDescriptions:
        OK: Reserved — not returned on real errors.
        InvalidParameter: A required parameter is missing or failed validation.
        BadRequest: Generic 400 used when no more specific code fits.
        InvalidContentType: The `Content-Type` header is not `application/json`.
        ResourceNotFound: >-
          The referenced resource does not exist. Note: returned as HTTP 400,
          not 404 (historical choice).
        NoLicense: The feature is license-gated and no active license was found.
        ReferenceExist: Deletion blocked — other entities still reference this resource.
        Unauthorized: '`app_key` is missing, invalid, or expired.'
        BalanceNotEnough: Billing-gated operation with insufficient account balance.
        AccessDenied: Authenticated but lacking the permission required for this operation.
        RouteNotFound: The request URL path is not a known route.
        MethodNotAllowed: The HTTP method is not allowed on this otherwise-known path.
        UndonedOrderExist: An outstanding billing order blocks this new one. Wait and retry.
        RequestLocked: Operation temporarily locked due to repeated failures.
        EntityTooLarge: Request body exceeds the configured max size.
        RequestTooFrequently: Rate limit hit — API-global, per-account, or per-integration.
        RequestVerifyRequired: Second-factor verification required but not supplied.
        DangerousOperation: High-risk operation requires MFA verification.
        InternalError: Unhandled server-side error. Include `request_id` in the bug report.
        ServiceUnavailable: A backend dependency is unavailable. Try again later.
      example: InvalidParameter
  responses:
    BadRequest:
      description: Invalid request — usually a missing or malformed parameter.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missingParameter:
              value:
                request_id: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
                error:
                  code: InvalidParameter
                  message: The specified parameter is not valid.
    Unauthorized:
      description: Missing or invalid app_key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missingAppKey:
              value:
                request_id: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
                error:
                  code: Unauthorized
                  message: You are unauthorized.
    TooManyRequests:
      description: >-
        Rate limit hit. Either the global API limit, a per-account limit, or a
        per-integration limit.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimited:
              value:
                request_id: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
                error:
                  code: RequestTooFrequently
                  message: Request too frequently.
    ServerError:
      description: Unexpected server-side error. Include the request_id when reporting.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            internal:
              value:
                request_id: 01HK8XQE3Z7JM2NTFQ5YJ8P9R4
                error:
                  code: InternalError
                  message: >-
                    We encountered an internal error, and it has been reported.
                    Please try again later.
  securitySchemes:
    AppKeyAuth:
      type: apiKey
      in: query
      name: app_key
      description: >-
        App key issued from the Flashduty console under Account → APP Keys.
        Required on every public API call. Keep it secret — it grants the same
        access as the owning account.

````