---
title: "Estimate canvas generation without starting jobs"
method: GET
path: "/v1/canvases/{canvasId}/generation-estimate"
tags: ["Canvases"]
---

# Estimate canvas generation without starting jobs

`GET /v1/canvases/{canvasId}/generation-estimate`

## Request

- Base URL: `https://api.masko.ai`
- URL: `https://api.masko.ai/v1/canvases/{canvasId}/generation-estimate`
- Auth: HTTP bearer

Read-only cost and work preview. Accepts read or write credentials in the canvas workspace. Always runs a dry run without charging credits, creating jobs or changing the graph. Returns estimated_cost, planned_jobs, plan_id and graph_content_hash. After approval, send identical options and the returned plan identifiers to POST /v1/canvases/{canvasId}/generate-all using a write credential.

## Path parameters

- `canvasId` string, uuid, required

## Query parameters

- `options` string: URL-encoded JSON object with animation_model (standard or premium, default standard), duration (default 5; standard 2–15, premium 4–30), targets, include_stickers, skip_completed, and optional node_ids or edge_ids arrays. Execution controls such as dry_run, approved_plan_id and max_credits are rejected. This endpoint always estimates only.

## Response `200`

Read-only generation plan

- CanvasGenerateAllResponse
  - `data` CanvasGenerateAllData, required
    - `plan_id` string: Stable identity of the exact graph, scope, prompts, and generation options. Return it as approved_plan_id when executing an approved dry-run plan.
    - `graph_content_hash` string: Canvas revision used by this plan. Return it as expected_graph_hash when executing an approved dry-run plan.
    - `dry_run` boolean
    - `can_dispatch` boolean
    - `targets` 'all' | 'images' | 'stickers' | 'animations'
    - `duration` number
    - `include_stickers` boolean
    - `skip_completed` boolean
    - `selection` object
      - `node_ids` string[], nullable, required
      - `edge_ids` string[], nullable, required
    - `jobs` object[], required
      - `job_id` string, uuid, required
      - `edge_id` string
      - `node_id` string
      - `type` 'image' | 'edit' | 'sticker' | 'loop' | 'transition', required
      - `source` string
      - `target` string
      - `item_name` string
      - `cost` number, required
      - `urls` object
      - `poll_url` string: Follow this link to poll the job. On /v1/canvases routes it selects the mascot contract, so the job reports mascot_id.
    - `generated` object[], required
    - `planned_jobs` object[]
    - `planned_job_count` number
    - `planned_nodes` object[]
    - `planned_edges` object[]
    - `planned_stickers` object[]
    - `skipped` number, required
    - `skipped_items` object[], required
      - `kind` 'node' | 'edge', required
      - `id` string, required
      - `reason` string, required
      - `asset_id` string, nullable
      - `asset_status` string
    - `reverse_free` object[], required
      - `kind` 'edge', required
      - `id` string, required
      - `reason` 'reverse_edge_free', required
      - `reverse_of_edge_id` string, nullable, required
    - `already_complete` object[], required
      - `kind` 'node' | 'edge', required
      - `id` string, required
      - `asset_id` string, required
    - `estimated_cost` number, required
    - `actual_cost` number, required
    - `would_charge_credits` number
    - `refunded_credits` number
    - `total_jobs` number, required
    - `total_cost` number, required

## Other responses

- `400`: Invalid options or canvas selection
- `401`: Authentication required
- `403`: Credential is not allowed to use the public API
- `404`: Canvas or mascot not found in the credential workspace
- `409`: Canvas has no mascot generation context

---

[API](https://skmtc.dev/masko/apis/masko-api.md) · [All operations](https://skmtc.dev/masko/apis/masko-api/llms.txt) · [OpenAPI document](https://skmtc.dev/masko/apis/masko-api/revisions/91eb3006a92f?raw)
