Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.moda.app/llms.txt

Use this file to discover all available pages before exploring further.

POST /v1/tasks (REST) and the start_design_task MCP tool are the single entry point for every Moda design workflow. The same call covers four different patterns depending on which source-canvas field you set.

Which recipe do I want?

GoalField to setWhat happens
Generate a brand-new design from a prompt(neither)A new canvas is created in your team and the agent designs into it.
Edit an existing canvas you owncanvas_idThe agent modifies that canvas in place.
Fill in a template with your contenttemplate_canvas_idA copy of the template is created; the agent edits the copy. The original is untouched.
Rebrand a template for a different brandtemplate_canvas_id + a different brand_kit_id + a prompt that explicitly asks for a visual rebrand (e.g. "Rebrand the colors, fonts, logo, and imagery to the selected brand kit.")A copy is created, the new brand kit is applied, and the agent rebrands colors, fonts, logo, and imagery on the copy.
canvas_id and template_canvas_id are mutually exclusive. conversation_id is mutually exclusive with template_canvas_id (a template remix always starts a fresh conversation on the new copy). Setting incompatible fields returns 422 Unprocessable Entity. Every recipe returns a Task envelope for polling, with a prefixed task_ ID and HATEOAS links for the running task and the resulting canvas.
Pin the API version on every request so the response shape stays stable. All examples below use Moda-Version: 2026-05-01. See Versioning for the supported list and sunset schedule.

1. Create a new design

Pass a prompt, a format, and optionally a canvas_name. Moda creates a fresh canvas and the agent designs into it.
REST vs MCP format arguments. The REST API takes a nested format object (e.g. format: { "category": "slides" }). The MCP tool flattens the same fields into top-level arguments — format_category, format_width, format_height, carousel_dimensions, carousel_page_count — and assembles them into the same format object before calling the REST handler. Use whichever shape matches the surface you’re calling.
curl -X POST https://api.moda.app/v1/tasks \
  -H "Authorization: Bearer $MODA_API_KEY" \
  -H "Moda-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Sales deck for Q4 2026 — six slides, focus on enterprise growth",
    "canvas_name": "Acme Q4 sales deck",
    "format": { "category": "slides" }
  }'
When to use: the design doesn’t exist yet — you want Moda to compose layout, copy, and visuals from scratch. Pair with brand_kit_id (or rely on your team’s default) to ground the output in your brand. format is required when creating a new canvas. It is ignored when canvas_id or template_canvas_id is set — the existing canvas’s dimensions win.

2. Edit an existing canvas

Pass canvas_id and the agent modifies that canvas in place. Use this when you want to iterate on a design you already have — fix typos, swap data, change a section — without forking it.
curl -X POST https://api.moda.app/v1/tasks \
  -H "Authorization: Bearer $MODA_API_KEY" \
  -H "Moda-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Replace the Q3 numbers on the metrics page with: ARR 12M, NRR 118%, customers 340",
    "canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV"
  }'
When to use: you have a canvas already in the loop (a live document, an ongoing collaboration) and you want changes applied to that canvas rather than a copy.
Edit-in-place mutates the source. If you want to keep the original untouched, use template_canvas_id instead (see recipes 3 and 4).

3. Fill in a template

Pass the source canvas as template_canvas_id. Moda copies the canvas into your team and the agent edits the copy — the original stays clean. The source does not have to be flagged as a template (template_type='template'); any canvas you can read from your team works. Pick a brand_kit_id that matches the source canvas’s brand kit. Skill selection is a direct comparison between the source’s brand kit and the request’s brand_kit_id — if they match, you get the content-only remix (preserve design, update content). If they differ, you get the full rebrand instead. Omitting brand_kit_id falls back to your team’s default, which only behaves the same as recipe 3 when the team default is the source’s brand kit; otherwise you’ll land in recipe 4 behavior. See Automatic mode selection for the full matrix.
curl -X POST https://api.moda.app/v1/tasks \
  -H "Authorization: Bearer $MODA_API_KEY" \
  -H "Moda-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Fill out this template to announce our auto-reimbursement feature",
    "template_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
    "brand_kit_id": "bk_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
    "canvas_name": "Acme — auto-reimbursement announcement"
  }'
Behind the scenes: because the requested brand kit matches the source’s brand kit, Moda runs the content-only remix skill — it preserves layout, colors, fonts, and imagery, and updates only copy and data to match your prompt. Callers don’t have to ask for this mode — it’s selected automatically from the brand-kit comparison (see Automatic mode selection below).

4. Rebrand a template for a different brand

The same call shape as recipe 3, but pass a different brand_kit_id than the one the source canvas was built for. This is the agency / multi-client pattern: take one well-designed template and produce variants across different brand identities.
You must tell the agent to rebrand in the prompt. Setting a different brand_kit_id selects the rebrand skill on the backend, but the agent only changes what your prompt asks it to. If your prompt only describes the new content (e.g. “announce v3 of TPS reports”), the agent will update copy and leave the existing colors, fonts, logo, and imagery in place. Lead the prompt with an explicit instruction like “Rebrand the colors, fonts, logo, and imagery to the selected brand kit.” and then add what the design should say. The example below is the recommended shape.
curl -X POST https://api.moda.app/v1/tasks \
  -H "Authorization: Bearer $MODA_API_KEY" \
  -H "Moda-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Rebrand the colors, fonts, logo, and imagery to the selected brand kit. Adapt the copy for Initech, announcing v3 of TPS reports.",
    "template_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
    "brand_kit_id": "bk_01J0NEWBRANDXYZ0123456789",
    "canvas_name": "Initech — TPS v3 launch"
  }'
