Skip to content

Observability exports (Prometheus, Datadog, Grafana Cloud)

Tested with: API v1 · Prometheus 3 · Datadog Agent 7 (OpenMetrics check) · Grafana Alloy 1.x

Every organization has a Prometheus endpoint with one series per instance: status, size, storage and the metered usage of the latest complete hour (compute, storage, egress, connections, backups). Point any Prometheus-compatible collector at it with an API key.

endpoint
GET https://api.databasezy.com/v1/orgs/{org_id}/metrics
Authorization: Bearer zb_...

Create a key that can only read usage. It cannot see credentials or change anything:

shell
curl -s https://api.databasezy.com/v1/orgs/$ORG/api-keys \
-H "Authorization: Bearer $ADMIN_KEY" -H 'Content-Type: application/json' \
-d '{"name":"metrics-scraper","role":"viewer","scopes":["usage:read"]}'

Store the returned key in your collector’s secret store. A key without usage:read gets 403.

The response is Prometheus text format 0.0.4. Every series carries org_id, instance_id, instance (the name), project_id, engine, region and team_id labels.

MetricTypeMeaning
zerobase_instance_infogaugeAlways 1; labels add status, size, placement, engine_version
zerobase_instance_upgauge1 while the instance is ready, 0 when paused, provisioning or failed
zerobase_instance_storage_allocated_gigabytesgaugeProvisioned storage
zerobase_instance_replicasgaugeRead replicas
zerobase_usage_compute_centsgaugeCompute charge for the latest complete hour, in USD cents (size price x running time, before the plan credit)
zerobase_usage_cu_hoursgaugeCompute capacity units (1 CU = 1 vCPU + 4 GiB) used in the hour; a capacity view, not a price
zerobase_usage_storage_used_gbgaugeStorage actually used
zerobase_usage_egress_gbgaugeEgress in the hour
zerobase_usage_connectionsgaugeConnections metered in the hour
zerobase_usage_<metric>gaugeEvery other metered dimension (backup_gb_hours, replica_compute_cents, …)
zerobase_usage_period_start_secondsgaugeStart of the hour the usage series describe
zerobase_metering_upgauge0 when usage could not be read (instance series are still served)

Usage is hourly, so a scrape interval of 60 s is plenty; 5 minutes is fine. Scraping counts against the normal API rate limit (600 requests per minute per key).

prometheus.yml
scrape_configs:
- job_name: databasezy
scheme: https
metrics_path: /v1/orgs/org_01J8XXXXXXXXXXXXXXXXXXXXXX/metrics
scrape_interval: 60s
authorization:
type: Bearer
credentials_file: /etc/prometheus/secrets/databasezy-key
static_configs:
- targets: ["api.databasezy.com"]

Alert when an instance stops serving:

databasezy-rules.yml
groups:
- name: databasezy
rules:
- alert: DatabasezyInstanceDown
expr: zerobase_instance_up == 0 and on (instance_id) zerobase_instance_info{status!="paused"}
for: 5m
labels: { severity: page }
annotations:
summary: "{{ $labels.instance }} ({{ $labels.engine }}) is not ready"
- alert: DatabasezyStorageAlmostFull
expr: zerobase_usage_storage_used_gb / zerobase_instance_storage_allocated_gigabytes > 0.85
for: 1h
annotations:
summary: "{{ $labels.instance }} uses over 85% of its storage"

Grafana Alloy scrapes the endpoint and remote-writes to your Grafana Cloud Prometheus stack:

config.alloy
prometheus.scrape "databasezy" {
targets = [{ "__address__" = "api.databasezy.com" }]
scheme = "https"
metrics_path = "/v1/orgs/org_01J8XXXXXXXXXXXXXXXXXXXXXX/metrics"
scrape_interval = "60s"
bearer_token = sys.env("DATABASEZY_METRICS_KEY")
forward_to = [prometheus.remote_write.grafana_cloud.receiver]
}
prometheus.remote_write "grafana_cloud" {
endpoint {
url = "https://prometheus-prod-13-prod-us-east-0.grafana.net/api/prom/push"
basic_auth {
username = sys.env("GRAFANA_CLOUD_PROM_USER")
password = sys.env("GRAFANA_CLOUD_API_KEY")
}
}
}

The older Grafana Agent (static mode) takes the same values under metrics.configs[].scrape_configs, with authorization: { type: Bearer, credentials: ... }.

Use the Agent’s OpenMetrics check. Add conf.d/openmetrics.d/conf.yaml:

conf.d/openmetrics.d/conf.yaml
init_config:
instances:
- openmetrics_endpoint: https://api.databasezy.com/v1/orgs/org_01J8XXXXXXXXXXXXXXXXXXXXXX/metrics
namespace: databasezy
metrics:
- zerobase_instance_.*
- zerobase_usage_.*
- zerobase_metering_up
headers:
Authorization: "Bearer ENC[databasezy_metrics_key]"
min_collection_interval: 60
tags:
- "source:databasezy"

ENC[...] resolves through the Agent’s secrets management; a plain value works for a first test. Restart the Agent, then check datadog-agent status for the openmetrics instance. Metrics appear as databasezy.zerobase_instance_up and friends, with the labels as tags, so a dashboard widget on sum:databasezy.zerobase_usage_compute_cents{*} by {instance} shows compute spend per instance.

On Kubernetes, put the same instance under the Datadog Helm chart’s datadog.confd or a cluster check; the endpoint is not in your cluster, so no pod annotation discovery is involved.

SymptomCause
401Key revoked, expired or suspended by an automatic security response (the org admin can lift a suspension)
403 required_permission: usage:readThe key lacks the usage:read scope
404The org id in the path is not the key’s org
zerobase_metering_up 0Usage is temporarily unavailable; instance series are still current
No zerobase_usage_* series for a new instanceUsage appears after its first complete metered hour