---
title: get_dashboard_spec
description: Read back a spec-backed dashboard's spec verbatim plus its hash, for the edit-and-republish loop. Parameters, errors and scope.
updated: 2026-08-27
tools: [get_dashboard_spec]
---

Reads back a dashboard's stored Dashies spec **verbatim**: comments, formatting
and the trailing newline intact, byte-identical to what was published. It also
returns the `spec_hash`.

This is the read half of the edit loop. Fetch the spec, change one field, then
republish to the same slug with
[`publish_dashboard`](/reference/mcp-tools/publish-dashboard), passing
`base_spec_hash` set to the hash you got here so a parallel edit is caught rather
than clobbered.

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

## Parameters

| Parameter | Type | Required | Notes |
|---|---|---|---|
| `slug` | string | yes | Canonical slug of the dashboard whose spec to read. |
| `workspace` | string | no | Workspace slug. |

## Returns

The human summary deliberately does **not** include the spec text. The spec is in
the JSON block.

```text
Spec for "revenue-overview" (https://acme.dashies.ai/revenue-overview):
Name: Revenue Overview
Spec hash: 6f1c9d...
Spec size: 2841 bytes (the spec text is in the JSON block below).

BEGIN_JSON
{"slug":"revenue-overview","url":"https://acme.dashies.ai/revenue-overview","name":"Revenue Overview","spec_hash":"6f1c9d...","spec":"dash: 1\n...","refresh_not_installed":false}
END_JSON
```

A spec-backed dashboard whose manifest failed to install additionally prints
`spec declares a schedule but refresh is NOT installed - republish to install.`

A dashboard published as raw HTML, or restored from a version predating specs, is
an **`ok: true` result** with the not-spec-backed text and
`{"spec_hash":null,"spec":null}`. It is not an error.

:::tip{title="For a small change, send edits rather than the whole document"}
The `spec_edits` argument on `publish_dashboard` applies exact-string
replacements against the stored spec, so comments, ordering and formatting
everywhere else survive byte for byte. Copy the span you are replacing verbatim
out of the JSON block here, indentation included, and pass the `spec_hash` you
got as `base_spec_hash`.
:::

## Errors

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

| Condition | Text |
|---|---|
| The read failed | `spec lookup failed: <err>` |
| No such dashboard | `No dashboard named "<slug>" in that workspace.` |
| The stored bytes do not match the stored hash | `The stored spec for "<slug>" failed its integrity check (spec_hash does not match the stored bytes). This is a server-side data issue; please report it.` |

That integrity check runs on every read. It exists so a corrupted spec is
refused rather than handed to you as the basis for a republish.

## Scope

Any member of the workspace may read the spec of its
dashboards.

## Check it worked

Hash the returned spec bytes yourself and compare against `spec_hash`. Then, on
the republish, confirm the receipt's `Spec hash` differs from the one you passed
as `base_spec_hash`, which is what tells you your edit actually landed rather
than being a no-op.
