Axiom.Dashboard reference
Dashboard
Section titled “Dashboard”Source:
src/Axiom/Dashboard.ts
An Axiom dashboard — a named, layout-driven collection of charts. Each
dashboard takes a full document (charts + layout array of grid cells +
timeWindow + refreshTime) at version schemaVersion: 2.
Charts are typed via Chart (a discriminated union over the
Axiom-validated chart kinds — TimeSeries, Table, Pie, Statistic,
Heatmap, LogStream, Note). The id on each chart is a free-form
string the author picks; layout cells join via LayoutCell.i.
The path identifier is uid (auto-assigned by Axiom). id is also
exposed as an output but the API uses uid everywhere.
Notes from probing POST /v2/dashboards:
- Relative time windows must use the
qr-now-{duration}form (e.g."qr-now-7d"/"qr-now"); plain"now-7d"is rejected. - When authenticating with an API token,
dashboard.ownermust be""(Axiom rewrites this to the org-sharedX-AXIOM-EVERYONE); per-user “private” dashboards aren’t allowed for tokens. - The chart payload is strict: only
id,name,type,query. Extra keys (e.g.dataset,description) triggerUnrecognized keys: "<name>".
Dashboard: Creating a Dashboard
Section titled “Dashboard: Creating a Dashboard”Minimal empty dashboard
yield* Axiom.Dashboard("ops", { dashboard: { name: "Ops Overview", owner: "", // org-shared (required for API tokens) description: "Top-level service health", charts: [], layout: [], refreshTime: 60, // seconds: 15 | 60 | 300 schemaVersion: 2, timeWindowStart: "qr-now-1h", timeWindowEnd: "qr-now", },});One-chart dashboard
import type { Chart, LayoutCell } from "alchemy/Axiom";
const errors: Chart = { id: "errors-5m", name: "5xx errors / 5m", type: "TimeSeries", query: { apl: `['my-app-traces'] | where status >= 500 | summarize count() by bin_auto(_time)`, },};
yield* Axiom.Dashboard("errors", { dashboard: { name: "Errors", owner: "", refreshTime: 60, schemaVersion: 2, timeWindowStart: "qr-now-24h", timeWindowEnd: "qr-now", charts: [errors], layout: [{ i: errors.id, x: 0, y: 0, w: 12, h: 6 } satisfies LayoutCell], },});Compare to last 24h
yield* Axiom.Dashboard("compare", { dashboard: { name: "Compare vs yesterday", owner: "", refreshTime: 300, schemaVersion: 2, timeWindowStart: "qr-now-1h", timeWindowEnd: "qr-now", against: "-1d", // overlay the same window from 24h ago charts: [], layout: [], },});Source:
src/Axiom/View.ts
An Axiom saved view — a named, shareable APL query. Useful for building starter dashboards, providing canned “open in Axiom” links from your app, or pinning common investigations the team revisits.
The path identifier is name. Renaming a view triggers a replacement
(the old one is deleted, a new one is created).
View: Creating a View
Section titled “View: Creating a View”Recent errors across one dataset
yield* Axiom.View("recent-errors", { name: "recent-errors", description: "Last 100 5xx responses", datasets: ["my-app-traces"], aplQuery: ` ['my-app-traces'] | where status >= 500 | order by _time desc | take 100 `,});Cross-dataset join (logs + traces by trace_id)
yield* Axiom.View("trace-with-logs", { name: "trace-with-logs", datasets: ["my-app-traces", "my-app-logs"], aplQuery: ` ['my-app-traces'] | where duration_ms > 1000 | join kind=leftouter (['my-app-logs']) on trace_id `,});