openapi: 3.1.0 info: title: Fast ACCOUNT_COSTS ALERTS_V1 API version: 0.1.0 tags: - name: ALERTS_V1 paths: /api/v1/alerts/rules: get: tags: - ALERTS_V1 summary: List Rules description: Paginated list of alert/report rules. operationId: list_rules_api_v1_alerts_rules_get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_type in: query required: false schema: anyOf: - type: string - type: 'null' description: '''alert'' or ''report''' title: Rule Type description: '''alert'' or ''report''' - name: platform in: query required: false schema: anyOf: - type: string - type: 'null' description: '''snowflake'' or ''databricks''' title: Platform description: '''snowflake'' or ''databricks''' - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category - name: search in: query required: false schema: anyOf: - type: string - type: 'null' title: Search - name: page in: query required: false schema: type: integer minimum: 1 description: Page number default: 1 title: Page description: Page number - name: size in: query required: false schema: type: integer maximum: 100 minimum: 1 description: Page size default: 50 title: Size description: Page size responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/Page_RuleResponse_' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - ALERTS_V1 summary: Create description: Create a new alert or report rule. operationId: create_api_v1_alerts_rules_post security: - HTTPBearer: [] - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RuleCreateRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/rules/summary: get: tags: - ALERTS_V1 summary: Rules Summary description: Summary counts for the rules list page. operationId: rules_summary_api_v1_alerts_rules_summary_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulesListResponse' security: - HTTPBearer: [] - HTTPBearer: [] /api/v1/alerts/rules/filters: get: tags: - ALERTS_V1 summary: Rules Filters description: Distinct filter values for the rules list page. operationId: rules_filters_api_v1_alerts_rules_filters_get responses: '200': description: Successful Response content: application/json: schema: {} security: - HTTPBearer: [] - HTTPBearer: [] /api/v1/alerts/rules/{rule_id}: get: tags: - ALERTS_V1 summary: Get description: Get a single rule by ID. operationId: get_api_v1_alerts_rules__rule_id__get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - ALERTS_V1 summary: Update description: Update an existing rule. operationId: update_api_v1_alerts_rules__rule_id__post security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RuleUpdateRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - ALERTS_V1 summary: Delete description: Delete a rule and all its runs. operationId: delete_api_v1_alerts_rules__rule_id__delete security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/rules/{rule_id}/clone: post: tags: - ALERTS_V1 summary: Clone description: Clone a rule. Only the owner can clone their own rules. operationId: clone_api_v1_alerts_rules__rule_id__clone_post security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/rules/{rule_id}/runs: get: tags: - ALERTS_V1 summary: Get Runs description: Paginated execution history for a rule. operationId: get_runs_api_v1_alerts_rules__rule_id__runs_get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: size in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 20 title: Size - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunsListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/rules/{rule_id}/evaluate: post: tags: - ALERTS_V1 summary: Evaluate description: Evaluate a rule. dry_run=True for read-only, False to record the run. operationId: evaluate_api_v1_alerts_rules__rule_id__evaluate_post security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id requestBody: content: application/json: schema: $ref: '#/components/schemas/EvaluateRequest' default: dry_run: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunResultResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/dry-run: post: tags: - ALERTS_V1 summary: Dry Run description: 'Evaluate a rule config on-the-fly without persisting anything. Accepts the same JSON shape as RuleCreateRequest / the saved column, so the payload can be copy-pasted directly.' operationId: dry_run_api_v1_alerts_dry_run_post requestBody: content: application/json: schema: $ref: '#/components/schemas/DryRunRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunResultResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] - HTTPBearer: [] /api/v1/alerts/preview: post: tags: - ALERTS_V1 summary: Preview description: Preview what a metric config would produce (chart + markdown). operationId: preview_api_v1_alerts_preview_post requestBody: content: application/json: schema: $ref: '#/components/schemas/PreviewRequest' required: true responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] - HTTPBearer: [] /api/v1/alerts/notifications/test: post: tags: - ALERTS_V1 summary: Test Notification description: 'Send a test notification using a draft rule config. Runs the same evaluator + chart pipeline as a real alert against real ClickHouse data, then dispatches via the chosen notifier (email / slack / webhook). Hard-fails on validation or chart-generation errors; returns 200 with `{ok: false, error}` for delivery failures. Rate limited to 10 requests/minute per tenant.' operationId: test_notification_api_v1_alerts_notifications_test_post requestBody: content: application/json: schema: $ref: '#/components/schemas/NotificationTestRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NotificationTestResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] - HTTPBearer: [] /api/v1/alerts/templates: get: tags: - ALERTS_V1 summary: List Templates description: Flat template library for the alert creation UI. operationId: list_templates_api_v1_alerts_templates_get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: platform in: query required: false schema: anyOf: - type: string - type: 'null' description: 'Filter by platform: ''snowflake'' or ''databricks''' title: Platform description: 'Filter by platform: ''snowflake'' or ''databricks''' - name: tag in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter templates by tag, e.g. 'popular' title: Tag description: Filter templates by tag, e.g. 'popular' responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/templates/{template_id}: get: tags: - ALERTS_V1 summary: Get Template description: Get a single template by ID. Returns a RuleCreateRequest-ready payload. operationId: get_template_api_v1_alerts_templates__template_id__get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: template_id in: path required: true schema: type: string title: Template Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/metrics/catalog: get: tags: - ALERTS_V1 summary: Metrics Catalog description: Full metrics catalog for the alerts editor. operationId: metrics_catalog_api_v1_alerts_metrics_catalog_get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: category in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter by entity type / category title: Category description: Filter by entity type / category - name: platform in: query required: false schema: anyOf: - type: string - type: 'null' description: 'Filter by platform: ''snowflake'' or ''databricks''' title: Platform description: 'Filter by platform: ''snowflake'' or ''databricks''' responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/metrics/filters/{filter_key}/options: get: tags: - ALERTS_V1 summary: Get Filter Options description: 'Load filter options dynamically for a given filter key. For searchable filters (e.g. tags), supports ``search``, ``page``, and ``size`` query parameters for paginated search-as-you-type.' operationId: get_filter_options_api_v1_alerts_metrics_filters__filter_key__options_get security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: filter_key in: path required: true schema: type: string title: Filter Key - name: metric_name in: query required: false schema: anyOf: - type: string - type: 'null' title: Metric Name - name: search in: query required: false schema: anyOf: - type: string - type: 'null' description: Search pattern (tags filter) title: Search description: Search pattern (tags filter) - name: page in: query required: false schema: type: integer minimum: 1 description: Page number (tags filter) default: 1 title: Page description: Page number (tags filter) - name: size in: query required: false schema: type: integer maximum: 200 minimum: 1 description: Page size (tags filter) default: 20 title: Size description: Page size (tags filter) responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/admin/rules/{rule_id}/execute: post: tags: - ALERTS_V1 summary: Admin Execute description: 'Execute any alert/report rule on demand (admin only). Restricted to the service user (email matching SERVICE_USER_EMAIL). Bypasses schedule and active/inactive status checks. Delegates to the Celery task for actual execution. Requires a `reason` (logged for audit) and accepts an optional `reference_time` to evaluate as if "now" were a different timestamp.' operationId: admin_execute_api_v1_alerts_admin_rules__rule_id__execute_post security: - HTTPBearer: [] - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: integer title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AdminExecuteRequest' responses: '202': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' components: schemas: RunResultResponse: properties: run_id: anyOf: - type: string - type: 'null' title: Run Id rule_id: anyOf: - type: integer - type: 'null' title: Rule Id metric_name: type: string title: Metric Name current_value: type: number title: Current Value previous_value: anyOf: - type: number - type: 'null' title: Previous Value change: anyOf: - type: number - type: 'null' title: Change change_percent: anyOf: - type: number - type: 'null' title: Change Percent threshold_breached: type: boolean title: Threshold Breached status: type: string title: Status error: anyOf: - type: string - type: 'null' title: Error executed_at: type: string format: date-time title: Executed At breaching_entities: anyOf: - items: additionalProperties: true type: object type: array - type: 'null' title: Breaching Entities description: 'For per-entity (''ANY'') rules: the warehouses that breached, each {entity, current_value, previous_value, change, change_percent}, worst first. Null for ordinary rules.' request: anyOf: - additionalProperties: true type: object - type: 'null' title: Request description: Echo of the resolved request config (dry-run only) queries: items: $ref: '#/components/schemas/QueryLogResponse' type: array title: Queries description: SQL queries executed during evaluation type: object required: - metric_name - current_value - threshold_breached - status - executed_at title: RunResultResponse DeliverySchedule: properties: cron: type: string title: Cron description: Cron expression, e.g. '0 14 * * *' default: 0 14 * * * timezone: type: string title: Timezone description: Timezone for the schedule default: UTC type: object title: DeliverySchedule description: When to run the alert/report. RuleCreateRequest: properties: name: anyOf: - type: string maxLength: 255 - type: 'null' title: Name description: anyOf: - type: string maxLength: 2000 - type: 'null' title: Description rule_type: anyOf: - type: string - type: 'null' title: Rule Type default: alert platform: anyOf: - type: string - type: 'null' title: Platform entity_type: anyOf: - type: string - type: 'null' title: Entity Type metric_config: anyOf: - $ref: '#/components/schemas/MetricConfig' - type: 'null' delivery: anyOf: - $ref: '#/components/schemas/DeliveryConfig' - type: 'null' alert_message: anyOf: - type: string - type: 'null' title: Alert Message type: object title: RuleCreateRequest description: 'Create request — field-level validation happens in validate_rule_create() so we get contextual error codes instead of generic Pydantic 422s.' QueryLogResponse: properties: label: type: string title: Label sql: type: string title: Sql params: additionalProperties: true type: object title: Params period_start: anyOf: - type: string - type: 'null' title: Period Start period_end: anyOf: - type: string - type: 'null' title: Period End value: anyOf: - type: number - type: 'null' title: Value elapsed_ms: anyOf: - type: number - type: 'null' title: Elapsed Ms type: object required: - label - sql title: QueryLogResponse RunsListResponse: properties: items: items: $ref: '#/components/schemas/RunResponse' type: array title: Items total: type: integer title: Total page: type: integer title: Page size: type: integer title: Size type: object required: - items - total - page - size title: RunsListResponse EvaluateRequest: properties: dry_run: type: boolean title: Dry Run default: true type: object title: EvaluateRequest PreviewRequest: properties: metric_config: $ref: '#/components/schemas/MetricConfig' rule_type: anyOf: - type: string - type: 'null' title: Rule Type description: '''alert'' or ''report'' — reports may show resource-wise splits' type: object required: - metric_config title: PreviewRequest NotifierConfig: properties: type: type: string title: Type description: '''email'', ''slack'', or ''webhook''' recipients: anyOf: - items: type: string type: array - type: 'null' title: Recipients description: Email addresses; used when type is 'email' channel: anyOf: - type: string - type: 'null' title: Channel description: Slack notification ID; used when type is 'slack' webhook_url: anyOf: - type: string - type: 'null' title: Webhook Url description: HTTP(S) URL for POST delivery; used when type is 'webhook' type: object required: - type title: NotifierConfig description: Single delivery destination (email, Slack, or webhook). HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError MetricFilter: properties: key: type: string title: Key description: Filter dimension name, e.g. 'warehouse' value: items: type: string type: array title: Value description: Filter values, e.g. ['WH1', 'WH2'], ['all'], or ['ANY'] order: type: integer title: Order description: Display order of this filter default: 0 type: object required: - key title: MetricFilter description: A single dimension filter for a metric query. RuleUpdateRequest: properties: name: anyOf: - type: string maxLength: 255 minLength: 1 - type: 'null' title: Name description: anyOf: - type: string maxLength: 2000 - type: 'null' title: Description rule_type: anyOf: - type: string pattern: ^(alert|report)$ - type: 'null' title: Rule Type platform: anyOf: - type: string pattern: ^(snowflake|databricks)$ - type: 'null' title: Platform entity_type: anyOf: - type: string - type: 'null' title: Entity Type metric_config: anyOf: - $ref: '#/components/schemas/MetricConfig' - type: 'null' delivery: anyOf: - $ref: '#/components/schemas/DeliveryConfig' - type: 'null' alert_message: anyOf: - type: string - type: 'null' title: Alert Message status: anyOf: - type: string pattern: ^(active|inactive)$ - type: 'null' title: Status type: object title: RuleUpdateRequest RecentRunResponse: properties: id: type: integer title: Id status: type: string title: Status executed_at: anyOf: - type: string format: date-time - type: 'null' title: Executed At message: anyOf: - type: string - type: 'null' title: Message type: object required: - id - status title: RecentRunResponse description: Lightweight run summary for embedding in RuleResponse.recent_runs. MetricParams: properties: comparison_type: type: string title: Comparison Type description: '''absolute_value'' or ''relative_value''' default: absolute_value threshold_type: type: string title: Threshold Type description: '''exceeds'', ''below'', ''changes_by'', or ''changes_by_percent''' default: exceeds threshold_value: type: number title: Threshold Value description: Threshold to compare against default: 0 aggregation: type: string title: Aggregation description: '''sum'', ''mean'', ''max'', or ''min''' default: sum date_range: type: string title: Date Range description: '''previous_day'', ''previous_week'', ''previous_month'', or ''previous_year''' default: previous_day is_percentage: anyOf: - type: boolean - type: 'null' title: Is Percentage description: Derived from threshold_type; included by templates type: object title: MetricParams description: Evaluation parameters within a metric config. NotificationTestResponse: properties: ok: type: boolean title: Ok target: type: string title: Target description: Channel type — 'email', 'slack', or 'webhook' chart_url: anyOf: - type: string - type: 'null' title: Chart Url error: anyOf: - type: string - type: 'null' title: Error type: object required: - ok - target title: NotificationTestResponse description: Result of a test notification dispatch. MetricConfig: properties: metric_name: type: string title: Metric Name description: Metric identifier, e.g. 'warehouse_daily_cost' params: $ref: '#/components/schemas/MetricParams' filters: items: $ref: '#/components/schemas/MetricFilter' type: array title: Filters category: anyOf: - type: string - type: 'null' title: Category description: Entity type echo; included by templates type: object required: - metric_name title: MetricConfig description: Typed representation of the metric_config JSON stored in alert rules. Page_RuleResponse_: properties: items: items: $ref: '#/components/schemas/RuleResponse' type: array title: Items total: anyOf: - type: integer minimum: 0.0 - type: 'null' title: Total page: anyOf: - type: integer minimum: 1.0 - type: 'null' title: Page size: anyOf: - type: integer minimum: 1.0 - type: 'null' title: Size pages: anyOf: - type: integer minimum: 0.0 - type: 'null' title: Pages type: object required: - items - total - page - size title: Page[RuleResponse] RunResponse: properties: id: type: integer title: Id rule_id: type: integer title: Rule Id status: type: string title: Status result: anyOf: - additionalProperties: true type: object - type: 'null' title: Result error: anyOf: - additionalProperties: true type: object - type: 'null' title: Error message: anyOf: - type: string - type: 'null' title: Message executed_at: anyOf: - type: string format: date-time - type: 'null' title: Executed At created_at: type: string format: date-time title: Created At type: object required: - id - rule_id - status - created_at title: RunResponse DeliveryConfig: properties: schedule: anyOf: - $ref: '#/components/schemas/DeliverySchedule' - type: 'null' description: When to run; None uses default cron. notifiers: items: $ref: '#/components/schemas/NotifierConfig' type: array title: Notifiers description: Where to send (email, Slack, etc.). type: object title: DeliveryConfig description: When and where to deliver alert/report (schedule + notifiers). AdminExecuteRequest: properties: reason: type: string maxLength: 500 minLength: 1 title: Reason description: Why this manual execution is needed (logged for audit). reference_time: anyOf: - type: string format: date-time - type: 'null' title: Reference Time description: Evaluate as if 'now' were this timestamp (ISO-8601). Defaults to UTC now. type: object required: - reason title: AdminExecuteRequest description: Request body for admin on-demand rule execution. RuleResponse: properties: id: type: integer title: Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description rule_type: type: string title: Rule Type platform: type: string title: Platform category: anyOf: - type: string - type: 'null' title: Category entity_type: type: string title: Entity Type metric_config: $ref: '#/components/schemas/MetricConfig' delivery: anyOf: - additionalProperties: true type: object - type: 'null' title: Delivery alert_message: anyOf: - type: string - type: 'null' title: Alert Message status: type: string title: Status created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At created_by: type: integer title: Created By last_run: anyOf: - $ref: '#/components/schemas/RunResponse' - type: 'null' recent_runs: items: $ref: '#/components/schemas/RecentRunResponse' type: array title: Recent Runs summary: anyOf: - type: string - type: 'null' title: Summary type: object required: - id - name - rule_type - platform - entity_type - metric_config - status - created_at - updated_at - created_by title: RuleResponse NotificationTestRequest: properties: name: anyOf: - type: string maxLength: 255 - type: 'null' title: Name default: Test alert rule_type: type: string pattern: ^(alert|report)$ title: Rule Type default: alert platform: anyOf: - type: string pattern: ^(snowflake|databricks)$ - type: 'null' title: Platform entity_type: type: string title: Entity Type metric_config: $ref: '#/components/schemas/MetricConfig' alert_message: anyOf: - type: string - type: 'null' title: Alert Message notifier: $ref: '#/components/schemas/NotifierConfig' description: Single channel to test (email, slack, or webhook). reference_time: anyOf: - type: string format: date-time - type: 'null' title: Reference Time description: Evaluate as if 'now' were this timestamp (ISO-8601). Defaults to UTC now. type: object required: - entity_type - metric_config - notifier title: NotificationTestRequest description: 'Send a test notification using a draft rule config. Alert tests run the same evaluator + chart pipeline as a real alert. Report tests build the corresponding report payload directly so the test message matches scheduled report delivery instead of alert delivery.' ValidationError: properties: loc: items: anyOf: - type: string - type: integer type: array title: Location msg: type: string title: Message type: type: string title: Error Type type: object required: - loc - msg - type title: ValidationError DryRunRequest: properties: name: anyOf: - type: string maxLength: 255 - type: 'null' title: Name default: Dry Run rule_type: anyOf: - type: string - type: 'null' title: Rule Type default: alert platform: anyOf: - type: string - type: 'null' title: Platform entity_type: type: string title: Entity Type metric_config: $ref: '#/components/schemas/MetricConfig' delivery: anyOf: - additionalProperties: true type: object - type: 'null' title: Delivery description: Ignored for evaluation; accepted so full rule JSON can be pasted. reference_time: anyOf: - type: string format: date-time - type: 'null' title: Reference Time description: Evaluate as if 'now' were this timestamp (ISO-8601). Defaults to UTC now. type: object required: - entity_type - metric_config title: DryRunRequest description: 'Run evaluation against a rule config without saving. Accepts the same shape as RuleCreateRequest so the payload can be copy-pasted from the saved column / frontend config JSON.' RulesListResponse: properties: total: type: integer title: Total active: type: integer title: Active alerts: type: integer title: Alerts reports: type: integer title: Reports type: object required: - total - active - alerts - reports title: RulesListResponse securitySchemes: HTTPBearer: type: http scheme: bearer