---
title: "Targeted spec diff of a version vs. its predecessor."
method: GET
path: "/v1/dashboards/{id}/revisions/{version}/diff"
tags: ["dashboards"]
---

# Targeted spec diff of a version vs. its predecessor.

`GET /v1/dashboards/{id}/revisions/{version}/diff`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/dashboards/{id}/revisions/{version}/diff`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Returns a property-level before→after diff of this version's dashboard spec against the
immediately preceding version (version-1) — only what changed, not the whole spec. Objects
are diffed by key; arrays of spec elements (panels, pages) are matched by `id` so reorders
don't register as changes. The first version (no predecessor) is reported as `initial: true`
with the whole spec as one added subtree at the root path. The change list is capped; when
the cap is exceeded `truncated` is true and `totalChanges` reports the full count. Read
access follows the dashboard — requires `dashboard:read` plus the same per-resource read
authorization as GET /v1/dashboards/{id}.

## Response `200`

The targeted spec diff for this version.

- RevisionDiffEnvelope
  - `data` RevisionDiff, required: A targeted property-level diff of a dashboard version against its predecessor.
    - `version` integer, required: The version being diffed.
    - `baseVersion` integer, required: The predecessor version diffed against (0 when this is the initial version).
    - `initial` boolean, required: True when this version has no predecessor; `changes` is the whole spec as one added root subtree.
    - `changes` SpecChange[], required
      - `path` string, required: Human-readable path to the changed value; empty string for the whole-spec root (initial version).
      - `op` 'added' | 'removed' | 'changed', required
      - `pageId` string: Id of the page containing this change (the `pages#<id>` path segment), when the change is under one. This is the machine-resolvable deep-link target: unlike `path`, it is unambiguous when an id itself contains `.` or `#` (DVT-1873). Absent for a dashboard-level change or a positional (id-less) array element.
      - `elementId` string: Id of the outermost enclosing panel (the first `panels#<id>` path segment) — the grid cell a client should scroll to. Absent for a page-level or dashboard-level change.
      - `before` unknown
      - `after` unknown
    - `totalChanges` integer, required: The full number of changes found, even when `changes` is capped.
    - `truncated` boolean, required: True when the change list was capped and does not include every change (`totalChanges` reports the full count).
  - `meta` Meta, required: Response metadata.
    - `requestId` string, required: Correlates with the X-Request-Id header.
    - `total` integer: Item count, present on collection responses.
    - `nextCursor` string, nullable: Opaque keyset-pagination cursor, present on paginated responses (e.g. GET /v1/dashboards) when more rows exist beyond this page. Pass it back as the `cursor` query param to fetch the next page; absent or null on the last page.
    - `roleResolveDegraded` boolean: Snowflake mode only (DVT-2260), on GET /v1/dashboards: present and true when the caller's live Snowflake role resolution failed or was unavailable — role-shared dashboards may be missing from this page. Omitted (not merely false) whenever resolution succeeded or the role-share arm does not apply (off snowflake mode, an org admin/owner, or off the ingress listener).

## Other responses

- `400`: Malformed request.
- `401`: Missing, invalid, or expired session.
- `403`: The caller's role does not permit this action.
- `404`: Resource does not exist.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
