Skip to content
datasquares.aiSign inStart free

Metrics & Governance

Lifecycle: export, import & restore

Dashboards, data models and governed metrics can leave a workspace as definitions — portable JSON artifacts with no data and no credentials in them — and be imported into another workspace. Alongside that, dashboards carry immutable version snapshots, a field-level diff, and a restore. Together they cover the dev → prod path: build in one workspace, export, import, promote, and roll back if it goes wrong.

Every list page has an export affordance:

Where Control
Dashboards list Export definition in the card’s ⋯ menu (More actions for <name>)
Data Models list a download icon on the row (hover) — accessible name Export <name>
Metrics hub an Export button on the row (hover), or in the metric’s drawer

You get a lowercase, filesystem-safe name with spaces and punctuation other than ., _ and - replaced by hyphens: <name>.<assetType>.json, for example q3-revenue.dashboard.json.

This is the part that matters most, so be precise about it. An exported artifact contains no data, no credentials, and no workspace IDs. Every binding to something workspace-local is replaced by a symbolic reference:

Reference Means
$model:0, $source:0, $metric:0, $query:0 a positional reference — you map it to a real object at import ($query:0 is the saved query a metric reads)
$field:{tableAlias}.{fieldName} a model field, resolved by name in the target model
$table:{tableAlias} a model table, resolved by alias
$measure:{name} a SquareX measure, resolved by name

The positional references are listed in the artifact’s references block with their original names, so the import screen can show you “Orders Model” rather than a bare token.

Serialization is deterministic — sorted keys, no timestamps, and symbolic references instead of workspace-local UUIDs — so the same unchanged asset exports byte-identical every time. That is what makes these files git-diffable: commit them, and a pull request shows exactly what changed.

Dashboard artifacts also embed definitions for dashboard-bound saved queries (name, SQL, description, and a symbolic source reference). Import recreates those queries with fresh IDs before it creates the cards, so saved-query cards do not arrive as “Not configured.”

A metric’s artifact carries its whole definition: what it reads ($model:0, or $query:0 for a metric on a saved query), its expression, time dimension, grain, filters, how it adds up, a ratio’s parts, settlement lag and close day, and its target, thresholds, format, Better when, description and domain. Its owner and its certification stay behind. A saved query is named in the file only when the person exporting may read saved queries.

Click Import on the Dashboards, Data Models or Metrics list (or Import a definition on the New dashboard page). The Import a DataSquares export dialog opens.

  1. Paste the JSON into Exported artifact (paste the JSON, or choose a file), or pick the file with Choose file. Invalid JSON shows “Not valid JSON yet.”, and JSON that isn’t an export says This isn’t a DataSquares export artifact — it’s missing …
  2. As soon as the JSON parses as an export, the Map references to this workspace section appears — one row per positional reference, labelled with its original name (e.g. Orders Model (model), Prod Postgres (source)). Pick the matching object in this workspace from each dropdown (they start at choose…).
  3. Optionally press Check — a dry run that resolves everything without writing, and reports anything it couldn’t match and any saved query of a dashboard that fails the safety check.
  4. Press Import.

Import stays disabled until every required reference is mapped. Mapped IDs are validated against the current workspace, so you cannot graft an asset onto another tenant’s model.

A dashboard’s saved queries pass the same safety check as saving a query, in the SQL of the source each is mapped to: a statement that would be refused when run (anything but a single read-only SELECT or WITH query that DataSquares can parse in that source’s SQL) is refused. Check lists each refused query with the check’s reason, and Import stays disabled while the list stands. If any query is refused, the whole import is refused: no dashboard, saved query or card is created, and the error names each query with its reason. Changing a mapping clears the list, since another source may read a query differently; press Check again. A hand-edited definition whose query names a data source outside this workspace is refused as not found.

The API has an allowUnresolvedFields escape hatch, but the web dialog does not expose it. In the UI, unresolved $field, $table, or $measure references block the real import after Check reports them.

A metric on a saved query maps its $query:0 row to one of this workspace’s saved queries (the first 200 by name). Someone who may not read saved queries is told You can’t read this workspace’s saved queries, so the metric’s saved query can’t be mapped. Ask someone who can open the SQL editor.

An imported metric is made as Create metric makes one: its formula is checked against the mapped data model or saved query (a part that fails is refused, named), it starts at version 1, it is owned by you, and the import is in the audit log.

A metric’s file has Import as: A new metric (Makes a new metric from the file, owned by you.), or, under Update an existing metric, one of this workspace’s metrics, which the file is imported over: Updates Revenue and keeps it, so its cards, alerts and decks read the file’s definition. Check shows what changes before anything is written. This is how a changed definition is promoted from a test workspace to a live one without breaking what uses it.