Behind the scenes: because the requested brand kit differs from the source’s, Moda runs the full rebrand skill — colors, fonts, logos, hero images, and copy all adapt to the new brand, while the structural layout is preserved.

Automatic mode selection

You never tell the API which “skill” to use. For any task with template_canvas_id, the backend resolves an effective brand kit for the request and compares it against the source canvas’s brand kit. The effective brand kit is resolved in this order:
  1. skip_brand_kit: true → no brand kit, skip the default.
  2. Explicit brand_kit_id on the request.
  3. Team’s default brand kit (if one is set).
  4. None.
Then:
Source canvas’s brand kitEffective request brand kitSkill that runs
bk_acmebk_acmeContent-only remix
bk_acmebk_initech (any kit different from source)Full rebrand
bk_acmenone (e.g. skip_brand_kit: true or no team default and brand_kit_id omitted)Full rebrand
The same /v1/tasks call covers all of these. Switch brands by switching brand_kit_id.
Be explicit if you want recipe 3 behavior. Omitting brand_kit_id resolves to your team’s default — not the source canvas’s brand kit. If those two are different, you’ll get the full rebrand skill even when you only meant to update copy. To guarantee content-only remix, pass the source canvas’s own brand_kit_id explicitly.
The skill controls what the agent is allowed to change. Your prompt still controls what the agent actually changes. For the full-rebrand skill, that means you have to ask the agent to update colors, fonts, logo, and imagery — see the warning under recipe 4. For the content-only skill, the agent never touches those dimensions regardless of how the prompt is phrased.

Response shape

Every recipe returns a Task envelope. For template-based recipes (3 and 4), the envelope also carries the source canvas on both input and result so pollers can correlate the new canvas with its source without an extra fetch:
{
  "id": "task_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
  "kind": "design",
  "status": "succeeded",
  "input": {
    "prompt": "Fill out this template to announce our auto-reimbursement feature",
    "source_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV"
  },
  "result": {
    "canvas_id": "cvs_01J0NEWCANVASCREATEDABCDE",
    "canvas_url": "https://app.moda.com/canvas/01J0NEWCANVASCREATEDABCDE",
    "conversation_id": "conv_01J0NEWCONVERSATIONFGHIJK",
    "source_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
    "source_canvas_url": "https://app.moda.com/canvas/01HT9WK8N3M2J4A5Z6P7Q8R9TV"
  },
  "links": {
    "self": "/v1/tasks/task_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
    "events": null,
    "cancel": null,
    "canvas": "https://app.moda.com/canvas/01J0NEWCANVASCREATEDABCDE"
  },
  "retry_after_ms": null
}
The input block is a normalized echo of the request, not a verbatim copy: template_canvas_id is rewritten to source_canvas_id so the same field name carries the source on both the input and the result side. For recipes 1 and 2, source_canvas_id and source_canvas_url are absent from both blocks.

Common options

These apply to every recipe:
FieldEffect
promptRequired. Natural-language instruction for the agent.
brand_kit_idApply a specific brand kit. Omit to use your team’s default. Must belong to your team. When template_canvas_id is set, the resolved kit is also what drives skill selection — see Automatic mode selection.
skip_brand_kittrue to skip brand-kit application entirely (even the team default). Overrides brand_kit_id when both are set.
idempotency_keyReplay-safe identifier. A retry with the same key returns the original task without creating a duplicate canvas.
callback_urlHTTPS URL to receive a signed webhook when the task terminates. See Webhooks for signature verification.
attachmentsReference images or files. Use either inline URLs or file_ids from POST /v1/uploads.
reference_canvas_idsCanvas IDs to show the agent as inspiration. Read-only — they are not modified.
formatOutput format. Required for recipe 1 (new canvas); ignored when canvas_id or template_canvas_id is set.
model_tierpro, standard, or lite. Omit for automatic selection.
number_of_slidesOptional cap for slide-generation tasks. Omit to use the 8-slide default, clamped to your plan limit.
conversation_idResume an existing conversation. Mutually exclusive with template_canvas_id — a template remix always starts a fresh conversation on the new copy.

Polling and webhooks

Every recipe returns a Task envelope with a prefixed id (e.g. task_01HT9WK8N3M2J4A5Z6P7Q8R9TV). Poll GET /v1/tasks/{id} until status reaches a terminal value (succeeded, failed, canceled, or expired). The envelope’s retry_after_ms is a suggested poll interval. If you’d rather not poll, set callback_url on the request and Moda fires a signed task.succeeded / task.failed / task.canceled webhook when the task terminates. See Webhooks for envelope shape, signature verification, and retry behavior.

See also