Blocks
A block is a unit of work in a dashboard. Every block has an id, a type, a config, an optional output_name it publishes under, and zero or more outputs. Producers (SQL, code) write a named result; consumers (chart, render, filter, markdown) read by name.
Any block can be displayed in the dashboard’s grid. Displayed blocks are the roots of the dashboard; non-displayed blocks live as internal upstreams reachable through config.source or config.inputs. The decision about what to show is independent of what runs.
Runs a SQL query against any source in the dashboard’s catalog and writes the result back to the catalog under a name you choose.
The two config keys that matter:
sourceis the input. Any name from the dashboard’s catalog (a connector, an upstream block’soutput_name, or an imported / pushed table).output_nameis what your result is published as. Downstream blocks reference this name.
A SQL block reads from the catalog and writes back to the catalog. The rest of the dashboard is built on this loop.
SELECT year, SUM(value) AS total_gdpFROM gdpGROUP BY yearORDER BY yearParameters
Section titled “Parameters”Write $name for every parameter you want bound at run time. Declare each one in config.inputs so the cascade walker knows the dependency. The engine translates $name to the destination dialect: psycopg sees %(name)s, DuckDB binds $name natively. Subscribed filter / param blocks supply values automatically.
The default visualization block. Runs a Python transform against an upstream output and returns HTML. Same sandbox and def transform(df): ... contract as code. config.source names the upstream output_name; the rows arrive as a DataFrame.
The agent reads BitBoard’s chart design guide (palette, type voice, axis rules, layouts) before producing the HTML, so charts across dashboards stay visually consistent.
Use chart for any standard visualization (line, bar, area, scatter, KPI tile, table).
render
Section titled “render”Identical runtime to chart, with no design guide applied. Use it for things the guide forbids or doesn’t cover: custom interactive controls that pilot filters, narrative HTML, off-rail styling. Visual consistency is the agent’s responsibility here, so reach for chart first.
A render block can call back into the dashboard from inside its iframe via the bridge: bb.query, bb.setFilter, bb.refresh. Use this to build a custom widget that drives other blocks.
Runs a Python transform over input rows. Same source/output convention as sql: reads one source from the catalog and writes a new source back. Use this when the transformation is awkward in SQL (string parsing, custom aggregation, calls to a small library) or when you want non-tabular logic in the middle of a tabular pipeline.
Must define def transform(df): ... returning a DataFrame, scalar, image, or HTML.
Calls a connector’s tool (Stripe, PostHog, etc.) and materializes the payload as a queryable output. The block’s source is a JSON args template; config.params_defaults supplies the default arguments; params on a run overrides them for one call.
The output appears in the catalog under output_name, so downstream SQL and chart blocks read it like any other source.
filter-daterange
Section titled “filter-daterange”A control block. Its source is the JSON-encoded selected value: a relative string like "7d" or "30d", or a concrete range {"start": "2026-01-01", "end": "2026-03-01"}. Subscribers reference this block via config.source (or in config.inputs).
Displaying the filter on the dashboard renders the picker; changing the picker re-runs subscribers with the new value.
param-enum
Section titled “param-enum”A control block whose source is one value chosen from a list of options. Subscribers reference it the same way as filter-daterange. Use this for “metric: revenue | orders | users” style toggles.
markdown
Section titled “markdown”Prose with embedded references to sources, runs, and other blocks. Use it for narrative around your data: what you’re showing, what to look for, what changed since last week. A markdown block has no inputs or outputs and never reruns.
document
Section titled “document”A long-form, page-shaped block. Non-runnable. Treat it as a heavier markdown block when you want a full write-up alongside the visuals.