Manage SLOs with OpenSLO files
Export SLOs as OpenSLO v1 YAML, keep them in Git and import them back: supported fields, Belvador annotations, dry-run checks and all-or-nothing saves.
OpenSLO is an open YAML format for SLOs. Belvador exports and imports a subset of OpenSLO v1, so you can keep SLO definitions in Git, review changes in pull requests and recreate them in another workspace.
Export#
Open an SLO and choose Export OpenSLO. The file looks like this:
apiVersion: openslo/v1kind: SLOmetadata: name: checkout-api-availability displayName: Checkout API availability annotations: "belvador.dev/source": uptime "belvador.dev/source-ref": "{\"id\":\"<uptime-check-id>\"}" "belvador.dev/sli": availability "belvador.dev/alert-policy": preset_defaultspec: budgetingMethod: Timeslices timeWindow: - duration: 30d isRolling: true objectives: - target: 0.999metadata.name is the SLO's identifier in the workspace; importing a file with the same name updates that SLO. The source is chosen by Belvador annotations, because OpenSLO's own metric queries describe metrics systems Belvador does not use.
Import#
Open SLOs → Import OpenSLO and choose a file.
Check file reads every document and lists, per SLO, whether it will be new or an update — or every problem with its document number and field path. Nothing is saved yet.
Import saves the whole file in one step. If any SLO is refused — for example a check this workspace does not own, a source that needs Allow public sources, or the plan limit — none of the file is saved.
A file may be up to 64 KB with up to 50 SLOs. YAML is read safely: custom tags are refused.
An imported SLO is managed by the file: its Edit button is locked and the page shows Managed by OpenSLO file. Change the file and import it again. Pause, mute and delete still work on the SLO page. Importing a file whose metadata.name matches an SLO created in Belvador takes that SLO over.
Supported fields#
| Field | Rule |
|---|---|
apiVersion | openslo/v1 |
kind | SLO; Service documents in the same file are accepted and ignored |
metadata.name | required; lowercase letters, digits and -, up to 63 characters, unique in the file |
metadata.displayName | the SLO name shown in Belvador (up to 120 characters); metadata.name when absent |
metadata.labels | accepted, not used |
spec.description | optional |
spec.service | accepted, not used |
spec.indicator | optional inline ratioMetric; accepted, not used — the source annotations decide what is counted |
spec.timeWindow | exactly one rolling window: 7d, 28d or 30d |
spec.budgetingMethod | Timeslices for uptime checks, Occurrences for monitors, heartbeats and spans |
spec.objectives | exactly one, with target between 90 % and 99.99 % as a ratio (0.999) |
Belvador annotations#
| Annotation | Value |
|---|---|
belvador.dev/source | uptime, monitor, heartbeat or spans |
belvador.dev/source-ref | JSON: {"id":"<check or monitor id>"}; monitors may add "environment"; spans use {"projectId":7,"service":"api","operation":"GET /api/orders","environment":"production"} (operation and environment optional) |
belvador.dev/sli | availability (default) or latency |
belvador.dev/latency-threshold-ms | required with latency: 1–60000 |
belvador.dev/alert-policy | preset_default (default), page_only, ticket_only or off |
belvador.dev/allow-public-sources | "true" to count data sent with a public key |
What is refused#
Belvador never drops a field silently. Anything outside this subset is refused with OPENSLO_UNSUPPORTED_FIELD and the field's path — for example spec.indicatorRef, several objectives, isRolling: false, calendar windows, thresholdMetric, and AlertPolicy, AlertCondition or SLI documents. Alerting is set with the alert-policy annotation and alert rules instead.
Spotted something wrong or missing? Tell us: hello@belvador.dev