{ "openapi": "3.1.0", "info": { "title": "YoVision Bell loopback alert console", "version": "1.0.0", "description": "Engineering-only, loopback API for the Event to Rule to Alert to acknowledgement vertical slice. Tenant, site and actor context are server-side configuration, never client input." }, "servers": [{"url": "http://127.0.0.1:{port}/bell-console/api/v1", "variables": {"port": {"default": "8081"}}}], "security": [{"consoleBearer": []}], "paths": { "/alerts": { "get": { "operationId": "listAlerts", "parameters": [ {"name": "state", "in": "query", "schema": {"$ref": "#/components/schemas/AlertState"}}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 16}}, {"name": "cursor", "in": "query", "schema": {"$ref": "#/components/schemas/AlertId"}} ], "responses": { "200": {"description": "Stable newest-first page", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertPage"}}}}, "400": {"$ref": "#/components/responses/BadRequest"}, "401": {"$ref": "#/components/responses/Unauthorized"} } } }, "/alerts/{alert_id}": { "get": { "operationId": "getAlert", "parameters": [{"$ref": "#/components/parameters/AlertId"}], "responses": { "200": {"description": "Alert, related event facts and append-only transitions", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertDetail"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"} } } }, "/alerts/{alert_id}:ack": { "post": { "operationId": "acknowledgeAlert", "parameters": [{"$ref": "#/components/parameters/AlertId"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandBody"}}}}, "responses": { "200": {"description": "First acknowledgement or exact idempotent replay", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandResponse"}}}}, "409": {"description": "Already acknowledged (including actual first actor/time), or reused key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandResponse"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"} } } }, "/alerts/{alert_id}:close": { "post": { "operationId": "closeAlert", "parameters": [{"$ref": "#/components/parameters/AlertId"}, {"$ref": "#/components/parameters/IdempotencyKey"}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandBody"}}}}, "responses": { "200": {"description": "Close after acknowledgement or exact idempotent replay", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandResponse"}}}}, "409": {"description": "Acknowledgement required, already closed, or reused key", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommandResponse"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"} } } } }, "components": { "securitySchemes": {"consoleBearer": {"type": "http", "scheme": "bearer", "description": "External engineering-console token; never persisted in browser storage."}}, "parameters": { "AlertId": {"name": "alert_id", "in": "path", "required": true, "schema": {"$ref": "#/components/schemas/AlertId"}}, "IdempotencyKey": {"name": "Idempotency-Key", "in": "header", "required": true, "schema": {"type": "string", "minLength": 8, "maxLength": 128, "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]*$"}} }, "responses": { "BadRequest": {"description": "Invalid bounded input", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "Unauthorized": {"description": "Missing or invalid console token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "NotFound": {"description": "Alert absent from configured tenant/site", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}} }, "schemas": { "AlertId": {"type": "string", "pattern": "^alt_[0-9A-HJKMNP-TV-Z]{26}$"}, "AlertState": {"type": "string", "enum": ["open", "acknowledged", "closed"]}, "Severity": {"type": "string", "enum": ["low", "medium", "high", "critical"]}, "AlertSummary": {"type": "object", "additionalProperties": false, "required": ["id", "severity", "title", "state", "rule_key", "rule_version", "created_at"], "properties": {"id": {"$ref": "#/components/schemas/AlertId"}, "severity": {"$ref": "#/components/schemas/Severity"}, "title": {"type": "string", "minLength": 1, "maxLength": 120}, "state": {"$ref": "#/components/schemas/AlertState"}, "rule_key": {"type": "string"}, "rule_version": {"type": "integer", "minimum": 1}, "created_at": {"type": "string", "format": "date-time"}}}, "AlertPage": {"type": "object", "additionalProperties": false, "required": ["items", "next_cursor"], "properties": {"items": {"type": "array", "maxItems": 100, "items": {"$ref": "#/components/schemas/AlertSummary"}}, "next_cursor": {"oneOf": [{"$ref": "#/components/schemas/AlertId"}, {"type": "null"}]}}}, "EventRef": {"type": "object", "additionalProperties": false, "required": ["id", "device_id", "kind", "severity", "occurred_at"], "properties": {"id": {"type": "string", "pattern": "^evt_[0-9A-HJKMNP-TV-Z]{26}$"}, "device_id": {"type": "integer", "minimum": 1}, "kind": {"type": "string"}, "severity": {"$ref": "#/components/schemas/Severity"}, "occurred_at": {"type": "string", "format": "date-time"}}}, "Transition": {"type": "object", "additionalProperties": false, "required": ["sequence", "from_state", "to_state", "actor_ref", "note", "occurred_at"], "properties": {"sequence": {"type": "integer", "minimum": 1}, "from_state": {"oneOf": [{"$ref": "#/components/schemas/AlertState"}, {"type": "null"}]}, "to_state": {"$ref": "#/components/schemas/AlertState"}, "actor_ref": {"type": "string"}, "note": {"oneOf": [{"type": "string", "maxLength": 500}, {"type": "null"}]}, "occurred_at": {"type": "string", "format": "date-time"}}}, "AlertDetail": {"allOf": [{"$ref": "#/components/schemas/AlertSummary"}, {"type": "object", "additionalProperties": false, "required": ["events", "transitions", "evidence_status", "delivery_status"], "properties": {"events": {"type": "array", "items": {"$ref": "#/components/schemas/EventRef"}}, "transitions": {"type": "array", "items": {"$ref": "#/components/schemas/Transition"}}, "evidence_status": {"const": "not_enabled"}, "delivery_status": {"const": "not_enabled"}}}]}, "CommandBody": {"type": "object", "additionalProperties": false, "properties": {"note": {"oneOf": [{"type": "string", "maxLength": 500}, {"type": "null"}]}}}, "CommandResponse": {"type": "object", "additionalProperties": false, "required": ["alert_id", "state", "actor_ref", "occurred_at"], "properties": {"alert_id": {"$ref": "#/components/schemas/AlertId"}, "state": {"$ref": "#/components/schemas/AlertState"}, "actor_ref": {"type": "string"}, "occurred_at": {"type": "string", "format": "date-time"}, "code": {"type": "string", "enum": ["already_acknowledged", "acknowledgement_required", "already_closed", "invalid_state"]}}}, "Error": {"type": "object", "additionalProperties": false, "required": ["code", "message"], "properties": {"code": {"type": "string"}, "message": {"type": "string"}}} } } }