The document
Every field of a dashboard document, from the window and the grid to groups, charts, axes, series, and templates.
This page is the field-by-field reference for the document that POST /dashboards and PUT /dashboards/{id} accept and GET /dashboards/schema describes. Unknown fields anywhere are a 422. Every string length below is a maximum.
Top level
| Field | Type | Default | Notes |
|---|---|---|---|
name | string 1..200 | required | unique per workspace (409) |
description | string 2000 | null | shown in the list and the definition, not on the page |
layout.columns | int 1..12 | 12 | the grid; 12 is also the maximum |
window | Window | null | the range the page opens with; null = the last 7 days |
components | list, up to 50 | [] | chart and group components |
A top-level chart must pass the standalone checks. A group is checked as a whole.
Window
Either absolute or relative, never mixed; at least one field.
| Field | Type | Notes |
|---|---|---|
start, end | datetime | absolute bounds; start before end |
last | ISO 8601 duration | how far back from now: P7D, PT12H, P1DT6H, P2W |
ahead | ISO 8601 duration | how far forward from now; last without ahead ends at now |
Durations accept weeks, days, hours, minutes, and seconds (P2W, P7D, PT12H, PT30M, PT45S, combined as in P1DT6H); anything else is a 422. The page's range picker overrides the window for the viewer and shows relative ranges as now-2d to now+2d.
Group
| Field | Type | Default | Notes |
|---|---|---|---|
type | "group" | required | |
title | string 200 | null | the section heading on the page |
description | string 1000 | null | |
for_each | ForEach | required | the iterator |
component | chart component | required | the chart every item is drawn from |
for_each names exactly one source:
| Field | Type | Notes |
|---|---|---|
object | type slug | every record of that object type, by name. Custom and built-in types; a type whose records sit between two records cannot be iterated |
filter | {"<attribute>": ["value", ...]} | with object only, custom types only: the list route's filter[<attribute>] |
records | list of uuid, 1..200 | these records, in this order; unknown ids are warnings |
limit | int 1..200 | 50 |
Object types named here must exist (422 on write). Records are checked at resolve time and become warnings, not errors.
Chart
| Field | Type | Default | Notes |
|---|---|---|---|
type | "chart" | required | |
title | string 200 | null | a template inside a group ({{ item.name }}) |
description | string 1000 | null | shown under the title on the card |
width | int 1..12 | 6 | grid columns |
height | int 1..4 | 1 | rows of about 160 px of plot |
chart | chart spec | required |
Standalone checks, applied to a chart outside a group: every series names a record, and no template refers to item (in the title, a series' record or label, or an axis bound). Both failures are a 422 naming the component index.
Chart spec (chart.chart)
| Field | Type | Default | Notes |
|---|---|---|---|
kind | line, area, bar | line | the default drawing kind; a series may override |
stacked | bool | false | stacks the series drawn on each axis on top of each other; the web app stacks bars and areas as separate stacks |
aggregation | "auto" or int seconds | "auto" | auto: about 2,000 points per line; a number: a fixed bucket, up to one year |
axes | map of key to axis | {} | named y axes; left and right exist on the first pane without being declared |
panes | list of up to 4 {"height": n} | null | relative heights, top to bottom; omitted = equal |
now_line | bool | false | a dashed vertical line at the current time |
series | list 1..50 | required |
Axis keys match ^[a-z][a-z0-9_-]*$, at most 32 characters. Declaring left or right sets their options. Rules: every series' axis must be declared or implicit; at most one axis per side per pane; when panes is given it must cover the highest pane an axis sits on. The pane count is the length of panes when given, else the highest pane used plus one.
Axis
| Field | Type | Default | Notes |
|---|---|---|---|
pane | int 0..3 | 0 | panes stack top to bottom and share the time axis |
side | left, right | left | |
label | string 40 | null | defaults to the unit of the series drawn on it |
min, max | number, or template string | null | a template must contain a placeholder; it renders per item and is evaluated as arithmetic |
zero_at | number, 0 up to but excluding 1 | null | fraction of the axis height where zero sits; bounds derive from the data |
align_zero | axis key | null | share another axis's zero line (same pane, target not itself aligned) |
zero_at and align_zero exclude each other and exclude min. max may be combined with either and then pins the top while the bottom follows. The renderer rounds derived bounds to tidy numbers, keeps the exact ratio, and hides labels below zero on an aligned axis whose data never goes negative.
Two ways to place zero instead of fixing bounds: zero_at: 0.3 keeps negative losses to the bottom 30% of the axis, and align_zero: "power" makes a wind speed on the right read against the power forecast's zero line. The tutorial puts both to work.
Series
| Field | Type | Default | Notes |
|---|---|---|---|
timeseries | string 1..100 | required | the series type slug on the record |
column | string 100 | null | one column of a multi-column type; omitted = every column, each its own line |
record | uuid or template, 200 | null | inside a group it defaults to the iterated record |
label | string 200 | null | template; sees item and record |
color | #rgb or #rrggbb | palette | |
kind | line, area, bar | chart's kind | per-series override (bars under a line) |
step | bool | false | stepped line |
dash | solid, dashed, dotted | solid | |
axis | axis key | left | |
scale | number, not 0 | 1 | multiplies values: -1 draws losses as negative bars, 0.001 turns kW into MW |
Default label: the record name when the chart compares several records, the column (or type) when it compares one record's series, both when it does both. Default colours come from a six-colour palette in series order; a series that reads a whole multi-column type gets one palette colour per column.
Templates
Placeholders are {{ path }}; spaces inside the braces are allowed.
| Path | Available in | Value |
|---|---|---|
item.id, item.name, item.object | chart title, series record, series label, axis min/max, inside a group | the iterated record |
item.values.<attribute> | same | the record's values as the API shows them (custom attributes; latitude, longitude, description for sites) |
item.stats.total_capacity_kw | same, sites only | the sum of the site's assets' capacity |
record.id, record.name, record.object | series label | the series' own record, which is item unless the series names a different record |
An unknown path renders as the empty string and is reported in the card's errors. Axis bounds are evaluated after rendering as plain arithmetic: numbers with +, -, *, /, and parentheses only. Anything else is reported on the card and the axis falls back to auto-fitting. A template in a chart outside a group is a 422.
Limits
| Limit | Value | On breach |
|---|---|---|
| components per document | 50 | 422 |
| series per declared chart | 50 | 422 |
| items per iterator | 200 (default 50) | warning, rest dropped |
| cards after expansion | 200 | warning, rest dropped |
| lines per dashboard | 10,000 | 422 at resolve |
| panes | 4 | 422 |