PulseBoard docs
Everything you need to get from zero to production: ingest your first metric in 30 seconds, configure alerting and on-call schedules, deploy PulseAgent across your fleet, and set up GitOps-managed dashboards. Workspace product docs below; cloud control-plane specifics are marked cloud.
Quickstart
Sign up, get a key, push a metric, and view it in under a minute.
# 1. Sign up (hosted) or run locally
curl -X POST https://your-edge/api/signup \
-H 'content-type: application/json' \
-d '{"slug":"acme","email":"you@acme.com"}'
# → {"apiKey":"pb_live_..."}
# 2. Push a metric (inline labels supported)
curl -X POST https://your-edge/ingest/metrics \
-H "Authorization: Bearer $PB_KEY" \
-H 'content-type: application/json' \
-d '[{"name":"http_requests_total{service=\"checkout\"}","value":42}]'
# 3. Query it back
curl "https://your-edge/api/prom/api/v1/query?query=http_requests_total" \
-H "Authorization: Bearer $PB_KEY"
Labels go inline in the metric name as a Prometheus series string.
The labels JSON field is intentionally ignored — use
name='metric{k="v"}' instead.
Ingest protocols
PulseBoard speaks every protocol your infrastructure already uses.
Native JSON
POST /ingest/metrics — bare JSON array of
{name, value, ts?}. NDJSON also accepted.
Prometheus remote_write
Snappy-encoded protobuf at /api/prom/api/v1/write.
Drop-in replacement for any Prom-compatible remote.
OTLP/HTTP
Metrics at /v1/metrics, logs at /v1/logs,
traces at /v1/traces. Protobuf and JSON encodings both
supported.
Loki push
POST /loki/api/v1/push. Compatible with Promtail,
Alloy, and any Loki-native client.
Log query
LogQL queries via GET /api/loki/api/v1/query_range with the same
bearer token. Full label filtering and line-filter |= "text" supported.
PulseAgent
A lightweight Rust agent that collects host metrics, container logs, Kubernetes pod logs, journald, Windows Event Log, and arbitrary Prometheus scrape targets — then ships them to your PulseBoard edge. Designed to be installed as a DaemonSet, a systemd unit, or a Windows service.
# Linux one-liner install
curl -sSfL https://pulseboard.dev/install.sh | sh
# Configure
cat /etc/pulseagent/agent.toml
# [target]
# url = "https://your-edge"
# token = "pb_live_..."
# Helm (Kubernetes DaemonSet)
helm repo add pulseboard https://charts.pulseboard.dev
helm install pulseagent pulseboard/pulseagent \
--set target.url=https://your-edge \
--set target.token=$PB_KEY
Sources
- host_metrics — CPU, memory, disk, network via sysinfo
- docker — container log streaming via Docker API
- kubernetes_pods — pod log scraping with namespace/label filters
- journald — systemd journal (Linux)
- windows_event_log — Application and System event channels
- prom_scrape — arbitrary
/metricsendpoints - otlp_receiver — local OTLP collector endpoint
- file_logs — tail arbitrary log files with glob patterns
Processors
- batch — buffer and flush on size or time
- relabel — add, drop, or rename labels
- redact_pii — regex-based PII scrubbing before transmission
- cardinality_guard — drop series exceeding a label-value cap
- transform — arithmetic transforms on metric values
Dashboards & panels
Create dashboards from the UI, import from JSON, or push via the
GitOps sync. Panels support PromQL (proxied to Mimir when
--mimir-url is set, or evaluated in-process with the full embedded
engine including rate(), avg by(), and arithmetic).
Panel types
timeseries— line/area chart with multi-series supportstat— single-value with threshold colouringlogs— streaming log view with LogQLtable— tabular view of instant or range resultsbargauge— horizontal bar gauges for vector valuesgauge— radial gauge for scalar valuespiechart— pie/donut distribution from vector valuesbarchart— categorical bar charthistogram— bucket histogram over matrix seriesstate-timeline— categorical state timeline over timestatus-history— status history blocks over timetext— Markdown/text paneldashlist— dashboard list/navigation panelalertlist— live list of firing alerts with runbook buttonsannolist— annotations list panelheatmap— heatmap density visualizationtrend— compact trend sparkline-style panelxychart— XY/scatter style chartcandlestick— OHLC/candlestick charttraces— trace list/details panelflamegraph— flame graph from span datanews— RSS/Atom news feed panelnodegraph— force-directed service/node graphcanvas— freeform canvas panelgeomap— geographic map panel
Export as code
Any dashboard or rule group can be exported to YAML or Terraform HCL via the
</> Code button, or via
GET /api/export/dashboards/<id>?format=tf|yaml.
Alerting
The embedded rule engine evaluates full PromQL (including rate(),
avg by(), arithmetic, and aggregations) entirely in-process with no
external dependency. In Mimir deployments, evaluations delegate to Mimir's instant
query endpoint automatically for full PromQL parity.
Rule format
POST /api/rules
{
"name": "High CPU",
"groupId": "infra",
"expr": "100 - avg by (instance)(rate(node_cpu_seconds_total{mode=\"idle\"}[5m]))*100",
"cmp": ">",
"threshold": 90,
"forMs": 300000,
"severity": "critical",
"annotations": {
"summary": "CPU > 90% on {{ $labels.instance }} — now at {{ $value }}"
},
"runbook": "## High CPU\n1. Check top processes\n2. ..."
}
Annotations support {{ $labels.name }} and {{ $value }}
templating, resolved at fire time.
Routing (Alertmanager-compatible)
Full routing tree with matchers, grouping, group-wait/interval/repeat intervals,
mute time windows, inhibition rules, and a continue flag. Configure via
PUT /api/alertmanager/config or the Routing UI in the Alerts tab.
Silences
Create and manage silences from the Alerts → Silences tab or via
POST /api/silences. Silences support label matchers and an
optional comment.
Notification receivers
Built-in receiver types: Webhook / Slack / Discord / Teams (URL), PagerDuty (routing key), OpsGenie, SendGrid, Mailgun, SES, Twilio SMS, Jira.
Dead-letter queue
Failed notifications are moved to the DLQ after maxAttempts.
Inspect, replay, or purge from the Alerts → Notifications tab or via
/api/notify/dlq.
On-call scheduling
Built-in on-call catalog: users, rotation schedules with configurable shift lengths, override windows, and multi-step escalation policies. No external PagerDuty account required.
- Define users with name, email, and linked receiver IDs.
- Create rotation schedules with multiple rotations, shift-length hours, a start timestamp, and ad-hoc override windows per user.
- Build escalation policies: step 1 notifies the on-call schedule; step 2 (after N minutes) notifies a backup schedule or a specific receiver.
- Who-is-on API:
GET /api/oncall/whoison/<scheduleId>. - Routing receivers can target an on-call policy via
kind: "policy"target in escalation steps.
Inline runbooks & incident analytics
Attach a Markdown step-by-step runbook to any alert rule. When the alert fires, the on-call engineer opens the runbook drawer, checks off steps, and acknowledges. PulseBoard records step completion, MTTR, and acknowledgement timestamps.
- Runbook steps are rendered as interactive checkboxes in the Alerts → Firing view.
- MTTR is tracked per alert fingerprint from
firedAttoack. - Incident analytics:
GET /api/runbooks/incidentsreturns per-rule aggregates (total incidents, resolved count, avg MTTR, most-skipped steps).
Synthetic uptime monitoring
Schedule HTTP, TCP, or DNS probes from one or more regions. Results are stored as
pulse_synthetic_up{check="..."} time-series so they can be used in
dashboards, alert rules, and status pages.
POST /api/synthetics
{
"name": "Checkout API",
"kind": "http",
"target": "https://api.acme.com/health",
"intervalMs": 60000,
"timeoutMs": 5000,
"enabled": true
}
The results matrix API (GET /api/synthetics/matrix) returns
up/down status, duration, and detail per region — useful for status pages and
dashboards.
Public status pages
Create branded public status pages backed by live metric thresholds and synthetic probe results. No extra infrastructure needed — the status page is served directly by the edge runtime.
- Each component maps to a metric series or a synthetic check.
- Uptime percentage is calculated over a configurable look-back window.
- Current incidents are derived from active firing alert rules.
- Custom slug: your page lives at
/status/your-slug. - Auto-refreshes every 30 seconds; no JavaScript framework required.
Admin CRUD: POST/PUT/DELETE /api/status/pages.
Public viewer: GET /status/<slug> (no auth required).
GitOps & export-as-code
Keep dashboards and alert rules in your Git repository. PulseBoard polls the repo and reconciles the diff — new files are created, changed files are updated, and (if prune is enabled) files removed from Git are deleted from the workspace.
# agent.toml / environment flags
PULSE_GITOPS_URL=https://github.com/acme/observability
PULSE_GITOPS_BRANCH=main
PULSE_GITOPS_PATH=pulseboard/ # sub-directory in the repo
PULSE_GITOPS_INTERVAL=60 # seconds
PULSE_GITOPS_TOKEN_ENV=GH_TOKEN # env var containing a PAT
PULSE_GITOPS_PRUNE=true
Files in the sub-directory must be JSON matching the dashboard or rule group
schema. The file name (without .json) is used as the stable ID.
Export as code
Export any dashboard or routing config to YAML or Terraform HCL:
GET /api/export/dashboards/{id}?format=yaml
GET /api/export/rules/{id}?format=tf
GET /api/export/routing?format=yaml
Or click the </> Code button in the dashboard toolbar.
Traces & service map
Send traces via OTLP/HTTP to /v1/traces. The edge extracts
service-map edges (caller → callee) and span error rates. The Traces view in the SPA
renders the service map and a per-trace waterfall. Error spans are highlighted
automatically.
# OTLP protobuf (curl example)
curl -X POST https://your-edge/v1/traces \
-H "Authorization: Bearer $PB_KEY" \
-H "Content-Type: application/x-protobuf" \
--data-binary @traces.pb
PulseAgent ships with a built-in OTLP receiver source
(otlp_receiver) that accepts traces from your application and
forwards them to the edge.
AI Explain
Ask PulseBoard to explain a spike in any metric. The default in-process analyser (no external LLM, no data leaves your instance) uses mean/stddev/jump detection to produce a deterministic, human-readable explanation.
POST /api/ai/explain
{
"seriesName": "payments.latency.p99",
"samples": [
{"ts": 1, "value": 1.0},
{"ts": 2, "value": 1.1},
{"ts": 3, "value": 9.0},
{"ts": 4, "value": 1.1}
]
}
// → "Largest single-step jump was 7.90 at index 3 (> 2× stddev)..."
Enterprise plans can configure a private LLM adapter
(IAiProvider) to use OpenAI, Azure OpenAI, or any compatible API.
Multi-tenancy & auth
PulseBoard supports single-tenant (open, API-key-only) and multi-tenant (OIDC + per-workspace isolation) deployments.
| Mode | Auth | Ingest |
|---|---|---|
| Single-tenant | Bearer API key | Open — no auth needed for /ingest/* |
| Multi-tenant | OIDC (any provider) + workspace bearer tokens | Scoped per tenant; Mimir org header injected |
Admin OIDC is configured with --oidc-issuer / --oidc-client-id.
cloud The hosted service uses GitHub OAuth plus a magic-link
email flow for password-less sign-in.
RBAC scopes
admin— full access including tenant management and billingquery— read metrics, logs, traces; manage dashboards and rulesingest— write-only ingest token (no read access)
Cost attribution
Every active series, log byte, and trace span is attributed to the team (label set) that produced it. Cost attribution is available in real time:
GET /api/admin/tenants/{id}/cost/teams
# → [{"team":"checkout","seriesCount":1240,"ingestGiB":0.14,"estimatedUsd":0.82},...]
The pricing calculator on the pricing page uses the same cost endpoint, so what you preview is exactly what appears on your invoice. Per-team limits and alerts can be set to prevent runaway label cardinality.
Self-hosting
The entire PulseBoard edge runtime is MIT-licensed and available on GitHub. Run it with Docker, bare metal, or Kubernetes.
# Docker (single-tenant, local storage)
docker run -p 8080:8080 \
-v /data/pulse:/data \
ghcr.io/pulseboard/pulseboard:latest \
--port=8080 --data=/data
# With Mimir back-end (long-term storage)
docker run -p 8080:8080 \
ghcr.io/pulseboard/pulseboard:latest \
--port=8080 --data=/data \
--mimir-url=http://mimir:9009 \
--mimir-write-tenant=acme \
--mimir-read-tenant=acme
See DEPLOYMENT.md for the full Helm chart, Kubernetes manifests, and environment-variable reference.
Key flags
| Flag / Env | Purpose |
|---|---|
--port / PULSE_PORT | HTTP listen port (default 8080) |
--data / PULSE_DATA | Local data directory |
--mimir-url | Upstream Mimir for long-term metric storage |
--oidc-issuer | OIDC provider issuer URL for multi-tenant auth |
--region / PULSE_REGION | Region label for synthetic probes |
--gitops-url | Git repository URL for GitOps sync |
License
The PulseBoard edge runtime, and all libraries in the OpenPulseBoard/pulseboard-oss repository are released under the MIT License. You can self-host, modify, and redistribute freely, including for commercial use, as long as you include the license notice.
The hosted cloud control-plane software in pulseboard-cloud is
proprietary. Your use of the hosted service is governed by the
Terms of Service and Privacy Policy.