Check shows the plan first, and Update stays disabled until it has:

  • Updates Revenue: 2 changes, each part by its name (Period: month → quarter, Filters [0].value: EU → US), or Revenue already matches this file: there is nothing to update.
  • the version it makes, Makes version 4 (it is at version 3): what it computes changes., or Makes no new version: only how it is named and shown changes.;
  • It clears Revenue’s certification: its new version must be certified again., when it does;
  • anything that would refuse it, under It can’t be imported over Revenue while:, such as a certified metric that only its owner or a workspace admin may change.

A new target or a new mapping makes the plan stale: Check again. An update writes only the parts that change, as an edit does, and needs the Metrics edit permission. Through the API it is POST /api/alm/import with targetId, whose dry run is the plan.

Import creates a new asset — except a metric imported over an existing one (above), and a pipeline, which is updated in place. It does not update, merge into, or overwrite an existing dashboard or model. Treat the artifact as the source of truth and the import as a deploy of a new object, not an in-place upgrade.

Metric names are unique per workspace, so a collision is different: Check reports the conflict and the dialog proposes <name> (imported), with Update Revenue instead to import over the metric of that name. Choose a different name, or update it, before importing. Dashboard and model imports still mint a new asset rather than updating one with the same name.

Once the positional refs are mapped, fields, tables and measures resolve by name against the target model. If the target model’s aliases and field names match the origin’s, everything binds. If they don’t, you get an amber warning — “Unresolved in the mapped model (aliases/field names must match):” — with the list. Fix the target model’s naming, or re-export from a workspace that matches.

Open a dashboard in the editor and choose Versions on the rail at the left (the command Versions & deploy does the same). (It’s hidden in preview mode, and needs edit permission.) The drawer says Each publish is a version. Compare it with the draft, restore it, or move it through the deployment stages.

Publish New Version snapshots the dashboard — name, description, layout, theme, filter state, pages, cards and filters — as an immutable version. The strip shows the current version number and whether it’s Published or Draft — publish to deploy, the deployment stages, plus the Version history (latest 10). Each stage shows the version deployed to it, or Not deployed, and requires publish when it does. With no published version yet, it says No versions published yet. Publish to start the deployment pipeline.

  1. Versions, on the editor’s rail: the current version and whether it is published, Changes since the last version, Publish New Version, the deployment stages (none until some are added through the API) and the version history, each with diff and restore.

    Versions, on the editor’s rail: the current version and whether it is published, Changes since the last version, Publish New Version, the deployment stages (none until some are added through the API) and the version history, each with diff and restore.

The diff compares two snapshots field by field and reports one entry per changed leaf, with readable paths — cards and filters are matched by ID but labelled by title, so you read:

cards."Revenue by month".chartSpec.yFields[0].aggregation sum → avg

The summary counts + added, − removed, ~ changed, and an unchanged comparison says “No differences — the two versions are identical.”

You reach it from four places:

Control Compares Gates anything?
Changes since v{n} the published version → your working state no — preview
diff (per version row) the previous version → that version no — preview
Promote to {stage} the version already on the stage → the one you’re promoting yes — see below
restore your working state → the version you’re restoring yes — it’s the confirm step

Promote to {stage} deploys to the next stage in your pipeline. What it deploys is the dashboard’s latest published version, or, when the next stage requires publish, a new version it publishes from the working state first (Auto-published on promotion to ‘…’). When the target stage already has a different version deployed than the stage you promote from, the diff opens first as a confirmation, and the deploy only fires when you confirm Promote v{n} to {stage}. The diff compares the two stages’ versions, so when the dashboard has been published, or edited for a stage that requires publish, since the source stage was deployed, the version deployed can be newer than the one the diff shows: publish and deploy in order to keep them the same.

On a stage with nothing deployed, Deploy v{n} deploys the newest published version to it. The editor has no control to deploy an older version, to take a version off a stage or to change the stages: those are API-only. POST /api/dashboards/{id}/deploy deploys any version to any stage (rolling a stage back is deploying an older version to it), DELETE /api/dashboards/{id}/deploy/{stage} takes the dashboard off a stage, and GET/POST /api/dashboards/stages and DELETE /api/dashboards/stages/{stageId} list, add and remove the workspace’s stages (a stage a dashboard is deployed to can’t be removed). Workspaces created since stages were introduced start with none, so their Versions drawer shows no stages until some are added through the API. Promoting and deploying are not recorded in the audit log.

