Articles

Dashboard as Code with Cube

Last updated October 2, 2026

Dashboard as Code with Cube means keeping report and dashboard definitions in source control and applying them to a deployment through an API. Teams build reports and dashboards in a workbook, retrieve their definitions over REST, assign stable identifiers, and use idempotent upserts to promote the same assets across deployments. The pipeline also resolves report IDs for each deployment before publishing the workbook.

What dashboard as code manages

Dashboard as code with Cube manages reporting assets: reports, workbooks, and the dashboards a workbook contains. A report is a saved query and visualization. A workbook is the container for a dashboard, while the dashboard layout records which widgets appear and where. In the workbook definition, that layout is stored in meta.dashboardDraft.

This workflow has a separate responsibility from the semantic layer. The semantic layer defines metrics, dimensions, joins, and access rules; reports and dashboards present questions over those definitions. Keeping the layers clear means a dashboard can change without silently redefining revenue or access policy. See what a semantic layer defines for the model underneath the reporting assets.

The REST endpoints are building blocks rather than a packaged bundle tool. Cube's business intelligence platform includes Dashboards, Workbooks, and Analytics Chat; the workflow here manages dashboard assets in that product through your own pipeline.

Choose stable identifiers before moving assets

Each asset needs an identity that survives a deployment. A report uses a publicId: a 12-character alphanumeric identifier that is unique across the account. A workbook uses a readable slug that is scoped to a deployment. The numeric IDs returned by the API are deployment-specific, so do not treat them as portable identifiers in Git.

Start by creating the report and dashboard in the UI, then read their definitions from the API and commit them. The GET /deployments/{deploymentId}/reports/{reportId} endpoint returns a report definition; the GET /deployments/{deploymentId}/workbooks/{workbookId} endpoint returns its workbook, including the dashboard draft. Keep the public ID with each report and the workbook slug with its definition. For an existing report without a public ID, assign one and keep it fixed: report public IDs are write-once.

Dashboard widgets in dashboardDraft refer to reports by numeric ID. Those IDs are stable inside one deployment but differ in another. During an apply, capture the IDs returned by report upserts and rewrite the workbook's widget references to the IDs for the target deployment. The stable public IDs and workbook slug identify the assets; the pipeline resolves their local numeric references.

Apply reports, the workbook, and then publish

An apply should run from a checked-in set of definitions and use the API key and deployment ID for the target environment. Store secrets in your CI system rather than in the repository. The REST API uses the deployment URL, a deployment API key, and the target deployment ID:

export CUBE_API_URL="https://<your-cube-cloud-host>"
export CUBE_API_TOKEN="<deployment-api-key>"
export DEPLOYMENT_ID="<deployment-id>"

Upsert each report by its public ID. The endpoint creates the report when that ID is not present in the deployment and updates it when it is:

curl -X PUT \
  "$CUBE_API_URL/api/v1/deployments/$DEPLOYMENT_ID/reports/by-public-id/$PUBLIC_ID" \
  -H "Authorization: $CUBE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @report.json

Once all report upserts succeed, update the workbook's dashboard draft with the IDs returned for those reports, then upsert the workbook by slug:

curl -X PUT \
  "$CUBE_API_URL/api/v1/deployments/$DEPLOYMENT_ID/workbooks/by-slug/$WORKBOOK_SLUG" \
  -H "Authorization: $CUBE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @workbook.json

The workbook request carries the dashboard layout in meta.dashboardDraft. After the upsert, publish the workbook using the ID returned by that request. Publishing makes the dashboard visible to viewers and is idempotent for the workbook:

curl -X POST \
  "$CUBE_API_URL/api/v1/deployments/$DEPLOYMENT_ID/workbooks/$WORKBOOK_ID/publish" \
  -H "Authorization: $CUBE_API_TOKEN"

The full report and dashboard definitions are large, generated structures; exporting them from the UI and reading them back through the API is safer than writing them by hand. The dashboard as code documentation has the request bodies and endpoint references.

Make the pipeline repeatable

The stable keys and upsert endpoints let the same definition be applied again without creating a duplicate. That is useful for repeatable staging-to-production promotion and for rerunning the same release pipeline. Keep the steps ordered: reports first, resolve their returned IDs, write the workbook draft, and publish only after both kinds of upsert have succeeded.

Add checks around the workflow that protect your own release process: verify that every widget reference maps to an upserted report, keep development and production credentials separate, and require review for changes to the saved query or visualization. The semantic layer architecture guide covers the governed model and query path on which those reports depend.

Dashboard as code controls the reporting artifact lifecycle; it does not decide what a metric means. The model still needs deliberate definitions and review. The dashboard software comparison covers the broader platform selection question, while the embedded analytics implementation guide is useful when the dashboard is part of a customer-facing product.

Cube's API workflow in context

Cube is the agentic analytics platform, built on a semantic layer. The same governed model supports internal business intelligence and embedded analytics, with dashboards as one surface people use alongside workbooks and Analytics Chat. The modeling investment is still real: teams define metrics and permissions before dashboard automation can apply them consistently. The benefit of managing reporting assets as code is that edits become visible, repeatable changes in the release process, while Cube continues to compile queries against the warehouse and enforce the model's rules.

Frequently asked questions

What is dashboard as code?
Dashboard as code is a way to manage dashboard and report definitions in version control and apply them through an API. The definitions can then be reviewed and promoted between deployments by a CI/CD pipeline, instead of living only in an analytics UI.
How does dashboard as code work in Cube?
Build reports and a dashboard in a workbook, retrieve their definitions through the REST API, and store the definitions in Git. Give each report a stable public ID and the workbook a slug, upsert the reports, apply the workbook with its dashboard draft, and publish it.
How do I deploy Cube dashboards from staging to production?
Apply each report definition to the target deployment first and capture the report IDs returned there. Update the workbook dashboard draft to reference those IDs, upsert the workbook by its slug, and publish it in the target deployment. Keep the API token and deployment ID specific to the environment.
Are Cube dashboard upserts idempotent?
Yes. The report and workbook upsert endpoints use stable identifiers, so applying an unchanged definition again is a no-op. Publishing a workbook is also idempotent, which makes repeated pipeline runs safe.
Can I manage an existing Cube report as code?
Yes. Read the report and workbook definitions through the REST API, assign a stable public ID to a report that does not have one, and store the definitions in your repository. A report's public ID is write-once, so keep an existing ID rather than replacing it.
Does Cube have one command to export and deploy a dashboard bundle?
No. The REST endpoints are primitives for a workflow that you assemble in your CI/CD system. Your pipeline is responsible for storing the definitions, upserting reports and workbooks in order, resolving report IDs, and publishing the workbook.

Get started with Cube