---
title: "Duplicate a v3 dashboard"
method: POST
path: "/dashboards/v3/{dashboard_id}/duplicate"
tags: ["Dashboard v3"]
---

# Duplicate a v3 dashboard

`POST /dashboards/v3/{dashboard_id}/duplicate`

## Request

- Base URL: `https://app.mammoth.io/api/v2`
- URL: `https://app.mammoth.io/api/v2/dashboards/v3/{dashboard_id}/duplicate`
- 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`

Copy an existing v3 dashboard: a new engine=v3 row over the SAME dataset, the source's draft canvas copied verbatim (titled 'Copy of <title>') with its baked bundle carried onto the copy so it opens without a re-bake. Synchronous — there is no LLM and no re-resolution (the dataset is identical, so the source bake stays valid), so a job + poll would only add latency. Gated on the dashboards-v3 workspace flag (a create flow, like /v3/generate) plus editor on the SOURCE dashboard.

With `target_dataview_id` the copy is created in THAT view's project (the caller needs read on the view and create in the project) and the data-swap job is enqueued to re-point it — `swap_job_id` is the job to poll. Columns that match keep the author's choices. Without it, behaviour is unchanged.

## Path parameters

- `dashboard_id` integer, required

## Query parameters

- `project_id` integer, nullable
- `target_dataview_id` integer, nullable

## Response `201`

Dashboard duplicated; the new dashboard's id

- DuplicateDashboardResponse
  - `id` integer, required: Id of the new (copied) dashboard
  - `swap_job_id` integer, nullable: Data-swap job to poll; set only when target_dataview_id was sent

## 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/5dfd1c296ded?raw)
