---
title: "Layerize Assets"
method: POST
path: "/media/layerize-assets"
tags: ["media"]
---

# Layerize Assets

`POST /media/layerize-assets`

## Request

- Base URL: `https://api.moda.app/v1`
- URL: `https://api.moda.app/v1/media/layerize-assets`
- Auth: HTTP bearer

Turn an image into downloadable full-size PNG layers and linked text metadata.

Returns a task immediately; poll its links.self or supply callback_url for
a signed terminal webhook. Requires media:generate; polling uses tasks:read.
No canvas-write/export scope or rollout flag is required. Billing uses the
normal Layerize credit precheck and usage. Some effects may be delivered as
composite layers with explicit partial-result warnings. PNG/JPEG/WebP only;
EXIF orientation is normalized before reconstruction.

## Headers

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

## Request body

- LayerizeAssetsRequest
  - `image` string, required: Accessible file_ upload reference or HTTP(S) raster image URL.
  - `mode` 'full' | 'text': Full reconstruction, or text separation over the remaining artwork.
  - `idempotency_key` string, nullable
  - `callback_url` string, nullable

## Response `202`

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' | 'layerize_assets', 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.
  - `attempts_started` integer, required: Number of attempts STARTED (claimed by a worker) — never attempts completed. ``0`` means the task has never been claimed. The claim itself increments the counter, so a task on its first attempt reports ``1`` while RUNNING and stays at ``1`` through that attempt's retry backoff. The retry signal is therefore ``status == "queued" && attempts_started >= 1`` (a queued task that has already burned an attempt), NOT ``>= 2``. Unlike ``attempt``, this is the raw counter and is not floored to 1.
  - `first_started_at` string, nullable: ISO 8601 timestamp of when the FIRST attempt was claimed. ``null`` means unknown — either the task has never started, or it predates this field being recorded. ``started_at`` remains the CURRENT attempt's start, so on a retried task the two differ and the gap is the real wall-clock age of the work.
  - `input` object, nullable: Sanitized echo of the original request.
  - `result` union: Result payload. Present only for succeeded tasks.
    - 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 named after the pages (``01-Cover@2x.png``, ``02-Page-2@2x.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.
    - PublicLayerizeAssetsResult
      - `schema_version` '1'
      - `mode` 'full' | 'text', required
      - `outcome` 'complete' | 'partial', required
      - `width` integer, required
      - `height` integer, required
      - `coordinate_system` 'pixels_top_left'
      - `layers` PublicLayerizeAssetLayer[], required
        - `id` string, required
        - `kind` 'background' | 'image' | 'shape' | 'text' | 'composite', required
        - `z_index` integer, required
        - `file_id` string, required
        - `content_type` 'image/png'
        - `width` integer, required
        - `height` integer, required
        - `x` 0
        - `y` 0
        - `text` LayerizeText
          - `content` string, required
          - `bounds` object, required
          - `transform` unknown[], required
            - unknown
          - `layout_width` number, required
          - `layout_height` number, required
          - `vertical_align` string, nullable
          - `paragraphs` LayerizeAssetTextParagraph[], required
            - `alignment` string, nullable
            - `line_height` number, nullable
            - `spans` LayerizeAssetTextSpan[]
              - …
        - `text_items` LayerizeText[]
          - `content` string, required
          - `bounds` object, required
          - `transform` unknown[], required
            - unknown
          - `layout_width` number, required
          - `layout_height` number, required
          - `vertical_align` string, nullable
          - `paragraphs` LayerizeAssetTextParagraph[], required
            - `alignment` string, nullable
            - `line_height` number, nullable
            - `spans` LayerizeAssetTextSpan[]
              - …
        - `url` string, required
      - `warnings` LayerizeWarning[]
        - `code` string, required
        - `message` string, required
        - `layer_ids` string[]
  - `error` object, nullable: Error info: ``{message, retryable, attempt}``. Present for failed tasks, and also for a NON-terminal task that carries an error from an earlier attempt — on a non-terminal task this always describes the PREVIOUS, already-dead attempt, never the one currently in flight. ``attempt`` is the ``attempts_started`` value the error is tied to (``0`` when the failure happened before any claim).
  - `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: Reserved for a future event-stream URL; currently always ``null``. Moda does not expose a task event stream — poll ``GET /v1/tasks/{id}`` using ``retry_after_ms`` instead.
    - `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.
- `402`: Insufficient credits for a metered operation.
- `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.

## Changes

- **2026-11-03** `9ac6a3abc0f8`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/moda/apis/moda-public-api/changes/media/layerize-assets/post.md)

---

[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.dev/moda/apis/moda-public-api/revisions/9ac6a3abc0f8?raw)
