Files
Raj Nandan Sharma e27ab6ff7d feat(api): add DELETE /api/v4/monitors/{monitor_tag} and fix alert-config orphans on delete, fixes #716
Monitor deletion is now available via the v4 API, reusing the same
DeleteMonitorCompletelyUsingTag path as the manage UI. While wiring it
in, monitor deletion was found to orphan alert configs on SQLite:
the code relied on FK cascades that SQLite never enforces (the
foreign_keys pragma is off). Delete paths now remove child rows
explicitly — v2 alerts, trigger junctions, monitor junctions — in both
the by-id and by-tag config deletes; see ADR 0008 for why explicit
deletes were chosen over enabling the pragma.

Also corrects the CONTEXT.md Stale Member entry (deletion strips group
membership and rebalances weights; only pausing produces a stale
member), documents the DELETE endpoint in the OpenAPI spec, points the
pages doc at the ~home token, and removes an orphaned fictional
api-reference markdown page superseded by the spec tab.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 13:42:08 +05:30

2476 lines
66 KiB
JSON

{
"openapi": "3.1.0",
"info": {
"title": "Kener API v4",
"version": "4.0.0",
"description": "OpenAPI specification for Kener self-hosted API v4. All endpoints use Bearer authentication unless explicitly public. Example request URL: GET https://your-kener.com/api/v4/pages"
},
"servers": [
{
"url": "{serverUrl}",
"variables": {
"serverUrl": {
"default": "https://your-kener.com",
"description": "Base URL for your Kener deployment"
}
}
}
],
"security": [
{
"bearerAuth": []
}
],
"tags": [
{
"name": "Monitors"
},
{
"name": "Monitor Data"
},
{
"name": "Incidents"
},
{
"name": "Incident Comments"
},
{
"name": "Pages"
},
{
"name": "Site"
},
{
"name": "Maintenances"
},
{
"name": "Maintenance Events"
}
],
"paths": {
"/api/v4/monitors": {
"get": {
"tags": ["Monitors"],
"operationId": "listMonitors",
"summary": "List monitors",
"parameters": [
{
"name": "status",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "category_name",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "monitor_type",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "is_hidden",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Monitor list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["monitors"],
"properties": {
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Monitor"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
},
"post": {
"tags": ["Monitors"],
"operationId": "createMonitor",
"summary": "Create monitor",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateMonitorRequest"
}
}
}
},
"responses": {
"201": {
"description": "Monitor created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["monitor"],
"properties": {
"monitor": {
"$ref": "#/components/schemas/Monitor"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
}
},
"/api/v4/monitors/{monitor_tag}": {
"parameters": [
{
"$ref": "#/components/parameters/MonitorTag"
}
],
"get": {
"tags": ["Monitors"],
"operationId": "getMonitor",
"summary": "Get monitor",
"responses": {
"200": {
"description": "Monitor",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["monitor"],
"properties": {
"monitor": {
"$ref": "#/components/schemas/Monitor"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Monitors"],
"operationId": "updateMonitor",
"summary": "Update monitor",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateMonitorRequest"
}
}
}
},
"responses": {
"200": {
"description": "Monitor updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["monitor"],
"properties": {
"monitor": {
"$ref": "#/components/schemas/Monitor"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
},
"delete": {
"tags": ["Monitors"],
"operationId": "deleteMonitor",
"summary": "Delete monitor",
"description": "Deletes the monitor and everything keyed to its tag: monitoring data, incident/maintenance/page links, alerts, alert configurations, and group memberships (remaining member weights are rebalanced equally). This is irreversible. Scheduled checks stop within seconds.",
"responses": {
"200": {
"description": "Monitor deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/monitors/{monitor_tag}/data": {
"parameters": [
{
"$ref": "#/components/parameters/MonitorTag"
}
],
"get": {
"tags": ["Monitor Data"],
"operationId": "getMonitorDataRange",
"summary": "Get monitor data in a time range",
"description": "Returns monitoring data points for [start_ts, end_ts). Timestamps are normalized to minute boundaries.",
"parameters": [
{
"name": "start_ts",
"in": "query",
"required": true,
"schema": {
"type": "integer"
}
},
{
"name": "end_ts",
"in": "query",
"required": true,
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Data points",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["data"],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitoringDataPoint"
}
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
},
"patch": {
"tags": ["Monitor Data"],
"operationId": "bulkUpdateMonitorData",
"summary": "Bulk update monitor data over a range",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BulkUpdateMonitorDataRequest"
}
}
}
},
"responses": {
"200": {
"description": "Range update completed",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["message", "updated_count"],
"properties": {
"message": {
"type": "string"
},
"updated_count": {
"type": "integer"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/monitors/{monitor_tag}/data/{timestamp}": {
"parameters": [
{
"$ref": "#/components/parameters/MonitorTag"
},
{
"$ref": "#/components/parameters/Timestamp"
}
],
"get": {
"tags": ["Monitor Data"],
"operationId": "getMonitorDataPoint",
"summary": "Get one monitor data point",
"responses": {
"200": {
"description": "Data point",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["data"],
"properties": {
"data": {
"$ref": "#/components/schemas/MonitoringDataPoint"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Monitor Data"],
"operationId": "upsertMonitorDataPoint",
"summary": "Upsert one monitor data point",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpsertMonitorDataPointRequest"
}
}
}
},
"responses": {
"200": {
"description": "Data point upserted",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["data"],
"properties": {
"data": {
"$ref": "#/components/schemas/MonitoringDataPoint"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/incidents": {
"get": {
"tags": ["Incidents"],
"operationId": "listIncidents",
"summary": "List incidents",
"parameters": [
{
"name": "start_ts",
"in": "query",
"schema": {
"type": "integer"
}
},
{
"name": "end_ts",
"in": "query",
"schema": {
"type": "integer"
}
},
{
"name": "monitor_tags",
"in": "query",
"description": "Comma-separated monitor tags",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Incident list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["incidents"],
"properties": {
"incidents": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Incident"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
},
"post": {
"tags": ["Incidents"],
"operationId": "createIncident",
"summary": "Create incident",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateIncidentRequest"
}
}
}
},
"responses": {
"201": {
"description": "Incident created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["incident"],
"properties": {
"incident": {
"$ref": "#/components/schemas/Incident"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/incidents/{incident_id}": {
"parameters": [
{
"$ref": "#/components/parameters/IncidentId"
}
],
"get": {
"tags": ["Incidents"],
"operationId": "getIncident",
"summary": "Get incident",
"responses": {
"200": {
"description": "Incident details",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["incident"],
"properties": {
"incident": {
"$ref": "#/components/schemas/Incident"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Incidents"],
"operationId": "updateIncident",
"summary": "Update incident",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateIncidentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Incident updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["incident"],
"properties": {
"incident": {
"$ref": "#/components/schemas/Incident"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
},
"delete": {
"tags": ["Incidents"],
"operationId": "deleteIncident",
"summary": "Delete incident",
"responses": {
"200": {
"description": "Incident deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/incidents/{incident_id}/comments": {
"parameters": [
{
"$ref": "#/components/parameters/IncidentId"
}
],
"get": {
"tags": ["Incident Comments"],
"operationId": "listIncidentComments",
"summary": "List incident comments",
"responses": {
"200": {
"description": "Comment list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["comments"],
"properties": {
"comments": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IncidentComment"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"post": {
"tags": ["Incident Comments"],
"operationId": "createIncidentComment",
"summary": "Create incident comment",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateIncidentCommentRequest"
}
}
}
},
"responses": {
"201": {
"description": "Comment created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["comment"],
"properties": {
"comment": {
"$ref": "#/components/schemas/IncidentComment"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/incidents/{incident_id}/comments/{comment_id}": {
"parameters": [
{
"$ref": "#/components/parameters/IncidentId"
},
{
"$ref": "#/components/parameters/CommentId"
}
],
"get": {
"tags": ["Incident Comments"],
"operationId": "getIncidentComment",
"summary": "Get incident comment",
"responses": {
"200": {
"description": "Comment",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["comment"],
"properties": {
"comment": {
"$ref": "#/components/schemas/IncidentComment"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Incident Comments"],
"operationId": "updateIncidentComment",
"summary": "Update incident comment",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateIncidentCommentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Comment updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["comment"],
"properties": {
"comment": {
"$ref": "#/components/schemas/IncidentComment"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
},
"delete": {
"tags": ["Incident Comments"],
"operationId": "deleteIncidentComment",
"summary": "Delete incident comment",
"responses": {
"200": {
"description": "Comment deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/pages": {
"get": {
"tags": ["Pages"],
"operationId": "listPages",
"summary": "List pages",
"responses": {
"200": {
"description": "Page list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["pages"],
"properties": {
"pages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Page"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
},
"post": {
"tags": ["Pages"],
"operationId": "createPage",
"summary": "Create page",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePageRequest"
}
}
}
},
"responses": {
"201": {
"description": "Page created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["page"],
"properties": {
"page": {
"$ref": "#/components/schemas/Page"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/pages/{page_path}": {
"parameters": [
{
"$ref": "#/components/parameters/PagePath"
}
],
"get": {
"tags": ["Pages"],
"operationId": "getPage",
"summary": "Get page",
"responses": {
"200": {
"description": "Page",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["page"],
"properties": {
"page": {
"$ref": "#/components/schemas/Page"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Pages"],
"operationId": "updatePage",
"summary": "Update page",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdatePageRequest"
}
}
}
},
"responses": {
"200": {
"description": "Page updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["page"],
"properties": {
"page": {
"$ref": "#/components/schemas/Page"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
},
"description": "The home page (addressed as `~home`) accepts all fields except `page_path`, which is fixed and returns `400` if changed."
},
"delete": {
"tags": ["Pages"],
"operationId": "deletePage",
"summary": "Delete page",
"responses": {
"200": {
"description": "Page deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
},
"description": "The home page (addressed as `~home`) cannot be deleted and returns `400`."
}
},
"/api/v4/site": {
"get": {
"tags": ["Site"],
"operationId": "listSiteConfig",
"summary": "List site config entries",
"responses": {
"200": {
"description": "Site config",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["site_data"],
"properties": {
"site_data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SiteDataEntry"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/site/{config_key}": {
"parameters": [
{
"$ref": "#/components/parameters/ConfigKey"
}
],
"get": {
"tags": ["Site"],
"operationId": "getSiteConfig",
"summary": "Get one site config entry",
"responses": {
"200": {
"description": "Site config entry",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SiteDataEntry"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Site"],
"operationId": "updateSiteConfig",
"summary": "Update one site config entry",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["value"],
"properties": {
"value": {}
}
}
}
}
},
"responses": {
"200": {
"description": "Site config updated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SiteDataEntry"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/maintenances": {
"get": {
"tags": ["Maintenances"],
"operationId": "listMaintenances",
"summary": "List maintenances",
"parameters": [
{
"name": "status",
"in": "query",
"schema": {
"type": "string",
"enum": ["ACTIVE", "INACTIVE"]
}
},
{
"name": "monitor_tag",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Maintenance list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["maintenances"],
"properties": {
"maintenances": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Maintenance"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
},
"post": {
"tags": ["Maintenances"],
"operationId": "createMaintenance",
"summary": "Create maintenance",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateMaintenanceRequest"
}
}
}
},
"responses": {
"201": {
"description": "Maintenance created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["maintenance"],
"properties": {
"maintenance": {
"$ref": "#/components/schemas/Maintenance"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
}
},
"/api/v4/maintenances/{maintenance_id}": {
"parameters": [
{
"$ref": "#/components/parameters/MaintenanceId"
}
],
"get": {
"tags": ["Maintenances"],
"operationId": "getMaintenance",
"summary": "Get maintenance",
"responses": {
"200": {
"description": "Maintenance",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["maintenance"],
"properties": {
"maintenance": {
"$ref": "#/components/schemas/Maintenance"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Maintenances"],
"operationId": "updateMaintenance",
"summary": "Update maintenance",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateMaintenanceRequest"
}
}
}
},
"responses": {
"200": {
"description": "Maintenance updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["maintenance"],
"properties": {
"maintenance": {
"$ref": "#/components/schemas/Maintenance"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
}
},
"delete": {
"tags": ["Maintenances"],
"operationId": "deleteMaintenance",
"summary": "Delete maintenance",
"responses": {
"200": {
"description": "Maintenance deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/maintenances/events": {
"get": {
"tags": ["Maintenance Events"],
"operationId": "listMaintenanceEvents",
"summary": "List maintenance events",
"parameters": [
{
"name": "page",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
}
},
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 20
}
},
{
"name": "monitors",
"in": "query",
"description": "Comma-separated monitor tags",
"schema": {
"type": "string"
}
},
{
"name": "event_status",
"in": "query",
"schema": {
"type": "string",
"enum": ["SCHEDULED", "ONGOING", "COMPLETED", "CANCELLED", "READY"]
}
},
{
"name": "event_start_date_time",
"in": "query",
"schema": {
"type": "integer"
}
},
{
"name": "maintenance_id",
"in": "query",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Events list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["events", "page", "limit", "total"],
"properties": {
"events": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MaintenanceEventDetailed"
}
},
"page": {
"type": "integer"
},
"limit": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
}
}
}
},
"/api/v4/maintenances/{maintenance_id}/events": {
"parameters": [
{
"$ref": "#/components/parameters/MaintenanceId"
}
],
"get": {
"tags": ["Maintenance Events"],
"operationId": "listMaintenanceEventsByMaintenance",
"summary": "List events for one maintenance",
"parameters": [
{
"name": "page",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
}
},
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 20
}
}
],
"responses": {
"200": {
"description": "Events list",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["events", "page", "limit"],
"properties": {
"events": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MaintenanceEvent"
}
},
"page": {
"type": "integer"
},
"limit": {
"type": "integer"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
},
"/api/v4/maintenances/{maintenance_id}/events/{event_id}": {
"parameters": [
{
"$ref": "#/components/parameters/MaintenanceId"
},
{
"$ref": "#/components/parameters/EventId"
}
],
"get": {
"tags": ["Maintenance Events"],
"operationId": "getMaintenanceEvent",
"summary": "Get one maintenance event",
"responses": {
"200": {
"description": "Event",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["event"],
"properties": {
"event": {
"$ref": "#/components/schemas/MaintenanceEvent"
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
},
"patch": {
"tags": ["Maintenance Events"],
"operationId": "updateMaintenanceEvent",
"summary": "Update one maintenance event",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateMaintenanceEventRequest"
}
}
}
},
"responses": {
"200": {
"description": "Event updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["event"],
"properties": {
"event": {
"$ref": "#/components/schemas/MaintenanceEvent"
}
}
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"500": {
"$ref": "#/components/responses/InternalServerError"
}
},
"description": "Either edit the event window (start_date_time and end_date_time) or transition its status (COMPLETED or CANCELLED). The two modes cannot be combined in one request."
},
"delete": {
"tags": ["Maintenance Events"],
"operationId": "deleteMaintenanceEvent",
"summary": "Delete one maintenance event",
"responses": {
"200": {
"description": "Event deleted",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MessageResponse"
}
}
}
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
}
}
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "API key"
}
},
"parameters": {
"MonitorTag": {
"name": "monitor_tag",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"Timestamp": {
"name": "timestamp",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"IncidentId": {
"name": "incident_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"CommentId": {
"name": "comment_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"PagePath": {
"name": "page_path",
"in": "path",
"required": true,
"description": "The page's path segment. Use the special token `~home` to address the home page, whose stored `page_path` is an empty string and can not appear as a URL segment. No real page can be named `~home` because the path sanitizer strips `~`.",
"schema": {
"type": "string"
},
"examples": {
"regular": {
"value": "services",
"summary": "A regular page"
},
"home": {
"value": "~home",
"summary": "The home page (empty page_path)"
}
}
},
"ConfigKey": {
"name": "config_key",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"MaintenanceId": {
"name": "maintenance_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
},
"EventId": {
"name": "event_id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
},
"responses": {
"BadRequest": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
},
"Unauthorized": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
},
"examples": {
"missingHeader": {
"value": {
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid authorization header"
}
}
},
"invalidToken": {
"value": {
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}
}
}
}
}
},
"NotFound": {
"description": "Not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
},
"InternalServerError": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
}
}
},
"schemas": {
"ErrorResponse": {
"type": "object",
"required": ["error"],
"properties": {
"error": {
"type": "object",
"required": ["code", "message"],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
},
"MessageResponse": {
"type": "object",
"required": ["message"],
"properties": {
"message": {
"type": "string"
}
}
},
"Monitor": {
"type": "object",
"required": ["tag", "name"],
"properties": {
"tag": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"image": {
"type": "string"
},
"cron": {
"type": "string"
},
"default_status": {
"type": "string",
"enum": ["UP", "DOWN", "DEGRADED", "MAINTENANCE", "NO_DATA"]
},
"status": {
"type": "string"
},
"category_name": {
"type": "string"
},
"monitor_type": {
"type": "string"
},
"type_data": {
"type": "object",
"additionalProperties": true
},
"include_degraded_in_downtime": {
"type": "string"
},
"is_hidden": {
"type": "string"
},
"monitor_settings_json": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": true
},
"CreateMonitorRequest": {
"type": "object",
"required": ["tag", "name"],
"properties": {
"tag": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string"
},
"image": {
"type": "string"
},
"cron": {
"type": "string"
},
"default_status": {
"type": "string"
},
"status": {
"type": "string"
},
"category_name": {
"type": "string"
},
"monitor_type": {
"type": "string"
},
"type_data": {
"type": "object",
"additionalProperties": true
},
"include_degraded_in_downtime": {
"type": "string"
},
"is_hidden": {
"type": "string"
},
"monitor_settings_json": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false
},
"UpdateMonitorRequest": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"image": {
"type": "string"
},
"cron": {
"type": "string"
},
"default_status": {
"type": "string"
},
"status": {
"type": "string"
},
"category_name": {
"type": "string"
},
"monitor_type": {
"type": "string"
},
"type_data": {
"oneOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
]
},
"include_degraded_in_downtime": {
"type": "string"
},
"is_hidden": {
"type": "string"
},
"monitor_settings_json": {
"oneOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
},
"MonitoringDataPoint": {
"type": "object",
"required": ["monitor_tag", "timestamp", "status", "latency", "type"],
"properties": {
"monitor_tag": {
"type": "string"
},
"timestamp": {
"type": "integer",
"description": "UTC timestamp in seconds, minute-aligned"
},
"status": {
"type": "string",
"enum": ["UP", "DOWN", "DEGRADED"]
},
"latency": {
"type": "number",
"minimum": 0
},
"type": {
"type": "string"
}
},
"additionalProperties": true
},
"BulkUpdateMonitorDataRequest": {
"type": "object",
"required": ["start_ts", "end_ts", "status", "latency"],
"properties": {
"start_ts": {
"type": "integer"
},
"end_ts": {
"type": "integer"
},
"status": {
"type": "string",
"enum": ["UP", "DOWN", "DEGRADED"]
},
"latency": {
"type": "number",
"minimum": 0
},
"deviation": {
"type": "number",
"minimum": 0,
"default": 0
}
},
"additionalProperties": false
},
"UpsertMonitorDataPointRequest": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["UP", "DOWN", "DEGRADED"]
},
"latency": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
},
"MonitorImpact": {
"type": "object",
"required": ["monitor_tag"],
"properties": {
"monitor_tag": {
"type": "string"
},
"impact": {
"type": "string",
"enum": ["UP", "DOWN", "DEGRADED", "MAINTENANCE"]
}
}
},
"Incident": {
"type": "object",
"required": ["id", "title"],
"properties": {
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"start_date_time": {
"type": "integer"
},
"end_date_time": {
"type": "integer"
},
"state": {
"type": "string"
},
"status": {
"type": "string"
},
"incident_type": {
"type": "string"
},
"incident_source": {
"type": "string"
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
},
"url": {
"type": "string",
"format": "uri",
"description": "Absolute URL of the public incident page.",
"examples": ["https://status.example.com/incidents/12"]
}
},
"additionalProperties": true
},
"CreateIncidentRequest": {
"type": "object",
"required": ["title", "start_date_time"],
"properties": {
"title": {
"type": "string",
"minLength": 1
},
"start_date_time": {
"type": "integer"
},
"end_date_time": {
"type": "integer"
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
}
},
"additionalProperties": false
},
"UpdateIncidentRequest": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"start_date_time": {
"type": "integer"
},
"end_date_time": {
"type": "integer"
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
}
},
"additionalProperties": false
},
"IncidentComment": {
"type": "object",
"required": ["id", "incident_id", "comment", "state", "timestamp"],
"properties": {
"id": {
"type": "integer"
},
"incident_id": {
"type": "integer"
},
"comment": {
"type": "string"
},
"state": {
"type": "string",
"enum": ["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]
},
"timestamp": {
"type": "integer"
},
"status": {
"type": "string"
}
},
"additionalProperties": true
},
"CreateIncidentCommentRequest": {
"type": "object",
"required": ["comment", "state"],
"properties": {
"comment": {
"type": "string",
"minLength": 1
},
"state": {
"type": "string",
"enum": ["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]
},
"timestamp": {
"type": "integer"
}
},
"additionalProperties": false
},
"UpdateIncidentCommentRequest": {
"type": "object",
"properties": {
"comment": {
"type": "string"
},
"state": {
"type": "string",
"enum": ["INVESTIGATING", "IDENTIFIED", "MONITORING", "RESOLVED"]
},
"timestamp": {
"type": "integer"
}
},
"additionalProperties": false
},
"Page": {
"type": "object",
"required": ["page_path", "page_title", "page_header"],
"properties": {
"page_path": {
"type": "string",
"description": "The page's path segment. The home page renders as the addressable token `~home` (its stored path is empty); its public URL is the site root.",
"examples": ["services", "~home"]
},
"page_title": {
"type": "string"
},
"page_header": {
"type": "string"
},
"page_subheader": {
"type": "string"
},
"page_logo": {
"type": "string"
},
"page_settings": {
"$ref": "#/components/schemas/PageSettings"
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Monitor"
}
}
},
"additionalProperties": true
},
"CreatePageRequest": {
"type": "object",
"required": ["page_path", "page_title", "page_header"],
"properties": {
"page_path": {
"type": "string",
"description": "Will be sanitized to lowercase kebab-like single segment"
},
"page_title": {
"type": "string",
"minLength": 1
},
"page_header": {
"type": "string",
"minLength": 1
},
"page_subheader": {
"type": "string"
},
"page_logo": {
"type": "string"
},
"page_settings": {
"$ref": "#/components/schemas/PageSettings"
},
"monitors": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"UpdatePageRequest": {
"type": "object",
"properties": {
"page_path": {
"type": "string",
"description": "New path for the page, sanitized to a lowercase single segment. For the home page (addressed as `~home`), sending back `~home` is a no-op and any other value returns `400` — its path is fixed."
},
"page_title": {
"type": "string"
},
"page_header": {
"type": "string"
},
"page_subheader": {
"type": "string"
},
"page_logo": {
"type": "string"
},
"page_settings": {
"$ref": "#/components/schemas/PageSettings"
},
"monitors": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
},
"SiteDataEntry": {
"type": "object",
"required": ["key", "value", "data_type"],
"properties": {
"key": {
"type": "string"
},
"value": {},
"data_type": {
"type": "string"
}
},
"additionalProperties": true
},
"Maintenance": {
"type": "object",
"required": ["id", "title", "start_date_time", "rrule", "duration_seconds"],
"properties": {
"id": {
"type": "integer"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"start_date_time": {
"type": "integer"
},
"rrule": {
"type": "string"
},
"duration_seconds": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string",
"enum": ["ACTIVE", "INACTIVE"]
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
},
"url": {
"type": "string",
"format": "uri",
"description": "Absolute URL of the public page for this maintenance. The public /maintenances/{id} route is keyed by maintenance EVENT id by default, so this URL carries ?type=maintenance. Always link via this field; never build links by concatenating `id` onto a path.",
"examples": ["https://status.example.com/maintenances/4?type=maintenance"]
}
},
"additionalProperties": true
},
"CreateMaintenanceRequest": {
"type": "object",
"required": ["title", "start_date_time", "rrule", "duration_seconds"],
"properties": {
"title": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string"
},
"start_date_time": {
"type": "integer"
},
"rrule": {
"type": "string",
"minLength": 1,
"description": "Valid RRULE string"
},
"duration_seconds": {
"type": "integer",
"minimum": 1
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
}
},
"additionalProperties": false
},
"UpdateMaintenanceRequest": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"start_date_time": {
"type": "integer"
},
"rrule": {
"type": "string"
},
"duration_seconds": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string",
"enum": ["ACTIVE", "INACTIVE"]
},
"monitors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MonitorImpact"
}
}
},
"additionalProperties": false
},
"MaintenanceEvent": {
"type": "object",
"required": ["id", "maintenance_id", "start_date_time", "end_date_time"],
"properties": {
"id": {
"type": "integer"
},
"maintenance_id": {
"type": "integer"
},
"start_date_time": {
"type": "integer"
},
"end_date_time": {
"type": "integer"
},
"event_status": {
"type": "string",
"enum": ["SCHEDULED", "ONGOING", "COMPLETED", "CANCELLED", "READY"]
},
"url": {
"type": "string",
"format": "uri",
"description": "Absolute URL of the public page for this maintenance event.",
"examples": ["https://status.example.com/maintenances/9"]
}
},
"additionalProperties": true
},
"MaintenanceEventDetailed": {
"allOf": [
{
"$ref": "#/components/schemas/MaintenanceEvent"
},
{
"type": "object",
"properties": {
"maintenance": {
"$ref": "#/components/schemas/Maintenance"
}
},
"additionalProperties": true
}
]
},
"UpdateMaintenanceEventRequest": {
"description": "Two mutually exclusive modes: edit the event window (both start_date_time and end_date_time required), or transition the event status (status alone). Combining status with time fields returns 400.",
"oneOf": [
{
"title": "Window edit",
"type": "object",
"required": ["start_date_time", "end_date_time"],
"properties": {
"start_date_time": {
"type": "integer"
},
"end_date_time": {
"type": "integer",
"description": "Must be greater than start_date_time"
}
},
"additionalProperties": false
},
{
"title": "Status transition",
"type": "object",
"required": ["status"],
"properties": {
"status": {
"type": "string",
"enum": ["COMPLETED", "CANCELLED"],
"description": "Allowed transitions: ONGOING to COMPLETED; SCHEDULED, READY or ONGOING to CANCELLED. Both target statuses are terminal. Transitioning an ONGOING event moves its end_date_time to the moment of the transition; cancelling an event that has not started keeps its planned window. Invalid transitions return 400."
}
},
"additionalProperties": false
}
]
},
"PageSettings": {
"type": "object",
"description": "Per-page display configuration. On update, provided fields are deep-merged into the current settings; omitted fields are left untouched.",
"properties": {
"incidents": {
"type": "object",
"description": "Incident display preferences for this page.",
"additionalProperties": true
},
"include_maintenances": {
"type": "object",
"description": "Maintenance display preferences for this page.",
"additionalProperties": true
},
"monitor_status_history_days": {
"type": "object",
"description": "Days of status history shown on the page, per device class.",
"properties": {
"desktop": {
"type": "integer",
"minimum": 1,
"maximum": 365,
"default": 90
},
"mobile": {
"type": "integer",
"minimum": 1,
"maximum": 365,
"default": 30
}
}
},
"monitor_layout_style": {
"type": "string",
"enum": ["default-list", "default-grid", "compact-list", "compact-grid"],
"default": "default-list",
"description": "How monitors are laid out on the status page."
},
"meta_page_title": {
"type": "string",
"description": "Per-page override for the meta title."
},
"meta_page_description": {
"type": "string",
"description": "Per-page override for the meta description."
},
"social_page_preview_image": {
"type": "string",
"description": "Per-page override for the social preview image."
}
},
"additionalProperties": true
}
}
}
}