ChatCLI AIOps Platform REST API — incidents, SLOs, runbooks, approvals, postmortems, analytics, audit, federation, and health.
The ChatCLI AIOps Platform REST API is served by the operator and gives programmatic access to the AIOps resources (Issues, RemediationPlans, AIInsights, Runbooks, ApprovalRequests, SLOs, PostMortems, AuditEvents, ClusterRegistrations and policies). Responses follow Kubernetes-like patterns (apiVersion + kind + metadata/resourceMeta + spec + status), with API key authentication, three roles and a per-client rate limit.
Incidents
Detection, ack, snooze, timeline, remediation, and resolution
Runbooks
Full CRUD for runbooks
Analytics
MTTD, MTTR, trends, top resources, capacity, compliance, cost
The API (and the web dashboard at /) listens on the operator pod, port 8090, exposed as port api of the Service chatcli-operator in the operator namespace (chatcli-system by default). It is not served by the Service of an Instance (that one is the gRPC server on 50051).
The port comes from the chart value api.port (default 8090), which sets the CHATCLI_AIOPS_PORT environment variable of the operator. To serve HTTPS (TLS 1.3 minimum), set CHATCLI_AIOPS_TLS_CERT and CHATCLI_AIOPS_TLS_KEY to certificate and key files inside the operator container (chart: security.apiTLS.certFile / security.apiTLS.keyFile). The operator chart has no extraVolumes value, so the files must be provided by another means (for example a patched Deployment); alternatively terminate TLS at an Ingress or gateway in front of the Service. Without both variables the API is plain HTTP.
Multiple operator replicas. Every replica serves the REST API and the dashboard on 8090, so a Service with several replicas can route a request to any pod. Reads are answered by any replica; a manual resolve accepted by a replica that is not the leader is completed by the leader’s Issue reconciler.
Roles are ordered viewer < operator < admin; each endpoint requires a minimum role (see the endpoint table). These three strings are the only valid roles: a key with any other role (for example superadmin or readonly) is accepted as a key but gets 403 on every endpoint.
viewer
Read-only. Every GET endpoint. Ideal for dashboards and observability tools.
operator
Daily ops. Everything viewer can do, plus the POST actions (acknowledge, snooze, resolve, approve, reject, postmortem review/close/feedback) and runbook create/update.
admin
Full access. Everything operator can do, plus DELETE /runbooks/{name}.
ConfigMap chatcli-operator-config, key api-keys (fallback, used only when the Secret does not exist)
The value is a YAML list of {key, role, name, description} entries. name is optional: it is the identity recorded on the approval decisions the key takes (falling back to description, then to a key-<hash> fingerprint), and a quorum counts each key once, so give each approver their own key. The operator chart renders the Secret only with apiKeys.create: true (the keys are then stored in the Helm release); otherwise you create it:
The operator polls the Secret and ConfigMap every 30 seconds and hot-reloads the keys without a restart: adding or removing an entry takes effect within about 30 s.
No keys configured = every /api/ call returns 401. If neither object holds a valid key, the API is closed (fail-closed). Setting CHATCLI_OPERATOR_DEV_MODE=true on the operator (chart: security.devMode: true) instead lets every request through as admin without a key — for local development only, never in production. Any boolean-true value counts (true, TRUE, 1, t, case-insensitive), for the auth check, the rate limiter and the startup log alike.Keys follow their source: an empty list leaves no valid key, a Secret without an api-keys entry falls back to the ConfigMap, and deleting both the Secret and the ConfigMap revokes every loaded key on the next poll (within about 30 s, 401 from then on). An api-keys entry that is not valid YAML keeps the last valid key set in force and is logged once per version. A read error other than not found also keeps the keys in force, so neither a typo nor an API server hiccup locks everyone out. Startup applies the same rules as the poll.
Try it without a cluster. From the operator/ directory of the repository, make dash-preview serves the dashboard and this API over synthetic data at http://127.0.0.1:8085/ with the API key preview (admin role). Override the address with DASHPREVIEW_ADDR.
The API allows 30 requests per minute per client host for requests that carry no valid API key (token bucket, bursts of up to 30, refilled continuously at 0.5 req/s), and 600 requests per minute per valid API key (bursts of up to 600, refilled at 10 req/s), keyed by a digest of the key. The limit runs before authentication; the per-key limit is the same for every role. Forwarding headers are not honored, so behind a proxy every unauthenticated caller shares the proxy’s host bucket. Idle buckets are evicted after 10 minutes.When it is exceeded the operator returns 429 Too Many Requests with the standard error envelope (rate limit exceeded: N requests per minute) and a Retry-After header with the seconds until the bucket holds a token again (2 for the host limit, 1 for the key limit). No X-RateLimit-* headers are sent. Implement backoff in production clients, and keep dashboards or scrapers that poll many endpoints within the budget.
Cross-origin browser requests are denied by default: no CORS headers are sent until an origin is configured. Configure it with environment variables on the operator (or the matching chart values under security.*):
Variable
Chart value
Meaning
CHATCLI_CORS_ALLOWED_ORIGINS
security.corsAllowedOrigins (list)
Comma-separated allowed origins, or *
CHATCLI_CORS_ORIGIN
security.corsOrigin
A single allowed origin (added to the list)
CHATCLI_CORS_ALLOWED_METHODS
security.corsAllowedMethods
Allowed methods (default GET, POST, PUT, DELETE, OPTIONS)
CHATCLI_CORS_ALLOW_CREDENTIALS
security.corsAllowCredentials
true to allow credentials
Allowed request headers are Content-Type, X-API-Key and Authorization; preflight responses are cached for 1 hour. The dashboard served by the operator itself is same-origin and needs no CORS configuration.
X-API-Key missing or invalid, or no keys configured
403
Forbidden
Role below the endpoint’s minimum, an unknown role, or the operator’s RBAC does not allow creating the runbook
404
Not Found
Resource does not exist, or unknown path/method combination
405
Method Not Allowed
Non-GET request to a read-only group (analytics, clusters, policies, audit, federation)
409
Conflict
Invalid state for the operation (for example resolving an already resolved incident, or deciding on an approval request that is no longer Pending or that the same API key already decided), a concurrent modification, or creating a runbook whose name already exists
422
Unprocessable Entity
The Kubernetes API server rejected a runbook being created (for example a value outside the CRD enums)
429
Too Many Requests
Rate limit exceeded — see Retry-After
500
Internal Server Error
Kubernetes API failure — inspect the operator logs
The response includes metadata.totalCount so you can compute the total number of pages. Invalid values fall back to the defaults.Most lists accept namespace (omitted = all namespaces). Incidents, postmortems, audit events and the analytics endpoints also accept the time filters from / to (RFC 3339, for example 2026-03-19T00:00:00Z), applied to the resource’s creation time (the event time for audit). Unparseable times are ignored.