Company admins can delete a dashboard from the library. It leaves the library at once and waits in the Recovery Center for the workspace recovery window. The one exception to needing the delete permission is a draft you created and never touched — see Drafts nobody touched.

  1. Open Dashboards and find the dashboard, here by searching its name. Deleting needs the delete permission on dashboards, which company admins have and the author role does not.

    Open Dashboards and find the dashboard, here by searching its name. Deleting needs the delete permission on dashboards, which company admins have and the author role does not.
  2. Open the More actions menu on its card and choose Move to Recovery Center. The dialog that follows says how long it stays there.

    Open the More actions menu on its card and choose Move to Recovery Center. The dialog that follows says how long it stays there.
  3. A confirmation titled Move dashboard to Recovery Center says the dashboard and its cards move to Recovery Center, where an admin can restore it for 30 days (the workspace recovery window). Choose Move to Recovery Center to go ahead, or Cancel to keep the dashboard in the library.

    A confirmation titled Move dashboard to Recovery Center says the dashboard and its cards move to Recovery Center, where an admin can restore it for 30 days (the workspace recovery window). Choose Move to Recovery Center to go ahead, or Cancel to keep the dashboard in the library.
  4. The dashboard leaves the library and waits in the Recovery Center for the workspace recovery window; someone with the restore permission can bring it back (see the Recovery Center walkthrough).

    The dashboard leaves the library and waits in the Recovery Center for the workspace recovery window; someone with the restore permission can bring it back (see the Recovery Center walkthrough).

Deleted dashboards, reports, stories, presentations and metrics wait in the Recovery Center. Restoring needs the recovery restore permission.

  1. Open Recovery. Deleted dashboards and reports wait here for a limited time before they are gone for good.

    Open Recovery. Deleted dashboards and reports wait here for a limited time before they are gone for good.
  2. View details shows what restoring would change. Restore is deliberately safe: the definition returns unpublished, and public links, schedules and alerts stay off until an owner reviews them. Restoring needs the recovery restore permission.

    View details shows what restoring would change. Restore is deliberately safe: the definition returns unpublished, and public links, schedules and alerts stay off until an owner reviews them. Restoring needs the recovery restore permission.

Each row says how the item left. A person’s delete reads Deleted, the time and the person’s name. A draft the system cleared reads Removed automatically, the time, and an untitled draft nobody changed for 7 days — no person is named, because none deleted it.

Preview restore opens the restore dialog. It starts with what to know before the item comes back, under Before you restore (1 public link will stay disabled. Published state remains off until the restored item is reviewed and published again.), then lists What returns and what Stays disabled. Restore safely restores it.

A deleted story waits like a dashboard or report, for the same recovery window, and the Type filter has a Stories choice. Nothing of it is removed while it waits — its sections, versions, comments, review rounds and decisions, follows and activity all stay — so a restore brings it back whole, with the two differences dashboards and reports have:

  • It comes back unpublished. A published story returns as a draft, with its versions kept in its history; publish it again when it is ready. An archived story stays archived.
  • Its access grants are removed. The people and groups it was shared with lose that access, and the preview says how many to add again. A review round that was open stays open, and its reviewers can open the story again once you share it with them.

A story has no public links, schedules or alerts, so there are none to switch off. It also keeps the privacy a story has everywhere else: you see a deleted story in the Recovery Center — in the list, the counts and Recent recoveries — only if you could have read it, meaning you own it, you are an admin, it was published and your role can view Stories, or it was shared with you directly or through a group. Restoring needs the recovery restore permission, as for the others, and leaves a receipt and an audit event.

A deleted presentation waits like a story, with the same privacy, and comes back the same way: as a draft, with its versions, records and comments kept and its access grants removed. Its schedules are switched off and counted in the preview and the receipt, as a dashboard’s and a report’s are, so publishing it again never resumes mailing its people and groups by itself: turn each schedule on again when it should send.

A deleted governed metric waits for the same recovery window, under the Type filter’s Metrics choice. It comes back with its own id: its definition, versions, owner, domain, target and certification return, and the dashboard cards, deck and story figures that name it read it again. What it reads is read again as it comes back: when its saved query, a measure or a field under it changed while it was deleted, it comes back as its next version, uncertified, and its owner is told. What returns says so.

A delete made while something used the metric turned its alerts and activations off and took it out of its digests. They stay that way for their owners to turn on again: Stays disabled names each one (Alert “Revenue under plan”, Digest “Monday numbers” no longer lists it), and the receipt counts the alerts. The anomaly sweep’s own record of the metric, and an alert that was already off before the delete, are not among them. A restore is refused when a live metric has taken its name, or when what it read was deleted since.

Before you restore says the same in sentences (Its delete turned off alert “Revenue under plan”: they stay off until their owners turn them on.), and the toast that says it is restored (Revenue restored safely) lists them again, with a line when it came back as a new version (What it reads changed while it was deleted, so it came back as version 4 and is no longer certified: an admin certifies the new version again.).

