Dash0 acquires Polar Signals

Last updated: October 2, 2026

Use the SLO API

Authentication, endpoints, and the OpenSLO SLO object — including the supported OpenSLO subset and the Dash0-specific metadata.

SLOs can be created and managed through the Dash0 API using an OpenSLO v1 SLO definition (apiVersion: openslo/v1, kind: SLO). Dash0 implements a subset of the specification. The same SLOs can also be created and edited in the UI; see Create SLOs.

Authentication

Calls require an Authorization: Bearer <token> header using a Dash0 auth token (format auth_...). Create and manage tokens in Organization Settings › Auth Tokens (Admins only).

  • Creating, updating, or deleting an SLO requires a token with the All permissions (*) option.
  • Reading SLOs (GET) requires at least the Reading (*:read) option. A Reading token is rejected with 403 Forbidden on create, update, or delete.
  • A token with only the Ingesting option gets 403 Forbidden on every SLO call.

Endpoints

The SLO API lives on the Dash0 API host.

Method and pathPurpose
POST /api/slos?dataset={dataset}Create an SLO
GET /api/slos?dataset={dataset}[&originPrefix={prefix}]List SLOs, optionally only those whose dash0.com/origin starts with prefix
GET /api/slos/{originOrId}?dataset={dataset}[&format=yaml]Read the latest version of an SLO; format=yaml returns it as an OpenSLO YAML document
PUT /api/slos/{originOrId}?dataset={dataset}Update an SLO, or create it when {originOrId} is an unknown dash0.com/origin (see below)
DELETE /api/slos/{originOrId}?dataset={dataset}Soft-delete an SLO (returns 204; a later PUT to the same origin restores it)

{originOrId} is either the server-issued id (the dash0.com/id label, slo_...) or the dash0.com/origin label you set yourself.

The dataset query parameter is optional. When omitted, POST and PUT fall back to the dash0.com/dataset label in metadata.labels and then to default; GET and DELETE fall back to your token's only dataset or to default, and answer 403 if the token cannot access that dataset. The Dash0-Dataset request header is an alternative to the query parameter. On POST and PUT requests (which have a body), the dataset query parameter overrides the dash0.com/dataset label if both are provided.

Upsert and restore. For auth-token callers, PUT /api/slos/{originOrId} creates the SLO when {originOrId} matches nothing and is not a slo_... id; the path value becomes the SLO's dash0.com/origin. A slo_... id that does not exist returns 404. A PUT to a deleted SLO restores it and writes a new version.

Optimistic locking. Every read returns a dash0.com/version label. You may send it back on PUT: if present it must match the current version, otherwise the request is rejected with 400 (superseded). Omit it to overwrite unconditionally.

Region-specific host

