---
title: restore_dashboard_version
description: Roll a dashboard's body back to a prior snapshot. Parameters, the reversibility guarantee and when it does not hold, errors and scope.
updated: 2026-08-27
tools: [restore_dashboard_version]
---

Replaces a dashboard's body with a prior snapshot's bytes. The slug, URL and
metadata (name, tags, chart) are unchanged, and the new body is live
immediately.

Use [`list_dashboard_versions`](/reference/mcp-tools/list-dashboard-versions)
first to choose a `version_id`. Do not guess one.

Behaviour hints for clients: not read-only, **not** destructive, idempotent, not
open-world.

## Parameters

| Parameter | Type | Required | Notes |
|---|---|---|---|
| `slug` | string | yes | Canonical slug of the dashboard to restore. |
| `version_id` | string | yes | A UUID belonging to this dashboard, from `list_dashboard_versions`. |
| `workspace` | string | no | Workspace slug. |

## Returns

```text
Restored revenue-overview to version 2c91....
URL: https://acme.dashies.ai/revenue-overview
The previous body was archived as version 5f77... first, so you can roll back to it with restore_dashboard_version.
```

That third line is the reversibility guarantee: the body you just replaced was
snapshotted before the restore, and the id it names is how you undo. **Read it,
because it does not always hold.** When the pre-restore snapshot did not land,
the third line reads instead:

```text
Note: a pre-restore snapshot of the previous body could not be saved, so this particular restore may not be undoable.
```

The restore still happened. What is missing is the way back.

The URL line reads `URL: https://<workspace-slug>.dashies.ai/<slug>`, and it is **omitted
entirely** when the authorization carries no workspace slug to build it from. That is the one
case where the receipt has no URL at all, and it is a property of the AUTHORIZATION rather
than of the dashboard: a grant locked to a workspace whose slug it does not carry.

## Errors

The shared [slug and version-id rules](/reference/mcp-tools/conventions#paths-and-slugs),
plus:

| Condition | Text |
|---|---|
| The version cannot be used | `version not found` |
| The version is usable but the slug names no dashboard | `dashboard not found` |
| The version belongs to a different dashboard of yours | `version does not belong to this dashboard` |
| The version lookup failed | `version lookup failed: <err>` |
| The dashboard lookup failed | `dashboard lookup failed: <err>` |
| A workspace was named but not routed | `workspace target not resolved: this request names a workspace but was not routed to one (the caller must resolve the workspace and wire workspace-scoped deps)` |

**The version is resolved before the dashboard is**, so a version id that does not resolve
reports `version not found` even when the slug names nothing either. `dashboard not found`
therefore means the version resolved and the slug did not.

:::note{title="version not found covers three causes, and a fourth is answered separately"}
Absent, belonging to someone else, or stored under a non-canonical key all collapse
into the same sentence. Distinguishing those would turn the refusal into an oracle
for which version ids exist.

**A version of a DIFFERENT DASHBOARD OF YOURS does not collapse**, and this page said it
did: the belonging guard answers `version does not belong to this dashboard`. That
discloses nothing, because both operands are already yours. The version resolved under
owner-only RLS and the slug resolved in your own scope, so a refusal that tells the two
apart tells you only about rows you can already read.

`get_dashboard_version` and `update_dashboard_version` fold that same case back into
`version not found`, so the three sibling version tools carry two behaviours here.
:::

## Ordering

The ordering is load-bearing and worth knowing when a restore fails partway:
every authorization check runs before any write; the reversibility snapshot of
the current body is taken before the destructive copy; and the database update is
last. So a failure early leaves the live dashboard untouched, and a failure late
leaves it restored.

## Scope

**Any current member may restore**, which is the same set of
people who can republish the body.

## Check it worked

Load the dashboard URL and confirm it renders the older body. Then run
[`list_dashboard_versions`](/reference/mcp-tools/list-dashboard-versions) and
confirm the version id the receipt named is present, which is what makes the
restore undoable.