Blank dashboard, Blank report and Blank story (and the other ways on the New … pages that open an editor) create the item at once — the editor needs somewhere to save to — so opening one and leaving without adding anything leaves an Untitled Dashboard, Untitled Report or Untitled story behind. Two things stop these piling up:

  • You can delete your own. The Editor role can create and edit content but not delete it; for a draft you created and have not touched, that does not apply. The Dashboards list offers Move to Recovery Center in its ⋯ menu and the Reports list Delete on it, and a story’s owner deletes it from the story’s ⋯ menu; it moves to the Recovery Center like any deleted item. Anyone else’s draft, and anything that is more than a draft, still needs the delete permission. A saved query you created that nothing uses can be deleted without that permission too — see Deleting a saved query of your own — but a saved query’s delete is permanent: it does not wait in the Recovery Center.
  • Untouched drafts are removed after 7 days. A sweep that runs every hour removes a draft that is still untouched and that nobody has changed for 7 days. It waits in the Recovery Center for the recovery window like any deleted item, marked Removed automatically. The audit log records the removal as dashboard.deleted, report.deleted or story.deleted with no user and the reason untouched_draft, and webhooks subscribed to dashboard.deleted or report.deleted receive it with that reason in place of deletedBy.

Untouched means all of this, so one change — a new name, a card, a line of text — makes the draft an ordinary one that is never swept:

Untouched when
Dashboard still named Untitled Dashboard, with no description, cards, filters or saved versions, and never published
Report still named Untitled Report, not a template, with no description, blocks, filters, table definition, versions or schedules, and never published
Story still titled Untitled story, with no summary or saved version, no section that has a title, an assignee, a due date, text or AI-written content, and never published

The 7 days is fixed. It is not the workspace recovery window, which is how long a removed item can then be restored.

In Version history, every version other than the current one has a restore link. Clicking it opens the diff (Restore v{n}) — each changed field with your working state’s value struck through, then → and that version’s value — and the confirm button reads Replace working state with v{n}.

Restore replaces the dashboard’s working state with the snapshot (keeping the original card and filter IDs), then auto-publishes, so the restore is itself a new version. Nothing is lost: the history records that the new version was restored from the old one, and you can restore back out of it.

Publishing a data model now stores a real definition snapshot. Open the model’s Version history and choose Restore on an older version to put its tables, relationships, fields, measures and policies back into the working definition. Existing IDs are preserved where possible so dashboard cards, filters and data-quality tests keep their bindings.

Model restore does not publish automatically and does not create another version. Review the restored working definition, validate it, and publish it when it is ready; that publish creates the next snapshot. The restore runs in one transaction and reconciles tables, fields, relationships, hierarchies, RLS policies, measures, and table transforms in dependency-safe order. When it changes what a governed metric of the model reads (a measure, a calculated field, the column a field reads), that metric gets its next version in the same transaction, its certification is cleared and its owner is told; the model’s other metrics are left as they are.

Version history starts with the first publish made after snapshot versioning was introduced; older version numbers do not have a snapshot to restore. The current model dialog executes Restore directly—there is no model diff or second confirmation step.

Walkthrough: change how long deleted items can be restored

Section titled “Walkthrough: change how long deleted items can be restored”

Admins choose the recovery window for the workspace. The steps stop before saving.

  1. Open Recovery in the sidebar. The Restore window card shows how long deleted dashboards and reports stay restorable; only admins see the Change button.

    Open Recovery in the sidebar. The Restore window card shows how long deleted dashboards and reports stay restorable; only admins see the Change button.
  2. Choose Change, then enter a length in whole days. Longer windows keep deleted items restorable for longer; choose Save changes to apply it.

    Choose Change, then enter a length in whole days. Longer windows keep deleted items restorable for longer; choose Save changes to apply it.
  3. A shorter window takes effect immediately: items deleted longer ago than the new length can no longer be restored. The warning appears, and the button says Shorten restore window, so it is a deliberate choice.

    A shorter window takes effect immediately: items deleted longer ago than the new length can no longer be restored. The warning appears, and the button says Shorten restore window, so it is a deliberate choice.
  • Field-level diff, promotion stages and auto-publishing restore remain dashboard-only. Models have snapshot history and restore, but no promotion pipeline or pre-restore field diff. Metrics still have no version restore.
  • Import always creates a dashboard or a model. There is no “update this existing dashboard from this artifact” path; only a metric (imported over an existing one) and a pipeline are updated in place by importing them.
  • No approval step or Git sync yet. Release management on Enterprise is the import above; an approval before a release goes live, a side-by-side compare of two workspaces and Git sync are not built.
  • Fields resolve by name, so renaming a field in the target model breaks imports that referenced it.