Use it when composing a dashboard; use viz_render instead for one chart or artifact_certify to grade each returned normalized chart. Returns layout, per-panel specs/hashes, computed KPI values, accessibility data and a reusable specRef. output.includeNormalizedSpec includes panel IR; output.html adds rendered HTML. brand/theme controls emitted pixels; selection and crossFilter apply caller-supplied filtering. resolveMeasures defaults true for governed measure references. output.contrastScan is a four-pair token preflight, not whole-document certification. Chord and flow_map are excluded from dashboards. Reference: TOOL-REFERENCE.md#dashboard_render; full schema: oods://schemas/dashboard_render.input.json.

Inputs

Name Type Required Description
theme "light" | "dark" | "hc" no CSS token theme for chart pixels, default light. See full schema for details.
schemaVersion "v0.1" yes IR version discriminant (V01 convention). A future template/shape change bumps to v0.2.
id string no Stable identifier for the dashboard instance.
title string no Human-friendly dashboard title surfaced in UI + narration.
datasets object[] yes SEAM (a) cross-panel DATA-SHARING. Shared, named tabular datasets. Tabular chart panels and KPI panels reference one by `datasetId`; sharing a dataset is what makes cross-filter possible (panels filter the same dimensional space).
panels object[] yes Heterogeneous panels: chart (11 of the 13 viz.render chartTypes; chord and flow_map are viz.render-only — plus its data branch) or kpi tiles.
layout object no Optional layout hints consumed by the deterministic auto-layout resolver. Absent hints -> declared panel order + KPI-row-first defaults; the resolver emits abstract {x,y,w,h} (renderer-agnostic, the client sizes the canvas).
links object[] no Declared panel relationships, returned in the result and rendered as a labelled reference list in HTML. They do not apply filters. Active cross-filtering uses selection and crossFilter.
crossFilter object no Active selection combination. Each active source contributes a predicate; ignoreSelfSource controls whether its own panel is filtered. Declared links do not change this behavior.
onPanelError "placeholder" | "omit" no SEAM (b) partial-panel ERROR policy. 'placeholder' = render an a11y-described error panel in-place (default — don't void the dashboard); 'omit' = drop the failed panel from the layout.
resolveMeasures boolean no Phase-3 governed-measure RESOLUTION switch. See full schema for details.
strictFields boolean no Field-presence STRICT switch. See full schema for details.
strictDatasets boolean no Unknown-datasetId STRICT switch. See full schema for details.
a11yEquivalence boolean no A11y equivalence CERTIFY-AT-EMISSION switch. See full schema for details.
a11y object yes SEAM (d) dashboard-level accessibility: a cross-panel summary + reading/focus order. The per-chart AccessibilitySpec stays per-panel; this is the dashboard envelope.
tokenCssRef string no SEAM (e) TOKEN strategy. See full schema for details.
brand string no CSS token brand for the dashboard document and chart pixels; defaults to A. The contrast scan grades the same scoped document tokens.
selection object no Optional accumulated cross-filter SelectionState, keyed by sourceWidgetId (one active selection per source). See full schema for details.
output object no Optional render output controls (mirrors viz.render).

Outputs

Name Type Required Description
status "ok" | "error" yes Whether the dashboard composed successfully (ok even when individual panels failed to a placeholder).
schemaVersion string no Echoes the DashboardSpec IR version.
panels panelResult[] yes Per-panel compiled results, in declared panel order. A chart panel carries its compiled spec; a kpi panel carries computed values; a failed panel becomes an a11y-described error placeholder (onPanelError default).
layout placement[] no The resolved abstract grid placements (m02), one per rendered panel.
links object[] no Declared panel relationships, rendered as a labelled reference list in HTML. Active filtering uses selection and crossFilter independently.
a11y dashboardA11y no
tokenCssRef string no Deferred token CSS reference when compact mode is on (use tokens.build).
html string no Opt-in self-contained dashboard HTML with scoped chart SVG, KPI tiles and error placeholders. Light/dark renders all admitted chart types. HC chart rendering preserves declared token colors; unsupported renderer paints become typed error panels under the existing placeholder/omit policy.
specRef string no One dashboard-level reference to the composed payload for pipeline reuse.
specRefCreatedAt string no
specRefExpiresAt string no
contentHash string no Deterministic SHA-256 (hex) over the canonicalized composed payload ({panels, layout}) — the content IDENTITY of exactly what specRef caches. Unlike specRef (a random, expiring cache handle), contentHash is stable: same input yields the same hash. panels[].contentHash, panels[].normalizedSpec, and outputHtmlHash are attached after this hash is computed and sit OUTSIDE the hashed projection. Default-on; omitted only on error outputs.
outputHtmlHash string no SHA-256 over the exact returned HTML bytes. Successful panels contain scoped SVG; failed panels follow the declared placeholder/omit policy, including measured HC render deferrals. This per-call identity is distinct from a certified runtime-matrix renderHashEpoch claim.
output object no Echoes the normalized output controls.
meta object no
errors issue[] no
warnings issue[] yes
a11yContrast a11yContrast no

A real call

Recorded by this site's tools run, step dashboard-render, with the published OODS Foundry 0.10.1.

Its input:

{
  "schemaVersion": "v0.1",
  "title": "Weekly orders",
  "datasets": [
    {
      "id": "orders",
      "rows": [
        {
          "week": "2026-09-07",
          "orders": 120
        },
        {
          "week": "2026-09-14",
          "orders": 135
        },
        {
          "week": "2026-09-21",
          "orders": 128
        },
        {
          "week": "2026-09-28",
          "orders": 150
        }
      ]
    }
  ],
  "panels": [
    {
      "id": "total",
      "kind": "kpi",
      "title": "Orders",
      "datasetId": "orders",
      "field": "orders",
      "aggregate": "sum"
    },
    {
      "id": "trend",
      "kind": "chart",
      "chartType": "line",
      "title": "Orders by week",
      "datasetId": "orders",
      "encodings": {
        "x": {
          "field": "week",
          "type": "temporal"
        },
        "y": {
          "field": "orders",
          "type": "quantitative"
        }
      }
    }
  ],
  "a11y": {
    "description": "Orders for four weeks: the total, and orders by week."
  }
}

Its result, first lines:

{
  "status": "ok",
  "schemaVersion": "v0.1",
  "panels": [
    {
      "id": "total",
      "kind": "kpi",
      "title": "Orders",
      "value": 533,
      "formatted": "533",
      "delta": null,
      "deltaPct": null,
      "trendDirection": "flat",
      "sparkline": [
        120,
        135,
        128,
        150
      ],
      "a11yDescription": "Orders: 533."
    },
    {
      "id": "trend",
      "kind": "chart",
      "chartType": "line",
      "renderer": "vega-lite",
      "title": "Orders by week",
      "a11yDescription": "Line chart of orders by week.",
      "spec": {
        "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
        "title": "Orders by week",
        "description": "Line chart of orders by week.",
        "data": {
          "values": [
            {
              "week": "2026-09-07",
              "orders": 120
            },
            {
              "week": "2026-09-14",
              "orders": 135
            },
            {
              "week": "2026-09-21",
              "orders": 128
            },
            {
              "week": "2026-09-28",
              "orders": 150
            }
          ]
        },
        "autosize": {
          "type": "fit-y",
          "contains": "padding"
        },
        "config": {
          "background": "#FFFFFF",
          "font": "Geist, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
          "title": {

The whole call, 6 KB of JSON