openapi: 3.0.3 info: title: Quismon API description: | Quismon is a comprehensive monitoring and alerting platform that allows you to monitor HTTP/HTTPS endpoints, TCP services, and ping targets. Create checks, configure alert rules, and receive notifications through multiple channels including email, webhooks, and ntfy. ## Authentication Quismon API supports two authentication methods: 1. **JWT Tokens**: Used by the web dashboard. Include in the `Authorization` header as `Bearer `. Tokens are obtained via `/v1/auth/signup` or `/v1/auth/login` and are valid for 7 days. 2. **API Keys**: Used for programmatic access. Include in the `Authorization` header as `Bearer qm_`. API keys never expire but can be revoked via the dashboard. ## Rate Limiting API requests are rate limited to 1000 requests per minute per organization. ## Pagination List endpoints support pagination via `limit` and `offset` query parameters. Default limit is 50, maximum is 100. version: 1.0.0 contact: name: Quismon Support url: https://quismon.com license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.quismon.com description: Production API server - url: https://app.quismon.com description: Production server (alternative) - url: http://localhost:8080 description: Local development tags: - name: Authentication description: User authentication and registration endpoints - name: Checks description: Health check monitoring endpoints - name: Alert Rules description: Alert rule configuration endpoints - name: Notification Channels description: Notification channel management - name: Incidents description: Incident tracking and management - name: Check Results description: Check execution results and uptime statistics security: - bearerAuth: [] - apiKeyAuth: [] paths: /: get: summary: API root description: Returns basic API information and version tags: - System security: [] responses: '200': description: API information content: application/json: schema: type: object properties: data: type: object properties: message: type: string example: "Quismon API" version: type: string example: "v1" status: type: string example: "running" /health: get: summary: Health check description: Returns the health status of the API tags: - System security: [] responses: '200': description: API is healthy content: application/json: schema: type: object properties: data: type: object properties: status: type: string example: "healthy" /v1/auth/signup: post: summary: Register new user description: Create a new user account and organization. Returns a JWT token for immediate authentication. tags: - Authentication security: [] requestBody: required: true content: application/json: schema: type: object required: - email - password - name - organization_name properties: email: type: string format: email example: "user@example.com" password: type: string format: password minLength: 8 example: "securepassword123" name: type: string example: "John Doe" organization_name: type: string example: "Acme Inc" responses: '201': description: User created successfully content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/AuthResponse' '400': $ref: '#/components/responses/BadRequest' /v1/auth/login: post: summary: Authenticate user description: Login with email and password. Returns a JWT token valid for 7 days. tags: - Authentication security: [] requestBody: required: true content: application/json: schema: type: object required: - email - password properties: email: type: string format: email example: "user@example.com" password: type: string format: password example: "securepassword123" responses: '200': description: Login successful content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/AuthResponse' '401': $ref: '#/components/responses/Unauthorized' /v1/auth/me: get: summary: Get current user description: Returns the authenticated user's profile and organization tags: - Authentication responses: '200': description: User information content: application/json: schema: type: object properties: data: type: object properties: user: $ref: '#/components/schemas/User' organization: $ref: '#/components/schemas/Organization' '401': $ref: '#/components/responses/Unauthorized' /v1/checks: get: summary: List all checks description: Returns all health checks for the authenticated organization with their current health status tags: - Checks parameters: - name: limit in: query schema: type: integer default: 50 maximum: 100 - name: offset in: query schema: type: integer default: 0 responses: '200': description: List of checks content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/Check' meta: type: object properties: total: type: string '401': $ref: '#/components/responses/Unauthorized' post: summary: Create a check description: Create a new health check monitor tags: - Checks requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCheckRequest' examples: http_check: summary: HTTP/HTTPS check value: name: "Production API" type: "https" config: url: "https://api.example.com/health" method: "GET" expected_status_code: 200 timeout_seconds: 10 interval_seconds: 60 regions: ["us-east-1", "eu-west-1"] enabled: true tcp_check: summary: TCP port check value: name: "Database Server" type: "tcp" config: host: "db.example.com" port: 5432 timeout_seconds: 5 interval_seconds: 120 regions: ["us-east-1"] enabled: true ping_check: summary: Ping check value: name: "Gateway Router" type: "ping" config: host: "192.168.1.1" timeout_seconds: 3 packet_count: 4 interval_seconds: 300 regions: ["us-east-1"] enabled: true responses: '201': description: Check created content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Check' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /v1/checks/{id}: get: summary: Get a check description: Returns details for a specific check tags: - Checks parameters: - $ref: '#/components/parameters/checkId' responses: '200': description: Check details content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Check' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' put: summary: Update a check description: Update an existing health check tags: - Checks parameters: - $ref: '#/components/parameters/checkId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateCheckRequest' responses: '200': description: Check updated content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Check' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' delete: summary: Delete a check description: Permanently delete a health check and all associated data tags: - Checks parameters: - $ref: '#/components/parameters/checkId' responses: '204': description: Check deleted successfully '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' /v1/checks/{id}/results: get: summary: Get check results description: Returns execution results for a check with optional time filtering tags: - Check Results parameters: - $ref: '#/components/parameters/checkId' - name: from in: query description: Start time (RFC3339 format) schema: type: string format: date-time - name: to in: query description: End time (RFC3339 format) schema: type: string format: date-time - name: limit in: query schema: type: integer default: 100 maximum: 1000 responses: '200': description: Check results content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/CheckResult' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/checks/{id}/uptime: get: summary: Get uptime statistics description: Returns uptime percentage and statistics for a check tags: - Check Results parameters: - $ref: '#/components/parameters/checkId' - name: period in: query description: Time period for uptime calculation schema: type: string enum: [1h, 24h, 7d, 30d, 90d] default: 24h responses: '200': description: Uptime statistics content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/UptimeStats' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/checks/{id}/test: post: summary: Test a check description: Execute a check immediately and return the result tags: - Checks parameters: - $ref: '#/components/parameters/checkId' responses: '200': description: Test result content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/CheckResult' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/checks/{id}/alerts: get: summary: List alert rules for check description: Returns all alert rules configured for a specific check tags: - Alert Rules parameters: - $ref: '#/components/parameters/checkId' responses: '200': description: List of alert rules content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/AlertRule' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' post: summary: Create alert rule description: Create a new alert rule for a check tags: - Alert Rules parameters: - $ref: '#/components/parameters/checkId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateAlertRuleRequest' examples: consecutive_failures: summary: Alert on consecutive failures value: name: "Production down" condition_type: "consecutive_failures" threshold: 3 notification_channel_ids: ["550e8400-e29b-41d4-a716-446655440001"] response_time: summary: Alert on slow response value: name: "Slow API" condition_type: "response_time" threshold: 5000 notification_channel_ids: ["550e8400-e29b-41d4-a716-446655440001"] responses: '201': description: Alert rule created content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/AlertRule' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' /v1/checks/{id}/alerts/{ruleID}: get: summary: Get alert rule description: Returns details for a specific alert rule tags: - Alert Rules parameters: - $ref: '#/components/parameters/checkId' - $ref: '#/components/parameters/ruleId' responses: '200': description: Alert rule details content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/AlertRule' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' delete: summary: Delete alert rule description: Permanently delete an alert rule tags: - Alert Rules parameters: - $ref: '#/components/parameters/checkId' - $ref: '#/components/parameters/ruleId' responses: '204': description: Alert rule deleted successfully '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' /v1/notification-channels: get: summary: List notification channels description: Returns all notification channels for the organization tags: - Notification Channels responses: '200': description: List of notification channels content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/NotificationChannel' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' post: summary: Create notification channel description: Create a new notification channel tags: - Notification Channels requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateNotificationChannelRequest' examples: email: summary: Email channel value: name: "Engineering Team" type: "email" config: to: ["dev@example.com", "ops@example.com"] webhook: summary: Webhook channel value: name: "Slack Integration" type: "webhook" config: url: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXX" method: "POST" ntfy: summary: ntfy channel value: name: "Mobile Push" type: "ntfy" config: topic: "quismon-alerts" server: "https://ntfy.sh" responses: '201': description: Notification channel created content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/NotificationChannel' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/notification-channels/{id}: get: summary: Get notification channel description: Returns details for a specific notification channel tags: - Notification Channels parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Notification channel details content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/NotificationChannel' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' put: summary: Update notification channel description: Update an existing notification channel tags: - Notification Channels parameters: - name: id in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateNotificationChannelRequest' responses: '200': description: Notification channel updated content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/NotificationChannel' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' delete: summary: Delete notification channel description: Permanently delete a notification channel tags: - Notification Channels parameters: - name: id in: path required: true schema: type: string format: uuid responses: '204': description: Notification channel deleted successfully '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/incidents: get: summary: List incidents description: Returns all incidents for the organization tags: - Incidents parameters: - name: status in: query description: Filter by incident status schema: type: string enum: [active, resolved, acknowledged] - name: limit in: query schema: type: integer default: 50 maximum: 100 - name: offset in: query schema: type: integer default: 0 responses: '200': description: List of incidents content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/Incident' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/incidents/{id}: get: summary: Get incident description: Returns details for a specific incident tags: - Incidents parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Incident details content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Incident' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' /v1/incidents/{id}/acknowledge: post: summary: Acknowledge incident description: Mark an incident as acknowledged tags: - Incidents parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Incident acknowledged content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Incident' '404': $ref: '#/components/responses/NotFound' '401': $ref: '#/components/responses/Unauthorized' '501': $ref: '#/components/responses/NotImplemented' components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT token obtained from /v1/auth/login or /v1/auth/signup apiKeyAuth: type: http scheme: bearer description: API key with qm_ prefix (e.g., Bearer qm_1234567890abcdef) parameters: checkId: name: id in: path description: Check UUID required: true schema: type: string format: uuid example: "550e8400-e29b-41d4-a716-446655440000" ruleId: name: ruleID in: path description: Alert rule UUID required: true schema: type: string format: uuid example: "660e8400-e29b-41d4-a716-446655440000" schemas: User: type: object properties: id: type: string format: uuid email: type: string format: email name: type: string created_at: type: string format: date-time updated_at: type: string format: date-time Organization: type: object properties: id: type: string format: uuid name: type: string slug: type: string created_at: type: string format: date-time updated_at: type: string format: date-time AuthResponse: type: object properties: token: type: string description: JWT token valid for 7 days user: $ref: '#/components/schemas/User' organization: $ref: '#/components/schemas/Organization' Check: type: object properties: id: type: string format: uuid org_id: type: string format: uuid name: type: string type: type: string enum: [http, https, tcp, ping] config: type: object description: Check-specific configuration (varies by type) interval_seconds: type: integer minimum: 60 description: Check interval in seconds (minimum 60) regions: type: array items: type: string description: Monitoring regions enabled: type: boolean health_status: type: string enum: [healthy, unhealthy, unknown] description: Current health status based on latest check result last_checked: type: string format: date-time nullable: true description: Timestamp of last check execution created_at: type: string format: date-time updated_at: type: string format: date-time CreateCheckRequest: type: object required: - name - type - config - interval_seconds properties: name: type: string minLength: 1 type: type: string enum: [http, https, tcp, ping] config: type: object description: | Configuration object varies by check type: - http/https: {url, method, expected_status_code, timeout_seconds, headers (optional)} - tcp: {host, port, timeout_seconds} - ping: {host, timeout_seconds, packet_count} interval_seconds: type: integer minimum: 60 regions: type: array items: type: string default: ["us-east-1"] enabled: type: boolean default: true UpdateCheckRequest: type: object properties: name: type: string type: type: string enum: [http, https, tcp, ping] config: type: object interval_seconds: type: integer minimum: 60 regions: type: array items: type: string enabled: type: boolean CheckResult: type: object properties: id: type: string format: uuid check_id: type: string format: uuid region: type: string success: type: boolean response_time_ms: type: integer description: Response time in milliseconds status_code: type: integer nullable: true description: HTTP status code (for HTTP/HTTPS checks) error_message: type: string nullable: true metadata: type: object nullable: true description: Additional check-specific data time: type: string format: date-time UptimeStats: type: object properties: uptime_percentage: type: number format: float minimum: 0 maximum: 100 total_checks: type: integer successful_checks: type: integer failed_checks: type: integer avg_response_time_ms: type: number format: float period: type: string AlertRule: type: object properties: id: type: string format: uuid check_id: type: string format: uuid name: type: string condition_type: type: string enum: [consecutive_failures, response_time, status_code, ssl_expiry] threshold: type: number description: Threshold value (meaning varies by condition_type) notification_channel_ids: type: array items: type: string format: uuid enabled: type: boolean created_at: type: string format: date-time updated_at: type: string format: date-time CreateAlertRuleRequest: type: object required: - name - condition_type - threshold - notification_channel_ids properties: name: type: string condition_type: type: string enum: [consecutive_failures, response_time, status_code, ssl_expiry] threshold: type: number notification_channel_ids: type: array items: type: string format: uuid minItems: 1 NotificationChannel: type: object properties: id: type: string format: uuid org_id: type: string format: uuid name: type: string type: type: string enum: [email, webhook, ntfy, slack, pagerduty] config: type: object description: Channel-specific configuration enabled: type: boolean created_at: type: string format: date-time updated_at: type: string format: date-time CreateNotificationChannelRequest: type: object required: - name - type - config properties: name: type: string type: type: string enum: [email, webhook, ntfy, slack, pagerduty] config: type: object description: | Configuration varies by type: - email: {to: [emails]} - webhook: {url, method, headers (optional)} - ntfy: {topic, server (optional)} - slack: {webhook_url} - pagerduty: {routing_key} UpdateNotificationChannelRequest: type: object properties: name: type: string config: type: object enabled: type: boolean Incident: type: object properties: id: type: string format: uuid check_id: type: string format: uuid alert_rule_id: type: string format: uuid status: type: string enum: [active, acknowledged, resolved] severity: type: string enum: [critical, warning, info] title: type: string description: type: string started_at: type: string format: date-time acknowledged_at: type: string format: date-time nullable: true resolved_at: type: string format: date-time nullable: true created_at: type: string format: date-time Error: type: object properties: error: type: string description: Error message responses: BadRequest: description: Bad request content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Invalid request body" Unauthorized: description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Missing Authorization header" NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Check not found" NotImplemented: description: Endpoint not yet implemented content: application/json: schema: $ref: '#/components/schemas/Error' example: error: "Endpoint not yet implemented"