The base host is region-specific (for example https://api.eu-west-1.aws.dash0.com). See the Dash0 API reference for the current host for your region and the full request and response schema.

The SLO object

json
123456789101112131415161718192021222324
{
"apiVersion": "openslo/v1",
"kind": "SLO",
"metadata": {
"name": "doc-validation-availability",
"labels": { "team": "platform" }
},
"spec": {
"budgetingMethod": "Occurrences",
"description": "99.7% of control-plane-api requests complete without an ERROR span status over a rolling 28-day window.",
"service": "control-plane-api",
"indicator": {
"spec": {
"ratioMetric": {
"counter": true,
"good": { "metricSource": { "type": "Prometheus", "spec": { "query": "..." } } },
"total": { "metricSource": { "type": "Prometheus", "spec": { "query": "..." } } }
}
}
},
"timeWindow": [ { "duration": "28d", "isRolling": true } ],
"objectives": [ { "displayName": "control-plane-api: 99.7% server availability", "target": 0.997 } ]
}
}

Notes:

  • target is a fraction strictly between 0 and 1 (0.997 = 99.7%). The equivalent targetPercent field (strictly between 0 and 100) is also accepted. Set exactly one of the two.
  • apiVersion is openslo/v1 or openslo.com/v1 (both accepted on write). Responses, JSON and YAML, always use openslo.com/v1, the form that is also installable as a Kubernetes CRD, so a document you read back can be PUT as is. kind must be SLO. metadata.name is required.
  • The server sets the dash0.com/id and dash0.com/version labels in metadata.labels and the dash0.com/created-at / dash0.com/updated-at annotations. Do not send dash0.com/id on POST (400). Use the dash0.com/id value, or your own dash0.com/origin label if you set one, as {originOrId} in the single-SLO endpoints.
  • The SLI is a ratioMetric with inline PromQL over your telemetry, in exactly one of three shapes: good + total, bad + total (Dash0 derives good as total - bad), or raw + rawType (success or failure) for a query that already returns a ratio between 0 and 1. A good, bad, or total query must be a bare vector selector (label matchers only, no functions or aggregations, else a 400); it may match many series, which Dash0 sums into one count. A raw query may be any PromQL expression that returns an instant vector and must resolve to one series. Make the good query a subset of the total query.
  • counter defaults to true: Dash0 applies increase() over 5-minute windows to the good, bad, and total selectors. Set counter: false when the series are gauges or other values that go up and down; Dash0 then only sums the selector. Ignored for raw.
  • service (optional) links the SLO to a Dash0 service. Use name or namespace/name; prefix the value with / if the service name itself contains a slash. The service is shown in the catalog and on the detail page, scopes the deployment markers on the charts, and is stamped as service.name / service.namespace resource attributes on the SLO metrics. If nothing matches, the SLO is simply not linked. It is also a list filter (?service=).
  • description is capped at 1050 characters. timeWindow is optional and defaults to a rolling 28-day window.

Dash0 metadata

metadata.name is the stable identifier. You can attach up to 50 custom labels and 50 custom annotations. Keys starting with dash0.com/ other than the ones below are reserved and dropped silently.

KeyPurpose
metadata.labels["dash0.com/origin"]Your own stable identifier, for example a Terraform resource id. Must be unique in the organization (400 otherwise) and must not start with slo_ or check_rule_. It resolves as {originOrId} and enables the PUT upsert. If omitted on a create made with an auth token, the server assigns an api-... origin. SLOs with an origin are read-only in the UI.
metadata.annotations["dash0.com/display-name"]Human-readable name shown instead of metadata.name in the UI.
metadata.annotations["dash0.com/enabled"]"true" (default) or "false". A disabled SLO keeps its definition but stops evaluating, produces no metrics, and does not count toward your SLO limit. Re-enabling re-checks the limit.
metadata.annotations["dash0.com/sharing"]Comma-separated read-access grants, team:<team_id> and user:<email>. Honored only for auth tokens and only on SLOs that carry a dash0.com/origin; 400 otherwise.

Supported OpenSLO capabilities

CapabilityBehavior
budgetingMethod: OccurrencesSupported
Single objectiveSupported
ratioMetric SLI with inline PromQL (good / total)Supported
ratioMetric SLI with bad + totalSupported
ratioMetric SLI with raw + rawType (success or failure)Supported; the raw query may be any PromQL expression that returns an instant vector and must resolve to one series
Rolling 28-day window (duration: "28d" or "4w", isRolling: true)Supported; timeWindow is optional and defaults to this, but when you do supply it, set isRolling: true explicitly (omitting it is a 400)
Timeslices / RatioTimeslices budgetingRejected with 400
Calendar windowsRejected with 400
Window durations other than 4w/28dRejected with 400
More than one objectiveRejected with 400
thresholdMetric SLIsRejected with 400
indicatorRef (top-level or per-objective)Rejected with 400
Composite objectives (compositeWeight, per-objective indicator)Rejected with 400
Per-objective threshold fields (op / value)Rejected with 400
timeSliceTarget / timeSliceWindowRejected with 400
metricSource.type other than PrometheusRejected with 400 (omit type or set it to Prometheus; spec.query must be a non-empty PromQL string)
metricSource.metricSourceRefRejected with 400 — inline the query instead
metadata.name missingRejected with 400
alertPoliciesAccepted for OpenSLO compatibility but not stored: dropped on write and absent when you read the SLO back (configure alerting with check rules)

Limits. An organization can have up to 25 enabled SLOs by default. Creating another, re-enabling a disabled one, or restoring a deleted one returns 400 The maximum number of SLOs (25) for this organization has been reached. Disabled and deleted SLOs do not count. Disable (dash0.com/enabled: "false") or delete an SLO, or contact Dash0 to raise the limit.

Errors

  • 400 Bad Request — the definition uses a capability that is not supported (the message names the capability); the dash0.com/version label does not match the current version (superseded); the dash0.com/origin is already in use or uses a reserved prefix; more than 50 labels or annotations; an invalid dash0.com/sharing string; or the SLO limit has been reached.
  • 403 Forbidden — This feature is not enabled for this organization means SLOs are not enabled for your organization; contact support if you believe they should be. Otherwise the token cannot access the requested or defaulted dataset, or lacks the permission for the call (writes need All permissions, reads need Reading).
  • 404 Not Found — {originOrId} does not exist or is not readable with this token (also on PUT for an unknown slo_... id).

Further reading