openapi: 3.0.3 info: title: Kao API description: | Kao is a minimalist system status monitor that uses ASCII emotes to represent system health. ## Priority System Events use a priority system where lower numbers indicate higher priority: - **1 (Critical)**: System failure - red, shaking - **2 (Warning)**: Degraded state - yellow, breathing - **3 (Notify)**: Informational alert - blue, popping - **4 (Optimal)**: All systems healthy - green, varies ## TTL/Heartbeat Pattern Events can have a TTL (time-to-live) that auto-expires them. Detectors typically send heartbeat events that expire if not refreshed, indicating loss of communication. version: 1.4.0 license: name: MIT servers: - url: http://192.168.2.114:5100 description: Local development server paths: /event: post: summary: Register an event description: | Register or update a system event. Events are identified by their ID and will overwrite any existing event with the same ID. Use TTL for heartbeat-style monitoring where absence of updates indicates a problem. operationId: postEvent requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/EventRequest" examples: critical: summary: Critical event value: id: "disk_root" priority: 1 message: "Root disk 98% full" heartbeat: summary: Heartbeat with TTL value: id: "cpu_monitor" priority: 4 message: "CPU nominal" ttl: 60 responses: "200": description: Event registered successfully content: application/json: schema: $ref: "#/components/schemas/EventResponse" "400": description: Invalid request content: application/json: schema: $ref: "#/components/schemas/Error" /clear-all: post: summary: Clear all events description: | Clear all active events at once. Used by the frontend when the display is tapped to dismiss warnings and critical alerts. operationId: clearAllEvents responses: "200": description: All events cleared content: application/json: schema: $ref: "#/components/schemas/ClearAllResponse" /clear: post: summary: Clear an event description: Remove an event by its ID. Use this when a condition has resolved. operationId: clearEvent requestBody: required: true content: application/json: schema: type: object required: - id properties: id: type: string description: Event identifier to clear example: "disk_root" responses: "200": description: Event cleared successfully content: application/json: schema: $ref: "#/components/schemas/ClearResponse" "400": description: Missing required field content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Event not found content: application/json: schema: $ref: "#/components/schemas/Error" /notify: post: summary: Send a notification description: | Send a temporary notification with optional custom display properties. Designed for Home Assistant integration. Notifications auto-expire after the specified duration. operationId: notify requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/NotifyRequest" examples: simple: summary: Simple notification value: message: "Doorbell rang" duration: 10 custom: summary: Custom notification value: message: "Welcome home!" duration: 10 emote: "(`-´)ゞ" color: "#00FF88" animation: "celebrating" sound: "chime" responses: "200": description: Notification sent content: application/json: schema: $ref: "#/components/schemas/NotifyResponse" /sleep: post: summary: Enter sleep mode description: | Put Kao into sleep mode. The display will show a sleeping emote with dimmed colors. All events are preserved but not displayed until wake. operationId: sleep responses: "200": description: Entered sleep mode content: application/json: schema: $ref: "#/components/schemas/SleepResponse" /wake: post: summary: Exit sleep mode description: Wake Kao from sleep mode and resume normal status display. operationId: wake responses: "200": description: Exited sleep mode content: application/json: schema: $ref: "#/components/schemas/WakeResponse" /status: get: summary: Get current status description: | Returns the current display state including the active emote, color, animation, and list of active events. The frontend polls this endpoint. operationId: getStatus responses: "200": description: Current status content: application/json: schema: $ref: "#/components/schemas/Status" /events: get: summary: List all active events description: Returns all currently active events with their full details. operationId: listEvents responses: "200": description: List of active events content: application/json: schema: $ref: "#/components/schemas/EventList" components: schemas: EventRequest: type: object required: - id - priority properties: id: type: string description: Unique identifier for this event example: "cpu_high" priority: type: integer minimum: 1 maximum: 4 description: | Event priority (1=Critical, 2=Warning, 3=Notify, 4=Optimal) example: 2 message: type: string description: Optional message to display example: "CPU at 90%" ttl: type: integer description: Time-to-live in seconds. Event auto-expires after this duration. example: 60 EventResponse: type: object properties: status: type: string example: "ok" current_state: $ref: "#/components/schemas/Status" ClearAllResponse: type: object properties: status: type: string example: "cleared" count: type: integer description: Number of events that were cleared example: 2 current_state: $ref: "#/components/schemas/Status" ClearResponse: type: object properties: status: type: string example: "cleared" current_state: $ref: "#/components/schemas/Status" NotifyRequest: type: object properties: message: type: string description: Text to display below the emote example: "Someone at the door" duration: type: integer description: Seconds before auto-expire default: 5 example: 10 emote: type: string description: Custom emote to display (overrides default) example: "( °o°)" color: type: string description: Custom color in hex format pattern: "^#[0-9A-Fa-f]{6}$" example: "#FF9900" animation: type: string description: Animation style enum: - breathing - shaking - popping - celebrating - floating - bouncing - swaying example: "popping" sound: type: string description: Sound effect to play enum: - chime - alert - warning - critical - success - notify - none example: "chime" NotifyResponse: type: object properties: status: type: string example: "ok" id: type: string description: Generated event ID example: "ha_notify_1704067200000" current_state: $ref: "#/components/schemas/Status" SleepResponse: type: object properties: status: type: string example: "sleeping" current_state: $ref: "#/components/schemas/Status" WakeResponse: type: object properties: status: type: string example: "awake" current_state: $ref: "#/components/schemas/Status" Status: type: object properties: current_state: type: string description: Current state name enum: - critical - warning - notify - optimal - sleeping example: "optimal" active_emote: type: string description: ASCII emote to display example: "( ^_^)" color: type: string description: Display color in hex example: "#00FF00" animation: type: string description: Current animation example: "breathing" message: type: string description: Status message example: "Optimal" sound: type: string description: Sound to play (only present when triggered) example: "chime" active_events: type: array items: $ref: "#/components/schemas/ActiveEvent" last_updated: type: string format: date-time description: ISO 8601 timestamp example: "2024-01-01T12:00:00" ActiveEvent: type: object properties: id: type: string example: "cpu_monitor" priority: type: integer example: 4 message: type: string example: "CPU nominal" EventList: type: object properties: events: type: object additionalProperties: type: object properties: priority: type: integer message: type: string timestamp: type: number ttl: type: number Error: type: object properties: error: type: string example: "Missing required fields: id, priority"