SLO API
Create, search, and query Service Level Objectives with an API key.
Use the SLO API to provision service-level objectives and retrieve their evaluated status, budget history, and burn rate from automation. For arbitrary rolling SLO metric queries, use the Metrics API with the SLO metrics listed below.
Authentication
For API-key access, send the key in X-API-Key:
X-API-Key: <your-api-key>The key must have the slo scope. Creating, updating, and deleting SLOs also
requires write access to that module; read-only keys can use the read and filter
endpoints. Interactive callers may instead use their access-token cookie or an
Authorization: Bearer <token> header. See
Authentication.
Application responses normally use this envelope:
{ "data": {}, "error": false, "message": "..." }Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/slo | Create an SLO. |
PUT | /api/slo | Replace an SLO. |
DELETE | /api/slo/{id} | Delete an SLO. |
GET | /api/slo/{id} | Get one SLO and its current evaluation summary. |
POST | /api/slo/list | List or search SLOs. |
POST | /api/slo/filters | Return values and counts for SLO facets. |
POST | /api/slo/filter/search | Search values within one SLO facet. |
GET | /api/slo/{id}/metrics | Aggregate SLO metrics over a range. |
GET | /api/slo/{id}/timeseries | SLO budget burndown and event counts over time. |
GET | /api/slo/{id}/burn-rate/timeseries | Rolling 1-hour and 6-hour burn rates. |
POST | /api/slo/preview | Calculate an SLO result without saving it. |
{id} is the SLO UUID returned when it is created.
Create an SLO
POST /api/slo creates a by_count SLO. The denominator is the total event
query; the numerator is the matching good-event query. This example defines a
99.9% successful-request objective from a Prometheus metric:
curl -s -X POST "https://<your-kubesense-host>/api/slo" \
-H "X-API-Key: $KUBESENSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Checkout availability",
"description": "Successful checkout requests",
"slo_type": "by_count",
"slo_target_percentage": 99.9,
"evaluation_time_interval_seconds": 60,
"evaluation_window_days": 30,
"total_events_filter": {
"selectedMode": "metrics",
"promql": "sum(rate(http_requests_total{service=\"checkout\"}[1m]))"
},
"good_events_filter": {
"selectedMode": "metrics",
"promql": "sum(rate(http_requests_total{service=\"checkout\",code!~\"5..\"}[1m]))"
},
"alert_types": [],
"notification_channels": []
}'The response data is the new SLO UUID.
| Field | Type | Description |
|---|---|---|
name | string | SLO name. |
description | string | Optional description. |
slo_type | string | Send by_count (default), time_slice, or alert. |
slo_target_percentage | number | Target compliance percentage, such as 99.9. |
evaluation_time_interval_seconds | integer | Required evaluation interval in seconds. |
evaluation_window_days | integer | Rolling evaluation window in days. |
good_events_filter | object | Good-event query; used by by_count. |
total_events_filter | object | Total-event query. Clients should provide it for every SLO type. |
operation, threshold_value | string, integer | Required for time_slice; compare each slice's total-query value to the threshold. Operations: lt, lte, gt, gte, eq, and their long forms. |
alert_types | array | Generated-alert types: burn_rate_fast, burn_rate_slow, error_budget_critical, or error_budget_low. Other values are ignored. |
notification_channels | integer array | Notification channel IDs for generated SLO alerts. |
warning_target_percentage | number | Optional warning threshold. |
When evaluate_from is omitted, KubeSense starts evaluation at the current time,
rounded to the evaluation interval. evaluation_start_time is never stored before
evaluate_from.
Event query structure
good_events_filter and total_events_filter identify the data source with
selectedMode: metrics, logs, or traces. Metrics queries use PromQL;
logs and traces use unified_filter, fields, and optional grouping.
Use these query filters to scope the SLO to a workload, namespace, cluster, or
other service dimension rather than top-level SLO metadata fields.
{
"selectedMode": "traces",
"value_operation": "row_count",
"groupBy": [
{ "field": "workload", "type": "string", "is_attribute": false }
],
"unified_filter": {
"type": "common",
"common_filter": [
{ "field": "return_code", "operation": "IN", "values": ["200", "201"] }
]
}
}For metrics, group in PromQL, for example
sum by (service)(rate(http_requests_total[5m])). Each group becomes a distinct
SLO series. See Log & Trace Fields for valid
logs/traces fields.
The Alerts API query-object reference describes the same metrics, logs, and traces query input conventions in more detail.
Get an SLO
GET /api/slo/{id} returns the stored configuration plus current SLO status,
recent evaluation totals, compliance, and error-budget balance. current_time
is a required RFC3339 query parameter and selects the point at which summaries
are calculated.
curl -s "https://<your-kubesense-host>/api/slo/$SLO_ID?current_time=2026-09-08T00:00:00Z" \
-H "X-API-Key: $KUBESENSE_API_KEY"The response includes good_events_filter and total_events_filter in their
stored query shape, status_eval, burn_rate_status, and summaries for the last
2 hours, 24 hours, 7 days, and 28 days.
Search and filters
List or search SLOs
POST /api/slo/list accepts pagination and a filter array.
current_time and lifecycle status are required query parameters; use
status=active for normal active SLOs. Use name for a substring search.
curl -s -X POST "https://<your-kubesense-host>/api/slo/list?current_time=2026-09-08T00:00:00Z&status=active&page=1&page_size=50" \
-H "X-API-Key: $KUBESENSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "checkout",
"filters": [
{ "field": "cluster", "operation": "IN", "values": ["production"] },
{ "field": "status", "operation": "IN", "values": ["breached"] }
]
}'Supported SLO filter fields are workload, namespace, cluster, name,
metric, status (also available as status_eval), and burn_rate (also
available as burn_rate_status). A filter has this shape:
{ "field": "namespace", "operation": "IN", "values": ["payments"] }Get filter facets
POST /api/slo/filters returns each matching value with its count. With no
filter_fields, it returns workload, namespace, cluster, metric,
status, and burn_rate.
curl -s -X POST \
"https://<your-kubesense-host>/api/slo/filters?filter_fields=cluster&filter_fields=status" \
-H "X-API-Key: $KUBESENSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filters": [{ "field": "namespace", "operation": "IN", "values": ["payments"] }] }'filter_fields can be repeated or comma-separated. A facet excludes its own
active filter when calculating its values, while retaining all other filters.
Unknown filter_fields are omitted from the response.
Search a facet's values
POST /api/slo/filter/search searches one supported facet. filter_field is
required; search and page_size are optional. page_size defaults to 25.
An unsupported filter_field currently returns 500; use the supported field
list above.
curl -s -X POST \
"https://<your-kubesense-host>/api/slo/filter/search?filter_field=workload&search=check&page_size=25" \
-H "X-API-Key: $KUBESENSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filters": [{ "field": "cluster", "operation": "IN", "values": ["production"] }] }'SLO dashboard data
Use the following endpoints for the four SLO values and charts shown in the Service Levels UI.
1. SLO compliance
GET /api/slo/{id}/metrics returns SLO compliance for a requested evaluation
range in data.slo_compliance_percentage. from_time and to_time are required
RFC3339 timestamps.
curl -s "https://<your-kubesense-host>/api/slo/$SLO_ID/metrics?from_time=2026-09-01T00:00:00Z&to_time=2026-09-08T00:00:00Z" \
-H "X-API-Key: $KUBESENSE_API_KEY"For grouped SLOs, data.groups[].slo_compliance_percentage contains the value
for each individual group. The cumulative all-groups evaluation has
group_key: "*" internally and is returned as the top-level
data.slo_compliance_percentage, not as an item in data.groups.
2. Error budget balance
The same GET /api/slo/{id}/metrics request returns the remaining error budget
for the requested range in data.error_budget_balance. For grouped SLOs, use
data.groups[].error_budget_balance for an individual group; the cumulative
group_key: "*" value is returned as top-level data.error_budget_balance.
3. Burn rates
GET /api/slo/{id}/burn-rate/timeseries returns rolling burn-rate chart data as
burn_rate_1h and burn_rate_6h. It accepts optional from_time, to_time,
group_key, and bucket_duration_seconds query parameters. Omitting the range
uses the previous seven days.
curl -s "https://<your-kubesense-host>/api/slo/$SLO_ID/burn-rate/timeseries?from_time=2026-09-01T00:00:00Z&to_time=2026-09-08T00:00:00Z&bucket_duration_seconds=3600" \
-H "X-API-Key: $KUBESENSE_API_KEY"4. Error budget balance time series
GET /api/slo/{id}/timeseries returns three resources: burndown (the
error-budget balance calculated from the requested range), good_events, and
bad_events. Use the burndown resource for the error-budget-balance time
series. For the SLO's rolling configured-window balance, query
kubesense_slo_error_budget_balance through Explore.
curl -s "https://<your-kubesense-host>/api/slo/$SLO_ID/timeseries?from_time=2026-09-01T00:00:00Z&to_time=2026-09-08T00:00:00Z&bucket_duration_seconds=3600" \
-H "X-API-Key: $KUBESENSE_API_KEY"group_key optionally limits a grouped SLO to one group. Omit the range for the
default last seven days. Omit bucket_duration_seconds to let KubeSense select a
bucket size for the range; the selected value is returned as
bucket_duration_seconds.
Both time-series responses include a top-level bucket_duration_seconds with
the bucket size actually used.
Other management endpoints
PUT /api/slo replaces an SLO. Send the same complete body as creation with
the existing UUID in id; omitted fields are written with their zero value.
DELETE /api/slo/{id} soft-deletes an SLO and removes its generated alert rules.
warning: Do not update an existing SLO when the change redefines its SLI, such as changing the good-event or total-event query, source, grouping, SLO type, or time-slice threshold. Existing evaluations were calculated with the previous definition, so mixing them with the new definition makes historical good and bad event data unreliable. Soft-delete the old SLO and create a new SLO instead.
POST /api/slo/preview accepts the create query fields and returns the
calculated result without persisting it.
For an alert preview, put the source alert-rule UUIDs in
total_events_filter.alert_ids. Preview also accepts optional RFC3339
from_time and to_time fields to select the calculation range.
Query rolling SLO metrics
For arbitrary rolling historical queries, call POST /api/explore/query-range.
SLO evaluations are also written as Prometheus-compatible metrics. Always select
the pooled SLO series with slo_group="*"; otherwise a grouped SLO returns the
pooled series and every group.
curl -s -X POST "https://<your-kubesense-host>/api/explore/query-range" \
-H "X-API-Key: $KUBESENSE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"queries": {
"A": {
"selectedMode": "metrics",
"from_time": "2026-09-01T00:00:00Z",
"to_time": "2026-09-08T00:00:00Z",
"promql": "kubesense_slo_error_budget_balance{slo_id=\"<slo-id>\",slo_group=\"*\"}",
"step": 3600,
"page": 1,
"page_size": 50
}
}
}'For a grouped SLO, replace slo_group="*" with a group selector such as
service="checkout". Group field names that are not valid Prometheus labels are
converted to underscores.
| Metric | Use |
|---|---|
kubesense_slo_evaluated_events_total | Evaluated total events or slices per evaluation. |
kubesense_slo_evaluated_events_good | Good events or slices per evaluation. |
kubesense_slo_evaluated_events_bad_percent | Bad-event percentage per evaluation. |
kubesense_slo_error_budget_balance | Remaining error-budget percentage across the SLO window. |
kubesense_slo_burn_rate | Budget-consumption rate; select window="1h", "2h", or "6h". |
kubesense_slo_breached | 1 when the evaluation is below target, otherwise 0. |
kubesense_slo_status | Current status represented as a labeled value of 1. |
kubesense_slo_burn_rate_status | Current burn-rate status represented as a labeled value of 1. |
All SLO metrics have slo_id, slo_group, and target_percentage labels.
kubesense_slo_error_budget_balance additionally has error_budget and
window; burn-rate metrics have window. Status metrics carry status.
Errors
| Status | Meaning |
|---|---|
400 | Invalid request body or a missing request-bound parameter, such as filter_field. |
401 | Missing, invalid, or expired authentication credentials. |
403 | An API key is outside the slo scope, or the caller has read-only access to an SLO write endpoint. |
500 | Evaluation, query, or persistence failure. Several semantic validation failures, including missing current_time on list/get, zero evaluation interval on create, and an unsupported filter_field on /filter/search, also currently return 500. |