---
title: "Render a template before it is published"
method: GET
path: "/dashboards/v3/templates/admin/{slug}/canvas"
tags: ["Dashboard v3 Template Admin"]
---

# Render a template before it is published

`GET /dashboards/v3/templates/admin/{slug}/canvas`

## Request

- Base URL: `https://app.mammoth.io/api/v2`
- URL: `https://app.mammoth.io/api/v2/dashboards/v3/templates/admin/{slug}/canvas`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-KEY` and API key in header `X-API-SECRET` and API key in header `X-WORKSPACE-ID`

The template's own canvas plus its baked plan and specs — the same payload the editor reads, so the panel renders a draft with the same code it renders a live one.

This exists because a draft had no readable board anywhere. The row's `preview_token` is the source dashboard's PUBLIC share url and is null until it is published, and the by-id editor read is gated on per-dashboard workspace access, which a curated-grant operator who did not run the import does not have. So the only way to see a template was to publish it — which is the same action that puts it in front of every customer. Reviewing before shipping is the entire point of a draft, and it was the one thing a draft could not do.

Static, no data, and no workspace: same gate as this panel's data preview, which is identity plus curated-only. Live rows are served too — one door, so the panel does not branch on state.

## Path parameters

- `slug` string, required

## Response `200`

Canvas + baked plan/specs (no data, no RLS resolution)

- CanvasResponse
  - `canvas` object, required
  - `plan` object, nullable
  - `specs` object
  - `meta` CanvasMeta, required
    - `sequence` integer, required
    - `signature_token` string, nullable
    - `signature_locked` boolean
    - `artifact_version` string, nullable
    - `filters` object
    - `figures` object
    - `stale_bake` boolean
    - `bake_error` union
      - object
      - string
    - `heal_notes` string[]
    - `unbuilt_notes` string[]
    - `fanout_notes` string[]
    - `unweighted_means` string[]
    - `broken_bindings` object[], nullable
    - `receipts` object
    - `context_drift` object[]
    - `published_context_drift` object[]
    - `context_baseline` boolean, nullable
    - `currency` object, nullable
    - `on_sample_data` boolean
    - `sanctioned_demo_publish` boolean
    - `rls_scoped` boolean
  - `dashboard_id` integer, nullable
  - `unavailable_files` UnavailableFileType[]
    - `id` integer, required
    - `name` string, required

## Other responses

- `400`: Bad request syntax or unsupported method
- `403`: Request forbidden -- authorization will not help

---

[API](https://skmtc.dev/mammoth/apis/mammoth-analytics.md) · [All operations](https://skmtc.dev/mammoth/apis/mammoth-analytics/llms.txt) · [OpenAPI document](https://skmtc.dev/mammoth/apis/mammoth-analytics/revisions/fe078afe239b?raw)
