---
title: "Remix Canvas"
method: POST
path: "/remix"
tags: ["remix"]
---

# Remix Canvas

`POST /remix`

Duplicate a canvas and optionally apply edits with AI.

Always returns a ``Task(kind="remix")`` envelope — uniform across the
prompted and promptless paths. The promptless path completes
synchronously and returns ``status="succeeded"`` inline, so the returned
``id`` is a synthetic (non-queryable) UUID and ``retry_after_ms`` is
``None``. The prompted path returns the in-flight task envelope; callers
poll ``GET /v1/tasks/{id}`` to observe completion.

## Headers

- `Moda-Version` '2026-04-12' | '2026-05-01'

## Request body

- RemixRequest
  - `canvas_id` string, required — Prefixed ``cvs_`` ID of the source canvas to duplicate. The source canvas may belong to a different team. The copy is created in the team specified by team_id.
  - `prompt` string, nullable — Optional natural-language edit prompt to apply to the copy. If omitted, the canvas is duplicated without modifications.
  - `new_name` string, nullable — Name for the new canvas. Defaults to the source canvas name.
  - `brand_kit_id` string, nullable — Prefixed ``bk_`` wire ID (Crockford base32 body) — the canonical, recommended form. For back-compat, **a bare UUID string is also accepted** in both path parameters and JSON request bodies (older integrations that stored raw UUIDs keep working). Both are permanent, supported inputs.
  - `skip_brand_kit` boolean — If true, no brand kit is applied — every brand-kit source is suppressed, including the canvas's own kit, the team default, and any explicit ``brand_kit_id`` override. Use only when the design must be unbranded; to merely leave the source canvas's kit alone, omit ``brand_kit_id`` instead.

## Response `200`

Successful Response

- Task — Canonical wire-format for every async design operation. All consumers -- REST, webhooks, SSE, MCP -- serialize through ``Task.from_db()`` so the shape is always consistent.
  - `id` string, required — Prefixed ``task_...`` identifier.
  - `kind` 'design' | 'export' | 'remix' | 'brand_kit_extract', required — Discriminator for the kind-specific ``result`` payload.
  - `status` 'queued' | 'running' | 'succeeded' | 'failed' | 'canceled' | 'expired', required — Frozen public status taxonomy. DB enum values are mapped at the API boundary -- never exposed directly.
  - `created_at` string, nullable — ISO 8601 timestamp.
  - `started_at` string, nullable — ISO 8601 timestamp.
  - `completed_at` string, nullable — ISO 8601 timestamp.
  - `progress` TaskProgress — Live progress indicator for a running task.
    - `percent` integer, nullable — Estimated completion percentage (0-100).
    - `step` string, nullable — Machine-readable step name the agent is executing.
    - `message` string, nullable — Human-readable progress message.
  - `attempt` integer, required — Current attempt number (1-based).
  - `max_attempts` integer, required — Maximum attempts before dead-lettering.
  - `input` object, nullable — Sanitized echo of the original request.
  - `result` TaskResult — Result payload of a design or remix task. Populated when ``status`` is ``succeeded``, and partially populated for some in-flight tasks (a remix surfaces its source canvas before the design task finishes). Extra keys are permitted so synchronous-completion payloads pass through without schema churn.
    - `canvas_id` string, nullable — Prefixed ``cvs_...`` id of the resulting canvas.
    - `canvas_url` string, nullable — URL to open the canvas in the Moda editor.
    - `canvas_name` string, nullable — Display name of the resulting canvas.
    - `conversation_id` string, nullable — Prefixed ``conv_...`` id — pass to a later task to keep iterating with full context.
    - `source_canvas_id` string, nullable — Prefixed ``cvs_...`` id of the source canvas, for template-remix tasks.
    - `source_canvas_url` string, nullable — Editor URL of the source canvas, for template-remix tasks.
    - `theme_canvas_id` string, nullable — Prefixed ``cvs_...`` id of the theme canvas attached to the resulting canvas, when a brand kit default theme was applied. Null when the deck is unthemed.
    - `export` TaskExport — Rendered export of a finished design task. Present on ``result.export`` once a programmatic (MCP / API) design task completes — the design is auto-exported in the canvas's category-default format and cached. Read this artifact directly instead of issuing a separate ``POST /v1/canvases/{id}/export`` for the same canvas.
      - `url` string, required — Signed, time-limited URL to download the rendered file.
      - `format` string, required — Delivered format — ``png``, ``jpeg``, ``pdf``, ``pptx``, or ``zip``. Multi-page PNG/JPEG exports are bundled into a ``.zip`` of per-page files (``page-1.png``, ``page-2.png``, …) since a single image container can't carry multiple pages.
      - `status` string, required — Render status; ``completed`` when the file is ready at ``url``.
      - `page_count` integer, required — Number of pages in the exported file.
  - `error` object, nullable — Error info for failed tasks: ``{message, retryable}``.
  - `credits` CreditUsage
    - `credits_used` integer, nullable — Number of credits consumed by this operation. Null if billing is not enabled or the job hasn't completed yet.
    - `credits_remaining` integer, nullable — Credit balance after this operation. Null if billing is not enabled.
  - `links` TaskLinks, required — HATEOAS-style links for navigating from a Task resource.
    - `self` string, required — Canonical URL of this task resource.
    - `events` string, nullable — SSE stream URL for real-time task events.
    - `cancel` string, nullable — URL to POST a cancellation request.
    - `canvas` string, nullable — URL to open the canvas in the Moda editor.
  - `retry_after_ms` integer, nullable — Suggested milliseconds to wait before the next poll. Null for terminal tasks.

## Other responses

- `401` — Authentication required.
- `403` — Permission denied for this scope.
- `404` — Resource not found.
- `409` — Conflict (idempotency / resource state).
- `422` — Request validation failed.
- `429` — Rate limit exceeded.
- `500` — Internal error.

---

[API](https://skmtc.dev/moda/apis/moda-public-api.md) · [All operations](https://skmtc.dev/moda/apis/moda-public-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/moda/moda-public-api/revisions/b34cb4cca59e/schema)
