{"openapi":"3.0.3","info":{"title":"Masko API","version":"1.6.0","description":"API for generating and managing AI mascots, animations, and logos. Every response follows the {data, meta?} / {error: {code, message}} envelope. Async writes return 202 with data.job_id + data.poll_url."},"servers":[{"url":"https://api.masko.ai","description":"Production"},{"url":"http://localhost:3000/api","description":"Local development"}],"security":[{"BearerAuth":[]}],"tags":[{"name":"Items","description":"An item is a single pose or state of your mascot (e.g. \"waving\", \"sitting\"). Each item groups the assets generated for that pose: the image, its transparent variant, and any animations derived from it. Use these endpoints to list, rename, or archive poses. For raw file access (individual PNG/MP4/WebM), see Assets."},{"name":"Assets","description":"An asset is a single file: one PNG, one MP4, one WebM. Assets belong to an item (their pose) and a collection (their mascot). Use these endpoints when you need raw file metadata, signed URLs, or want to archive a specific file variant."}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key: Bearer masko_<key>"}},"schemas":{"ProjectListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"organization_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","organization_id","created_at","updated_at"]},"Meta":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/Pagination"}}},"Pagination":{"type":"object","properties":{"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0,"exclusiveMinimum":true},"offset":{"type":"integer","minimum":0},"has_more":{"type":"boolean"}},"required":["total","limit","offset","has_more"]},"ProjectResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}},"required":["data"]},"CreateProjectBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Project display name. 1 to 255 characters."}},"required":["name"]},"CollectionListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"Collection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string"},"project_id":{"type":"string","format":"uuid"},"config":{"type":"object","properties":{"prompt":{"type":"string"},"reference_asset_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"style_card":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"caution_list":{"type":"array","items":{"type":"string"}}},"required":["prompt","reference_asset_ids","style_card","caution_list"]},"is_published":{"type":"boolean"},"slug":{"type":"string","nullable":true},"user_prefix":{"type":"string","nullable":true},"cdn_status":{"type":"array","items":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid"},"item_name":{"type":"string","nullable":true},"type":{"type":"string"},"cdn_url":{"type":"string","format":"uri"},"status":{"type":"string"},"file_size":{"type":"number","nullable":true}},"required":["asset_id","item_name","type","cdn_url","status","file_size"]}},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","type","created_at","updated_at"]},"CollectionResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Collection"}},"required":["data"]},"CreateCollectionBody":{"type":"object","properties":{"project_id":{"type":"string","format":"uuid","description":"Project to create the collection in. List projects via GET /v1/projects."},"name":{"type":"string","description":"Display name. Defaults to a generated name if omitted."},"prompt":{"type":"string","description":"Optional - do not set this if your references already show the mascot clearly. The reference images ARE the character. Only use prompt when you cannot provide references (pure text-to-mascot). When references are present, a prompt is auto-extracted from them."},"context":{"type":"string","description":"Extra hints the image alone cannot convey: personality and behavior (\"curious, cautious, never aggressive\"), consistency rules (\"always has a small white star on left ear\"), forbidden variants (\"never show without the hat\"), brand tone. Not a character description - the references cover that."},"type":{"type":"string","default":"mascot","description":"Collection type. Defaults to \"mascot\"."},"style":{"type":"string","description":"Style ID or name. List styles via GET /v1/styles."},"reference_image_urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Recommended entry point. Public image URLs of the mascot - at least one, up to 6. Each is downloaded and stored as an asset. The first reference acts as the canonical look; additional ones widen angle/pose coverage. If you also pass reference_asset_ids, totals combine up to 6."},"reference_asset_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Existing asset IDs (from POST /v1/upload or another collection) to link as references. Assets are not duplicated. Use this when you already uploaded the image via /v1/upload. Max 6 references combined with reference_image_urls."},"settings":{"type":"object","properties":{"cdn_enabled":{"type":"boolean","default":true},"animation_sizes":{"type":"array","items":{"type":"number"}}},"description":"Collection settings. cdn_enabled: whether new assets auto-publish to the CDN. animation_sizes: pixel sizes to auto-generate variants for, e.g. [480, 360]. Recommended values: 720, 480, 360, 240. Full supported range: 32 to 1920."}},"required":["project_id"]},"UpdatedFlagResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UpdatedFlag"}},"required":["data"]},"UpdatedFlag":{"type":"object","properties":{"updated":{"type":"boolean"},"slug":{"type":"string"}},"required":["updated"]},"UpdateCollectionBody":{"type":"object","properties":{"name":{"type":"string","description":"New display name."},"context":{"type":"string","description":"Updated brand or product context."},"slug":{"type":"string","minLength":2,"maxLength":50,"description":"CDN slug for this collection. Used in the public URL path: https://assets.masko.ai/:user_prefix/:slug/... Globally unique across all collections. Normalized server-side: lowercased, non-alphanumeric stripped (hyphens kept), trimmed. After normalization must be 2 to 50 characters. Returns 409 if taken."},"config":{"type":"object","additionalProperties":{"nullable":true},"description":"Raw config object merged into existing config. Advanced use only: prefer dedicated endpoints /references, /settings, /cdn-slug."}}},"ItemListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Item"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"Item":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string"},"prompt":{"type":"string"},"public_slug":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"}},"required":["id","name","type","prompt","public_slug","created_at"]},"ItemResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ItemWithAssets"}},"required":["data"]},"ItemWithAssets":{"allOf":[{"$ref":"#/components/schemas/Item"},{"type":"object","properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}}},"required":["assets"]}]},"Asset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["image","transparent_image","sticker_image","video","webm","hevc","stacked_video","scene","logo"]},"status":{"type":"string"},"metadata":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"item_id":{"type":"string","nullable":true,"format":"uuid"},"collection_id":{"type":"string","nullable":true,"format":"uuid"},"file_url":{"type":"string","nullable":true,"format":"uri"},"cdn_url":{"type":"string","nullable":true,"format":"uri"},"is_archived":{"type":"boolean"},"archived_at":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","type","status","item_id","file_url","cdn_url","created_at"]},"UpdateItemBody":{"type":"object","properties":{"name":{"type":"string","minLength":1},"prompt":{"type":"string"}}},"AssetListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"CdnExportResponse":{"type":"object","properties":{"collection":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CdnExportItem"}}},"required":["collection","items"]},"CdnExportItem":{"type":"object","properties":{"name":{"type":"string"},"image":{"type":"string","format":"uri"},"transparent_image":{"type":"string","format":"uri"},"animations":{"type":"array","items":{"$ref":"#/components/schemas/CdnExportAnimation"}},"logos":{"type":"object","additionalProperties":{"type":"string"}}},"required":["name"]},"CdnExportAnimation":{"type":"object","additionalProperties":{"type":"string"}},"AssetResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Asset"}},"required":["data"]},"StickerGenerateResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/StickerGenerateData"}},"required":["data"]},"StickerGenerateData":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["completed"]},"source_asset_id":{"type":"string","format":"uuid"},"asset_ids":{"type":"object","properties":{"sticker_image":{"type":"string","format":"uuid"}},"required":["sticker_image"]},"estimated_cost":{"type":"number"},"sticker_image":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["sticker_image"]},"status":{"type":"string","enum":["completed"]},"file_url":{"type":"string","format":"uri"},"width":{"type":"integer","nullable":true,"minimum":0,"exclusiveMinimum":true},"height":{"type":"integer","nullable":true,"minimum":0,"exclusiveMinimum":true}},"required":["id","type","status","file_url"]}},"required":["job_id","status","source_asset_id","asset_ids","estimated_cost","sticker_image"]},"ReferenceResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ReferenceData"}},"required":["data"]},"ReferenceData":{"type":"object","properties":{"reference_asset_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["reference_asset_ids"]},"AddReferenceBody":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid","description":"Asset ID of an existing uploaded or generated image."},"url":{"type":"string","format":"uri","description":"Public image URL. Downloaded and stored in the collection."}}},"GenerateAsyncResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GenerateAsyncData"}},"required":["data"]},"GenerateAsyncData":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"type":{"type":"string","enum":["image","animation","edit","logo","reverse"]},"item_id":{"type":"string","format":"uuid"},"item_name":{"type":"string"},"estimated_cost":{"type":"number"},"asset_ids":{"type":"object","additionalProperties":{"type":"string","format":"uuid"}},"urls":{"type":"object","additionalProperties":{"type":"string","format":"uri"}},"poll_url":{"type":"string"}},"required":["job_id","status","type","item_id","item_name","estimated_cost","poll_url"]},"JsonResponse":{"type":"object","properties":{},"additionalProperties":{"nullable":true}},"GenerateBody":{"oneOf":[{"$ref":"#/components/schemas/GenerateImageBody"},{"$ref":"#/components/schemas/GenerateAnimationBody"},{"$ref":"#/components/schemas/GenerateEditBody"},{"$ref":"#/components/schemas/GenerateLogoBody"},{"$ref":"#/components/schemas/GenerateSceneBody"}],"discriminator":{"propertyName":"type","mapping":{"image":"#/components/schemas/GenerateImageBody","animation":"#/components/schemas/GenerateAnimationBody","edit":"#/components/schemas/GenerateEditBody","logo":"#/components/schemas/GenerateLogoBody","scene":"#/components/schemas/GenerateSceneBody"}}},"GenerateImageBody":{"type":"object","properties":{"name":{"type":"string","description":"Name for the new item. Required when creating a new item. Omit when passing item_id."},"item_id":{"type":"string","format":"uuid","description":"Existing item ID in this collection. Pass this to add a new asset to an existing item, or to animate/edit its current image. For animations and edits, prefer item_id over source_image_asset_id: the MCP server and CLI auto-resolve the source image from the item."},"type":{"type":"string","enum":["image"]},"image_prompt":{"type":"string","description":"What the character is doing in the image, e.g. \"waving hello with a big smile\"."}},"required":["type"],"description":"Generate a static image (pose). Cost: 1 credit."},"GenerateAnimationBody":{"type":"object","properties":{"name":{"type":"string","description":"Name for the new item. Required when creating a new item. Omit when passing item_id."},"item_id":{"type":"string","format":"uuid","description":"Existing item ID in this collection. Pass this to add a new asset to an existing item, or to animate/edit its current image. For animations and edits, prefer item_id over source_image_asset_id: the MCP server and CLI auto-resolve the source image from the item."},"type":{"type":"string","enum":["animation"]},"animation_prompt":{"type":"string","description":"How the character moves, e.g. \"bouncing up and down energetically\". You can generate an animation directly from just this: when neither item_id nor source_image_asset_id is passed, the system generates a source image first (adds 1 credit), then animates it."},"image_prompt":{"type":"string","description":"Used only when no source image exists. The character description that gets passed to image generation before animation starts."},"source_image_asset_id":{"type":"string","format":"uuid","description":"Asset ID of the image to animate. Use `data.asset_ids.image` from a previous /generate response. Prefer `item_id` when possible — the system resolves the canonical source automatically."},"end_image_asset_id":{"type":"string","format":"uuid","description":"Asset ID of the target image for a transition. Use `data.asset_ids.image` from a previous /generate response. When provided with `source_image_asset_id`, creates a transition from source to end. Forces loop to false."},"duration":{"type":"number","minimum":3,"maximum":10,"description":"Animation duration in seconds. 3 to 10. Defaults to 4. Cost is 5 credits per second."},"loop":{"type":"boolean","description":"Whether the animation loops seamlessly. Defaults to true. Automatically set to false when end_image_asset_id is provided."},"reverse":{"type":"boolean","description":"Reverse an existing video. Used with reverse_of_video_asset_id. Costs 0 credits."},"reverse_of_video_asset_id":{"type":"string","format":"uuid","description":"Asset ID of the forward video to reverse. Required when reverse is true."},"auto_reverse":{"type":"boolean","description":"Transitions only: also generate the reverse transition (end to source) at 0 extra credits. Requires source_image_asset_id + end_image_asset_id. Response includes a reverse_job field."},"reverse_name":{"type":"string","description":"Name for the auto-generated reverse item. Defaults to \"<item name> (Reverse)\"."},"sizes":{"type":"array","items":{"type":"integer","minimum":64,"maximum":1080},"description":"Requested animation size variants in pixels, e.g. [480, 360]. Filtered against the collection settings. No extra credit cost."}},"required":["type"],"description":"Generate an animated video of the mascot. Cost: 5 credits per second (+1 if a source image has to be generated)."},"GenerateEditBody":{"type":"object","properties":{"name":{"type":"string","description":"Name for the new item. Required when creating a new item. Omit when passing item_id."},"item_id":{"type":"string","format":"uuid","description":"Existing item ID in this collection. Pass this to add a new asset to an existing item, or to animate/edit its current image. For animations and edits, prefer item_id over source_image_asset_id: the MCP server and CLI auto-resolve the source image from the item."},"type":{"type":"string","enum":["edit"]},"edit_instructions":{"type":"string","description":"What to change on the source asset, e.g. \"add a santa hat\". Required."},"source_image_asset_id":{"type":"string","format":"uuid","description":"Asset ID of the image to edit. Use `data.asset_ids.image` from a previous /generate response. If you pass `item_id`, the source is resolved from the item automatically."},"source_video_asset_id":{"type":"string","format":"uuid","description":"Asset ID of the video to edit. For video edits with new instructions."}},"required":["type","edit_instructions"],"description":"Edit an existing image or video with natural-language instructions. Cost: 1 credit for images, 5 credits per second for videos."},"GenerateLogoBody":{"type":"object","properties":{"name":{"type":"string","description":"Name for the new item. Required when creating a new item. Omit when passing item_id."},"item_id":{"type":"string","format":"uuid","description":"Existing item ID in this collection. Pass this to add a new asset to an existing item, or to animate/edit its current image. For animations and edits, prefer item_id over source_image_asset_id: the MCP server and CLI auto-resolve the source image from the item."},"type":{"type":"string","enum":["logo"]},"logo_description":{"type":"string","description":"What the logo should look like, e.g. \"iconic face-only, circular badge\". Defaults to \"Iconic representation of the character\"."},"logo_style_name":{"type":"string","description":"Short label for the logo style, e.g. \"Flat\", \"Retro\". Defaults to \"Flat\"."},"logo_style_instruction":{"type":"string","description":"Detailed style instructions, e.g. \"Flat design with solid colors, no gradients\"."}},"required":["type"],"description":"Generate an iconic/logo version of the mascot. Cost: 5 credits."},"GenerateSceneBody":{"type":"object","properties":{"name":{"type":"string","description":"Name for the new item. Required when creating a new item. Omit when passing item_id."},"item_id":{"type":"string","format":"uuid","description":"Existing item ID in this collection. Pass this to add a new asset to an existing item, or to animate/edit its current image. For animations and edits, prefer item_id over source_image_asset_id: the MCP server and CLI auto-resolve the source image from the item."},"type":{"type":"string","enum":["scene"]},"scene":{"type":"string","description":"The environment, e.g. \"cozy reading nook with afternoon light\". Required unless editing (source_image_asset_id + edit_instructions)."},"action":{"type":"string","description":"What the mascot is doing in the scene, e.g. \"reading a book\". Required unless editing."},"aspect_ratio":{"type":"string","enum":["4:3","1:1","21:9","4:5","3:4","9:16"],"description":"Output aspect ratio. Use 4:3 for marketplace_card or marketplace_story, 1:1 for marketplace_square, 21:9 for hero_desktop, and 4:5 or 3:4 for hero_mobile."},"position":{"type":"string","enum":["left","center","right"],"description":"Where the mascot sits in the frame. Defaults: right for 21:9, center for others."},"source_image_asset_id":{"type":"string","format":"uuid","description":"For scene edits: existing scene asset to edit. Must be paired with edit_instructions."},"edit_instructions":{"type":"string","description":"For scene edits: what to change, e.g. \"warm up the lighting\". Paired with source_image_asset_id."}},"required":["type"],"description":"Generate a 4K scene image of the mascot in an environment, or edit an existing scene. Cost: 3 credits."},"BatchAsyncResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BatchAsyncData"}},"required":["data"]},"BatchAsyncData":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/GenerateAsyncData"}},"total_cost":{"type":"number"},"poll_url":{"type":"string"}},"required":["jobs","total_cost","poll_url"]},"GenerateBatchBody":{"type":"object","properties":{"requests":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/GenerateImageBody"},{"$ref":"#/components/schemas/GenerateAnimationBody"},{"$ref":"#/components/schemas/GenerateEditBody"},{"$ref":"#/components/schemas/GenerateLogoBody"},{"$ref":"#/components/schemas/GenerateSceneBody"}],"discriminator":{"propertyName":"type","mapping":{"image":"#/components/schemas/GenerateImageBody","animation":"#/components/schemas/GenerateAnimationBody","edit":"#/components/schemas/GenerateEditBody","logo":"#/components/schemas/GenerateLogoBody","scene":"#/components/schemas/GenerateSceneBody"}}},"minItems":1,"maxItems":10,"description":"Up to 10 generate requests run in parallel. Each request follows the same discriminated schema as /generate. Credits are deducted per request."}},"required":["requests"]},"SuggestionsResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SuggestionsData"}},"required":["data"]},"SuggestionsData":{"type":"object","properties":{"suggestions":{"type":"array","items":{"type":"string"}}},"required":["suggestions"]},"SceneSuggestionsResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SceneSuggestionsData"}},"required":["data"]},"SceneSuggestionsData":{"type":"object","properties":{"suggestions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"emoji":{"type":"string"},"scene":{"type":"string"},"action":{"type":"string"},"position":{"type":"string"}},"required":["name","scene","action"]}}},"required":["suggestions"]},"UpdateSettingsBody":{"type":"object","properties":{"publish_params":{"type":"object","properties":{"animation_sizes":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether animation size variants are generated."},"sizes":{"type":"array","items":{"type":"number"},"description":"Pixel sizes to generate. Any integer from 32 to 1920. Common values: 720, 480, 360, 240."}},"required":["enabled","sizes"]}},"required":["animation_sizes"],"description":"Publish parameters. Applies to new animations and retroactively resizes existing ones."}},"required":["publish_params"]},"CanvasListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CanvasListItem"}}},"required":["data"]},"CanvasListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","created_at","updated_at"]},"CanvasResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Canvas"}},"required":["data"]},"Canvas":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"graph":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"object","properties":{"nodes":{"type":"object","properties":{"total":{"type":"number"},"completed":{"type":"number"},"pending":{"type":"number"}},"required":["total","completed","pending"]},"edges":{"type":"object","properties":{"total":{"type":"number"},"completed":{"type":"number"},"pending":{"type":"number"},"failed":{"type":"number"}},"required":["total","completed","pending","failed"]},"ready":{"type":"boolean"},"failed_edges":{"type":"array","items":{"type":"object","properties":{"edge_id":{"type":"string"},"error":{"type":"string"}},"required":["edge_id","error"]}}},"required":["nodes","edges","ready","failed_edges"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","graph"]},"CreateCanvasBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Display name for the canvas."},"graph":{"type":"object","additionalProperties":{"nullable":true},"description":"Canvas graph JSON with nodes, edges, and inputs. Omit to create an empty canvas. Mutually exclusive with template_id."},"template_id":{"type":"string","minLength":1,"description":"Optional template to apply at creation. Creates items, starts image generation for each node, and returns the populated graph plus job IDs. List templates via GET /v1/canvas-templates."},"node_overrides":{"type":"object","additionalProperties":{"nullable":true},"description":"Per-node overrides keyed by node key. Merged into template nodes before creation. Only used when template_id is provided."},"edge_overrides":{"type":"object","additionalProperties":{"nullable":true},"description":"Per-edge overrides keyed by \"source->target\" key. Merged into template edges before creation. Only used when template_id is provided."}},"required":["name"]},"UpdateCanvasBody":{"type":"object","properties":{"graph":{"type":"object","additionalProperties":{"nullable":true},"description":"Full canvas graph to replace the current one. Nodes, edges, and inputs are overwritten."}},"required":["graph"]},"CanvasGraphExtendResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CanvasGraphExtendData"}},"required":["data"]},"CanvasGraphExtendData":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"graph":{"type":"object","additionalProperties":{"nullable":true}},"updated_at":{"type":"string"},"added":{"type":"object","properties":{"nodes":{"type":"number"},"edges":{"type":"number"},"inputs":{"type":"number"}},"required":["nodes","edges","inputs"]},"updated":{"type":"object","properties":{"edges":{"type":"number"}},"required":["edges"]}},"required":["id","name","graph","updated_at","added","updated"]},"ExtendCanvasGraphBody":{"type":"object","properties":{"add_nodes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"default":[],"description":"Nodes to append. Fails if any node ID already exists."},"add_edges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"default":[],"description":"Edges to append. Fails if any edge ID already exists."},"update_edges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1}},"required":["id"],"additionalProperties":{"nullable":true}},"default":[],"description":"Partial edge patches keyed by id. Existing edge fields are preserved unless explicitly overwritten."},"add_inputs":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"],"additionalProperties":{"nullable":true}},"default":[],"description":"Inputs to append. Existing input names are left unchanged."}}},"CanvasEdgePatchResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CanvasEdgePatchData"}},"required":["data"]},"CanvasEdgePatchData":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"edge":{"type":"object","additionalProperties":{"nullable":true}},"graph":{"type":"object","additionalProperties":{"nullable":true}},"updated_at":{"type":"string"}},"required":["id","name","edge","graph","updated_at"]},"PatchCanvasEdgeBody":{"type":"object","properties":{"speed":{"type":"number","minimum":0.1,"maximum":10,"description":"Playback speed multiplier for this edge. Normal transitions use 2, snappy interact transitions use 3-4, calm loops use 1."}}},"CanvasEdgeGenerateResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CanvasEdgeGenerateData"}},"required":["data"]},"CanvasEdgeGenerateData":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"edge_id":{"type":"string"},"type":{"type":"string","enum":["loop","transition"]},"source":{"type":"string"},"target":{"type":"string"},"cost":{"type":"number"},"urls":{"type":"object","additionalProperties":{"type":"string","format":"uri"}},"poll_url":{"type":"string"}},"required":["job_id","edge_id","type","source","target","cost","poll_url"]},"GenerateEdgeBody":{"type":"object","properties":{"duration":{"type":"number","minimum":3,"maximum":10,"default":4,"description":"Animation duration in seconds. 3 to 10. Defaults to 4."}}},"CanvasGenerateAllResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CanvasGenerateAllData"}},"required":["data"]},"CanvasGenerateAllData":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"edge_id":{"type":"string"},"node_id":{"type":"string"},"type":{"type":"string","enum":["image","edit","sticker","loop","transition"]},"source":{"type":"string"},"target":{"type":"string"},"item_name":{"type":"string"},"cost":{"type":"number"},"urls":{"type":"object","additionalProperties":{"type":"string","format":"uri"}}},"required":["job_id","type","cost"]}},"generated":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"skipped":{"type":"number"},"skipped_items":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["node","edge"]},"id":{"type":"string"},"reason":{"type":"string"},"asset_id":{"type":"string","nullable":true},"asset_status":{"type":"string"}},"required":["kind","id","reason"]}},"reverse_free":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["edge"]},"id":{"type":"string"},"reason":{"type":"string","enum":["reverse_edge_free"]},"reverse_of_edge_id":{"type":"string","nullable":true}},"required":["kind","id","reason","reverse_of_edge_id"]}},"already_complete":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["node","edge"]},"id":{"type":"string"},"asset_id":{"type":"string"}},"required":["kind","id","asset_id"]}},"estimated_cost":{"type":"number"},"actual_cost":{"type":"number"},"refunded_credits":{"type":"number"},"total_jobs":{"type":"number"},"total_cost":{"type":"number"}},"required":["jobs","generated","skipped","skipped_items","reverse_free","already_complete","estimated_cost","actual_cost","total_jobs","total_cost"]},"GenerateAllBody":{"type":"object","properties":{"duration":{"type":"number","minimum":1,"maximum":10,"default":4,"description":"Animation duration in seconds, applied to every state loop and transition. Defaults to 4."},"skip_completed":{"type":"boolean","default":true,"description":"Deprecated compatibility flag. Canvas generate-all only dispatches missing work and always skips edges that already have assigned generated assets."},"include_stickers":{"type":"boolean","default":false,"description":"When true, generate sticker_image derivatives for generated image nodes."},"targets":{"type":"string","enum":["all","images","stickers","animations"],"default":"all","description":"Which work to dispatch. \"images\" only generates skeleton node images. \"stickers\" backfills sticker_image derivatives for completed node images. \"animations\" only dispatches edge videos. \"all\" does both images and animations."}}},"ExportConfigResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ExportConfigData"}},"required":["data"]},"ExportConfigData":{"type":"object","additionalProperties":{"nullable":true}},"CanvasTemplateListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CanvasTemplate"}}},"required":["data"]},"CanvasTemplate":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"source":{"type":"string","enum":["builtin","user"]},"public":{"type":"boolean"},"nodes":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"edges":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"inputs":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"created_at":{"type":"string"}},"required":["id","name","description","source"]},"CanvasTemplateResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CanvasTemplate"}},"required":["data"]},"CreateTemplateBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Template name."},"description":{"type":"string","description":"What the template does."},"canvas_id":{"type":"string","format":"uuid","description":"Existing canvas to snapshot. Required together with collection_id. Mutually exclusive with template."},"collection_id":{"type":"string","format":"uuid","description":"Source collection for the snapshot. Required together with canvas_id."},"template":{"type":"object","additionalProperties":{"nullable":true},"description":"Raw template JSON. Provide this OR (canvas_id + collection_id)."},"public":{"type":"boolean","description":"If true, template is visible to all users. Defaults to false."}},"required":["name"]},"UpdateTemplateBody":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"New template name."},"description":{"type":"string","description":"Updated description."},"template":{"type":"object","additionalProperties":{"nullable":true},"description":"Replacement template JSON."},"public":{"type":"boolean","description":"Toggle whether template is visible to all users."}}},"JobListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"Job":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","processing","completed","failed"]},"type":{"type":"string","enum":["item_generation","image_generation","logo","animation","reverse","size_variant","size_variant_batch","export_animation","scene_generation","sticker_generation"]},"collection_id":{"type":"string","nullable":true,"format":"uuid"},"cost_credits":{"type":"number"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"item_id":{"type":"string","nullable":true,"format":"uuid"},"item_name":{"type":"string","nullable":true},"error":{"type":"string","nullable":true},"urls":{"type":"object","additionalProperties":{"type":"string","format":"uri"}}},"required":["id","status","type","collection_id","cost_credits","created_at","updated_at"]},"JobResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Job"}},"required":["data"]},"CreditsResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreditsData"}},"required":["data"]},"CreditsData":{"type":"object","properties":{"subscription":{"type":"number"},"topup":{"type":"number"},"total":{"type":"number"}},"required":["subscription","topup","total"]},"StylesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/StylePreset"}}},"required":["data"]},"StylePreset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"thumbnail_url":{"type":"string","format":"uri"}},"required":["id","name"],"additionalProperties":{"nullable":true}},"UploadResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UploadData"}},"required":["data"]},"UploadData":{"type":"object","properties":{"asset_id":{"type":"string","format":"uuid"}},"required":["asset_id"]},"UploadUrlBody":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Publicly accessible image URL. Downloaded server-side. Max 10MB. Images only (image/png, image/jpeg, image/webp, image/svg+xml, image/gif). SVGs are auto-converted to PNG. For video uploads or binary files, POST the same endpoint as multipart/form-data with a \"file\" field (max 10MB for images, 50MB for videos)."}},"required":["url"]},"PreviewResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PreviewData"}},"required":["data"]},"PreviewData":{"type":"object","properties":{"images":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expires_in":{"type":"number"}},"required":["url","expires_in"]}},"cost":{"type":"number"}},"required":["images","cost"]},"PreviewBody":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"Text description of the mascot to preview. Preview exists for cheap idea iteration: tweak the prompt, regenerate, compare, then create the collection with the winning reference. Costs 1 credit per image generated."},"preset_id":{"type":"string","description":"Optional style preset ID. List presets via GET /v1/styles."},"count":{"type":"number","minimum":1,"maximum":6,"default":1,"description":"Number of preview variants to generate. 1 to 6. Defaults to 1."},"reference_image_urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Optional \"check against\" images. Feed an image you want the mascot to resemble; the preview tries to match it. Useful for \"does this prompt produce something close to my sketch?\" iterations. Not stored - use POST /v1/collections/:id/references for persistent references."}},"required":["prompt"]},"AnalyzeImageResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnalyzeImageData"}},"required":["data"]},"AnalyzeImageData":{"type":"object","properties":{"suggested_name":{"type":"string"},"description":{"type":"string"},"style_hints":{"type":"array","items":{"type":"string"}},"suggested_prompt":{"type":"string"}},"required":["suggested_name","description","style_hints","suggested_prompt"]},"AnalyzeUrlResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnalyzeUrlData"}},"required":["data"]},"AnalyzeUrlData":{"type":"object","properties":{"screenshotPath":{"type":"string"},"markdown":{"type":"string"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"description":{"type":"string"}},"additionalProperties":{"nullable":true}},"AnalyzeBody":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"],"description":"Analyze a mascot/character image."},"image_url":{"type":"string","format":"uri","description":"Public image URL to analyze. Returns a structured description suitable for seeding a collection prompt."}},"required":["type","image_url"]},{"type":"object","properties":{"type":{"type":"string","enum":["url"],"description":"Analyze a brand website."},"url":{"type":"string","format":"uri","description":"Website URL to analyze. Extracts brand colors, product description, and tone."}},"required":["type","url"]}],"description":"What to analyze. Use type=\"image\" with image_url to analyze a mascot picture, or type=\"url\" with url to analyze a brand website."},"WebhookListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["data"]},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"consecutive_failures":{"type":"number"},"created_at":{"type":"string"}},"required":["id","url","events","active","consecutive_failures","created_at"]},"WebhookResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}},"required":["data"]},"CreateWebhookBody":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL that receives webhook POSTs as JSON. Each delivery includes X-Masko-Signature (sha256=<hmac-hex>), X-Masko-Timestamp, and X-Masko-Event headers. Retries 3 times with 1s, 5s, 30s backoff on any non-2xx response. Auto-disables after 100 consecutive failures."},"events":{"type":"array","items":{"type":"string"},"description":"Event types to subscribe to. Omit for all events. Available events: job.completed, job.failed."}},"required":["url"]}},"parameters":{}},"paths":{"/v1/projects":{"get":{"tags":["Projects"],"summary":"List projects","description":"Returns all projects owned by the authenticated user, paginated. Projects are the top-level containers for collections. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"}],"responses":{"200":{"description":"List of projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectListResponse"},"example":{"data":[{"id":"04dae799-dd9a-4296-ba86-9e3913c2f8d1","name":"test","created_at":"2026-04-08T03:30:21.168491+00:00","updated_at":"2026-04-08T03:30:21.168491+00:00","organization_id":"bc5a4520-ee23-46e7-b714-2835bd3a7f80"}],"meta":{"pagination":{"total":2,"limit":5,"offset":0,"has_more":false}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["Projects"],"summary":"Create a project","description":"Creates a new project under the authenticated user. Projects are lightweight containers - create one per product or per workspace. Returns 201 with the new project record. No credit cost.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectBody"}}}},"responses":{"201":{"description":"Created project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections":{"get":{"tags":["Collections"],"summary":"List collections","description":"Returns all collections owned by the authenticated user, paginated. A collection is a single mascot character with its own style, references, and items. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to this project."},"required":false,"description":"Filter to this project.","name":"project_id","in":"query"},{"schema":{"type":"string","description":"Filter by type, e.g. \"mascot\"."},"required":false,"description":"Filter by type, e.g. \"mascot\".","name":"type","in":"query"}],"responses":{"200":{"description":"List of collections","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionListResponse"},"example":{"data":[{"id":"f9503022-a991-46ea-bf8c-d628c921b6b0","name":"v1-api-test-cat-1776591403","type":"mascot","project_id":"04dae799-dd9a-4296-ba86-9e3913c2f8d1","project_name":"test","is_published":true,"public_slug":"v1-api-test-cat-1776591403-rmau1uyd","user_prefix":"fda8417d","created_at":"2026-04-19T09:36:43.46139+00:00"}],"meta":{"pagination":{"total":6,"limit":5,"offset":0,"has_more":true}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["Collections"],"summary":"Create a mascot (collection)","description":"This is the primary way to create a mascot. In the API the resource is called `collection` - today one collection holds one mascot so the terms are interchangeable. Required input is reference images (`reference_image_urls` or `reference_asset_ids` from POST /v1/upload) - one or more images of the character. The references ARE the mascot; you do not need to describe it in `prompt`. Use `context` to add things the image cannot express: personality, consistency rules (\"always wears red sneakers\"), forbidden variants (\"never without the hat\"), brand tone. The collection is assigned to a project and gets a public CDN slug. No credit cost to create, but future /generate calls use the style automatically extracted from these references.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionBody"}}}},"responses":{"201":{"description":"Created collection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"},"example":{"data":{"id":"f9503022-a991-46ea-bf8c-d628c921b6b0","name":"v1-api-test-cat-1776591403","slug":"v1-api-test-cat-1776591403-rmau1uyd","type":"mascot","reference_asset_ids":["e906ebb5-deb1-4010-82f9-f0182a3812e0","5114bec3-b92a-4917-8675-84fce713d3cf"],"settings":{"cdn_enabled":true,"animation_sizes":[]}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}":{"get":{"tags":["Collections"],"summary":"Get collection details","description":"Returns the full collection record including config (prompt, reference_asset_ids, style_card, caution_list) and cdn_status. Returns 404 if the collection does not exist or is not owned by the caller.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Collection details with cdn_status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionResponse"},"example":{"data":{"id":"f9503022-a991-46ea-bf8c-d628c921b6b0","name":"v1-api-test-cat-1776591403","type":"mascot","project_id":"04dae799-dd9a-4296-ba86-9e3913c2f8d1","config":{"prompt":"terracotta clay cat mascot with big eyes and speckled texture","reference_asset_ids":["e906ebb5-deb1-4010-82f9-f0182a3812e0","5114bec3-b92a-4917-8675-84fce713d3cf"],"style_card":null,"caution_list":[]},"is_published":true,"slug":"v1-api-test-cat-1776591403-rmau1uyd","user_prefix":"fda8417d","cdn_status":[],"created_at":"2026-04-19T09:36:43.46139+00:00","updated_at":"2026-04-19T09:36:46.966862+00:00"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"tags":["Collections"],"summary":"Update collection metadata","description":"Updates a collection name, prompt, or public slug. Returns { updated: true }. Returns 404 if not found or not owned by the caller. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionBody"}}}},"responses":{"200":{"description":"Updated collection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatedFlagResponse"},"example":{"data":{"updated":true}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/items":{"get":{"tags":["Items"],"summary":"List items in a collection","description":"Returns paginated items in a collection. An item groups related assets (e.g. \"wave\" item may have an image, a transparent image, and animation variants). Filter by `type` to narrow results. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"},{"schema":{"type":"string"},"required":false,"name":"type","in":"query"}],"responses":{"200":{"description":"List of items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"},"example":{"data":[],"meta":{"pagination":{"total":0,"limit":5,"offset":0,"has_more":false}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/items/{itemId}":{"get":{"tags":["Items"],"summary":"Get item details","description":"Returns the item record with all its generated assets (images, animations, logos). Returns 404 if the item does not exist or is not in the given collection. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"itemId","in":"path"}],"responses":{"200":{"description":"Item details with assets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"tags":["Items"],"summary":"Update item name or prompt","description":"Updates the item name (used to derive the public slug) and/or the prompt. Does not re-generate assets. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"itemId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateItemBody"}}}},"responses":{"200":{"description":"Updated item","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemResponse"},"example":{"data":{"id":"e8ca0d1b-b445-46f6-862f-26b26ac2c6ff","name":"sitting-calmly","prompt":"sitting on ground with closed eyes peacefully","public_slug":"sitting","created_at":"2026-04-19T09:44:26.659167+00:00"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["Items"],"summary":"Archive an item","description":"Soft-deletes (archives) the item and its assets. Files are retained but filtered from reads. Returns 204 on success. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"itemId","in":"path"}],"responses":{"204":{"description":"Archived"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/assets":{"get":{"tags":["Assets"],"summary":"List assets in a collection","description":"Returns paginated assets in a collection (images, videos, transparent variants). Each asset has a signed `file_url` (1-hour expiry) and a `cdn_url` when published. Filter by `type` or `item_id`. Set `include_file_urls=false` for faster metadata-only listings. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"},{"schema":{"type":"string"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"item_id","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"Whether to include signed file_url values. Defaults to true. Set false for faster metadata-only listings."},"required":false,"description":"Whether to include signed file_url values. Defaults to true. Set false for faster metadata-only listings.","name":"include_file_urls","in":"query"}],"responses":{"200":{"description":"List of assets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetListResponse"},"example":{"data":[{"id":"5114bec3-b92a-4917-8675-84fce713d3cf","type":"image","status":"completed","metadata":{},"item_id":null,"file_url":"https://storage.googleapis.com/masco-media/references/.../f4bdfb19.png?GoogleAccessId=...&Expires=...&Signature=...","cdn_url":null,"created_at":"2026-04-19T09:36:46.95543+00:00"}],"meta":{"pagination":{"total":2,"limit":5,"offset":0,"has_more":false}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/cdn-export":{"get":{"tags":["Collections"],"summary":"Export published CDN links","description":"Returns the same clean hosted-link JSON shown in the collection page Get Links export modal. This endpoint is built from published CDN assets, not raw item types, so pose/image items with attached video loops are included. Use the raw items and assets endpoints for IDs, prompts, metadata, and status checks. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Collection CDN export JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdnExportResponse"},"example":{"collection":"Fox Mascot","items":[{"name":"card-sit","image":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit.png","transparent_image":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit-transparent.png","animations":[{"video":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit.mp4","transparent_video_webm":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit.webm","transparent_video_mov":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit.mov","transparent_video_android":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit-android.mp4","transparent_video_android_360":"https://assets.masko.ai/fda8417d/fox-mascot/card-sit-360.mp4"}]}]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"CDN export is not ready","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["cdn_export_not_ready"]},"message":{"type":"string"},"details":{"type":"object","properties":{"collection_id":{"type":"string"},"is_published":{"type":"boolean"},"cdn_asset_count":{"type":"number"}},"required":["collection_id","is_published","cdn_asset_count"]}},"required":["code","message","details"]}},"required":["error"]},"example":{"error":{"code":"cdn_export_not_ready","message":"CDN export is not ready. Enable asset hosting for this collection and publish assets before requesting cdn-export.","details":{"collection_id":"f9503022-a991-46ea-bf8c-d628c921b6b0","is_published":false,"cdn_asset_count":0}}}}}}}}},"/v1/assets":{"get":{"tags":["Assets"],"summary":"List assets across all collections","description":"Returns paginated assets spanning every collection owned by the caller, each annotated with its `collection_id`. Filter by `type`, `status`, or `collection_id`. Set `include_file_urls=false` for faster metadata-only listings. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to a single collection. Omit to list across all of your collections."},"required":false,"description":"Filter to a single collection. Omit to list across all of your collections.","name":"collection_id","in":"query"},{"schema":{"type":"string","description":"Filter by asset type: image, transparent_image, video, webm, hevc, stacked_video, etc."},"required":false,"description":"Filter by asset type: image, transparent_image, video, webm, hevc, stacked_video, etc.","name":"type","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"Include archived assets. Defaults to false (active only)."},"required":false,"description":"Include archived assets. Defaults to false (active only).","name":"is_archived","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to a single item within a collection."},"required":false,"description":"Filter to a single item within a collection.","name":"item_id","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"Whether to include signed file_url values. Defaults to true. Set false for faster metadata-only listings."},"required":false,"description":"Whether to include signed file_url values. Defaults to true. Set false for faster metadata-only listings.","name":"include_file_urls","in":"query"}],"responses":{"200":{"description":"List of assets across your collections","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetListResponse"},"example":{"data":[{"id":"5114bec3-b92a-4917-8675-84fce713d3cf","type":"image","status":"completed","metadata":{},"item_id":null,"collection_id":"f9503022-a991-46ea-bf8c-d628c921b6b0","file_url":"https://storage.googleapis.com/masco-media/...signed-url...","cdn_url":null,"created_at":"2026-04-19T09:36:46.95543+00:00"}],"meta":{"pagination":{"total":215,"limit":3,"offset":0,"has_more":true}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/assets/{id}":{"get":{"tags":["Assets"],"summary":"Get asset details","description":"Returns a single asset record with its signed `file_url` and optional `cdn_url`. Returns 404 if the asset is not owned by the caller. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Asset details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["Assets"],"summary":"Archive an asset","description":"Soft-deletes (archives) a single asset. The underlying file is retained on storage but filtered from reads. Returns 204 on success. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Archived"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/assets/{id}/sticker":{"post":{"tags":["Assets"],"summary":"Generate a sticker from an image asset","description":"Creates a transparent `sticker_image` derivative from a completed image asset. The generated sticker preserves the selected image subject, adds a bold white sticker border, removes the matte background, and costs 1 credit.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"201":{"description":"Sticker generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StickerGenerateResponse"},"example":{"data":{"job_id":"8c458fc7-df42-4e5a-b5cb-8768c4d9f4a1","status":"completed","source_asset_id":"5114bec3-b92a-4917-8675-84fce713d3cf","asset_ids":{"sticker_image":"bafc3f5e-e90c-4cf8-88c2-bb5bcf3c5088"},"estimated_cost":1,"sticker_image":{"id":"bafc3f5e-e90c-4cf8-88c2-bb5bcf3c5088","type":"sticker_image","status":"completed","file_url":"https://storage.googleapis.com/masco-media/...signed-url...","width":1024,"height":1024}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/references":{"post":{"tags":["References"],"summary":"Add a reference image","description":"Adds an asset as a style reference for the collection (up to 6 references). References guide future generations for consistency. Invalidates the cached style_card, which will be re-extracted on next generation. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddReferenceBody"}}}},"responses":{"201":{"description":"Reference added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceResponse"},"example":{"data":{"reference_asset_ids":["e906ebb5-deb1-4010-82f9-f0182a3812e0","5114bec3-b92a-4917-8675-84fce713d3cf","b357dfe9-92ab-4696-beb3-4f36779808f2"]}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/references/{assetId}":{"delete":{"tags":["References"],"summary":"Remove a reference image","description":"Removes an asset from the collection reference list. Returns the updated `reference_asset_ids` array. Invalidates the cached style_card. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"Reference removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferenceResponse"},"example":{"data":{"reference_asset_ids":["e906ebb5-deb1-4010-82f9-f0182a3812e0","5114bec3-b92a-4917-8675-84fce713d3cf"]}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/generate":{"post":{"tags":["Generate"],"summary":"Generate image or animation","description":"Starts an async generation job. Returns 202 with `data.job_id` - poll via GET `/v1/jobs/{id}` (or pass `?wait=true` for long-polling). Cost by type: image=1, animation=5/sec (+1 if no source image), logo=5, edit=1 for images, scene=3, reverse=0. For `type: animation`, you can skip providing a source image: pass only `animation_prompt` (and optionally `image_prompt`) and the system generates a fresh source image first, then animates it. If you have an existing item, pass `item_id` to animate/edit its current image. Scene generation and scene editing also use this endpoint with `type: \"scene\"`. Returns 402 if credits are insufficient.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBody"}}}},"responses":{"202":{"description":"Generation job started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAsyncResponse"},"example":{"data":{"job_id":"b87c9579-7460-4bd0-aa54-77991615dfef","status":"pending","type":"image","item_id":"e328c567-0965-42fc-90b5-7ff6faa61b25","item_name":"wave","estimated_cost":1,"asset_ids":{"image":"a8b158bb-5698-431a-b0f1-98ee30228b11"},"urls":{"transparent_image":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/wave-91a9ac20.png","image":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/wave-a8b158bb.png"},"poll_url":"/api/v1/jobs/b87c9579-7460-4bd0-aa54-77991615dfef"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/generate-batch":{"post":{"tags":["Generate"],"summary":"Batch-generate multiple items","description":"Starts multiple generation jobs in one call (up to the per-request cap). Returns 202 with an array of `data.jobs[]`, each with its own `job_id`. Cost is summed across all items. Returns 402 if credits are insufficient for the whole batch.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateBatchBody"}}}},"responses":{"202":{"description":"Batch generation jobs started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAsyncResponse"},"example":{"data":{"jobs":[{"job_id":"fe21477f-7e46-448f-bfdb-96eac80205b8","item_id":"e8ca0d1b-b445-46f6-862f-26b26ac2c6ff","item_name":"sitting","status":"pending","estimated_cost":1,"asset_ids":{"image":"25dc5edf-bf41-4a7f-ba23-b783ea2718d8"},"urls":{"transparent_image":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/sitting-fb7bbd6f.png","image":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/sitting-25dc5edf.png"}}],"total_cost":2,"poll_url":"/api/v1/jobs"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/suggestions":{"get":{"tags":["Generate"],"summary":"Suggest action poses","description":"Returns AI-generated action/pose suggestions (e.g. \"waving\", \"thinking\") tailored to the collection. Use these as prompts for POST `/v1/collections/{id}/generate`. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Suggested actions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionsResponse"},"example":{"data":{"suggestions":["Curious Head Tilt","Wide Eyed Stare","Slow Clay Blink","Gentle Tail Wag","Heavy Paw Waddle","Playful Pounce","Happy Ear Twitch"]}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/scenes/suggestions":{"get":{"tags":["Generate"],"summary":"Suggest scenes for a collection","description":"Returns AI-generated scene ideas (setting + action + recommended position) tailored to the collection. Use these as payloads for POST `/v1/collections/{id}/generate` with `type: \"scene\"`. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["4:3","1:1","21:9","4:5","3:4","9:16"],"default":"4:5","description":"Aspect ratio to optimize the suggestions for. Defaults to 4:5."},"required":false,"description":"Aspect ratio to optimize the suggestions for. Defaults to 4:5.","name":"aspect_ratio","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":10,"default":6,"description":"Number of scene suggestions to return. Defaults to 6, max 10."},"required":false,"description":"Number of scene suggestions to return. Defaults to 6, max 10.","name":"count","in":"query"}],"responses":{"200":{"description":"AI-suggested scenes for the collection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SceneSuggestionsResponse"},"example":{"data":{"suggestions":[{"name":"Sunlit Terrace","emoji":"☀️","scene":"A sun-drenched Mediterranean stone balcony overlooking a sparkling blue coastline, decorated with potted succulents and blooming bougainvillea in earthen jars.","action":"Sitting contentedly among the flower pots and soaking up the afternoon warmth.","position":"center"}]}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/settings":{"patch":{"tags":["Settings"],"summary":"Update collection settings","description":"Updates collection-level settings such as CDN publishing and animation size presets. Returns `{ updated: true }`. Returns 404 if the collection is not owned by the caller. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingsBody"}}}},"responses":{"200":{"description":"Settings updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatedFlagResponse"},"example":{"data":{"updated":true}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases":{"get":{"tags":["Canvases"],"summary":"List canvases in a collection","description":"Returns all canvases (state machines / animation graphs) attached to the collection. A canvas describes nodes (poses) and edges (loops or transitions). No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"List of canvases","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasListResponse"},"example":{"data":[]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["Canvases"],"summary":"Create a canvas","description":"Creates a canvas for the collection. If `template_id` is provided, items and images are generated for every node (image cost per node, 1 credit each). With no `template_id`, creates an empty canvas with zero cost. Returns 201.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCanvasBody"}}}},"responses":{"201":{"description":"Created canvas (populated if template_id provided)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasResponse"},"example":{"data":{"id":"8c4b872c-df43-4d64-b84c-00f0d8314140","name":"test-empty-canvas","graph":{"edges":[],"nodes":[],"inputs":[],"viewport":{"x":0,"y":0,"zoom":1}},"created_at":"2026-04-19T09:42:15.222526+00:00"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}":{"get":{"tags":["Canvases"],"summary":"Get canvas details","description":"Returns the canvas with its full graph (nodes, edges, inputs, viewport) and a status summary indicating which nodes/edges have been generated. `status.ready` is true when all images and transitions have completed.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"}],"responses":{"200":{"description":"Canvas details with status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasResponse"},"example":{"data":{"id":"280ceab9-4673-4c78-b37c-3617feb51914","name":"test-canvas-from-template","graph":{"edges":[{"id":"d7420e54-9545-4527-bff0-912be67c3758","jobId":"a3c6ec30-a82c-41b2-a28f-37bedf369815","source":"38df9602-c21a-4637-9cea-c0962433d2e1","target":"38df9602-c21a-4637-9cea-c0962433d2e1","reverse":false,"duration":4,"conditions":[],"description":"Gentle breathing, slow blinking, tail curling slightly","videoAssetId":"a98ba960-c1b3-4bf5-9e6f-1d57b43c651d","reverseOfEdgeId":null}],"nodes":[{"x":0,"y":0,"id":"38df9602-c21a-4637-9cea-c0962433d2e1","itemName":"Idle"}],"inputs":[],"viewport":{"x":0,"y":0,"zoom":0.8}},"status":{"nodes":{"total":2,"completed":2,"pending":0},"edges":{"total":3,"completed":3,"pending":0,"failed":0},"ready":true,"failed_edges":[]}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"tags":["Canvases"],"summary":"Update canvas graph or name","description":"Updates canvas name or replaces its graph. Use this to add/remove nodes and edges before calling generate-all. No credit cost - generation is triggered separately.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCanvasBody"}}}},"responses":{"200":{"description":"Canvas updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["Canvases"],"summary":"Delete a canvas","description":"Deletes the canvas record. Generated node/edge assets are kept but no longer linked. Returns 204. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"}],"responses":{"204":{"description":"Canvas deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}/graph/extend":{"post":{"tags":["Canvases"],"summary":"Extend a canvas graph","description":"Safely appends nodes, edges, and inputs, and applies partial edge updates without replacing the whole graph. Existing generated asset IDs are preserved unless an update_edges patch explicitly changes that edge.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendCanvasGraphBody"}}}},"responses":{"200":{"description":"Canvas graph extended","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasGraphExtendResponse"},"example":{"data":{"id":"280ceab9-4673-4c78-b37c-3617feb51914","name":"Main canvas","graph":{"nodes":[],"edges":[],"inputs":[],"viewport":{"x":0,"y":0,"zoom":1}},"updated_at":"2026-05-04T12:00:00.000Z","added":{"nodes":1,"edges":2,"inputs":1},"updated":{"edges":1}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}/edges/{edgeId}":{"patch":{"tags":["Canvases"],"summary":"Patch a canvas edge","description":"Patches one edge without replacing the graph. Use this for speed tuning after generation: normal transitions use speed 2, snappy interact transitions use 3-4, held/special loops use 2, and calm loops use 1.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"edgeId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchCanvasEdgeBody"}}}},"responses":{"200":{"description":"Canvas edge patched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasEdgePatchResponse"},"example":{"data":{"id":"280ceab9-4673-4c78-b37c-3617feb51914","name":"Main canvas","edge":{"id":"idle-to-interact","source":"idle","target":"interact","duration":4,"speed":3},"graph":{"nodes":[],"edges":[],"inputs":[],"viewport":{"x":0,"y":0,"zoom":1}},"updated_at":"2026-05-04T12:00:00.000Z"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}/edges/{edgeId}/generate":{"post":{"tags":["Canvases"],"summary":"Generate a single canvas edge","description":"Dispatches generation for one specific canvas edge by ID. Costs the same as a single edge in generate-all (duration * 5 credits). If the edge already has a video asset, archives the old assets and re-dispatches. Any State edges (source: \"*\") and reverse edges are rejected with 400. Requires the source and target nodes to already have generated images.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"},{"schema":{"type":"string"},"required":true,"name":"edgeId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateEdgeBody"}}}},"responses":{"202":{"description":"Edge generation started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasEdgeGenerateResponse"},"example":{"data":{"job_id":"a1b2c3d4-0000-0000-0000-000000000001","edge_id":"idle-to-interact","type":"transition","source":"Idle","target":"Interact","cost":20,"urls":{},"poll_url":"/v1/jobs/a1b2c3d4-0000-0000-0000-000000000001"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}/generate-all":{"post":{"tags":["Canvases"],"summary":"Generate canvas images, stickers, and animations","description":"Kicks off generation for pending canvas node images, sticker derivatives, and/or edge animations. Use `targets=\"images\"` to generate poses, `targets=\"stickers\"` to backfill transparent sticker derivatives for completed node images, `targets=\"animations\"` for edge videos, or `include_stickers=true` to create stickers alongside newly generated images. Stickers cost 1 credit each. Each generated edge costs 5 credits per second (duration * 5). Returns 202 with new jobs plus explicit `skipped_items`, `reverse_free`, `already_complete`, `estimated_cost`, and `actual_cost` accounting. Returns 402 if credits are insufficient.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateAllBody"}}}},"responses":{"202":{"description":"Generation jobs started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasGenerateAllResponse"},"example":{"data":{"jobs":[{"job_id":"58341ab3-80fc-4fca-8a86-f9d2caee9a14","edge_id":"095872b7-c6f6-4f6d-8679-9739436fd16c","type":"transition","source":"Idle","target":"Waving","cost":20,"urls":{"webm":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/idle---waving-a622eb51.webm","video":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/idle---waving-7e5fe2ec.mp4","hevc":"https://assets.masko.ai/fda8417d/cat-api-test-1776591702/idle---waving-2880976b.mov"}}],"total_jobs":3,"total_cost":60,"generated":[],"skipped":0,"skipped_items":[],"reverse_free":[{"kind":"edge","id":"waving-to-idle","reason":"reverse_edge_free","reverse_of_edge_id":"idle-to-waving"}],"already_complete":[],"estimated_cost":60,"actual_cost":60}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/collections/{id}/canvases/{canvasId}/export":{"get":{"tags":["Canvases"],"summary":"Export a canvas","description":"Exports the canvas as legacy MaskoAnimationConfig JSON by default, or as a target-specific delivery envelope with delivery=1. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"canvasId","in":"path"},{"schema":{"type":"string","enum":["json"]},"required":false,"name":"format","in":"query"},{"schema":{"type":"string","enum":["1"],"description":"Return the delivery envelope instead of legacy MaskoAnimationConfig data."},"required":false,"description":"Return the delivery envelope instead of legacy MaskoAnimationConfig data.","name":"delivery","in":"query"},{"schema":{"type":"string","enum":["macos","web","full"],"description":"Delivery media target. macos returns HEVC URLs, web returns WebM and HEVC URLs, full returns all selected formats."},"required":false,"description":"Delivery media target. macos returns HEVC URLs, web returns WebM and HEVC URLs, full returns all selected formats.","name":"target","in":"query"},{"schema":{"type":"string","enum":["selected","manifest"],"description":"Delivery mode. selected returns one variant; manifest includes known variants."},"required":false,"description":"Delivery mode. selected returns one variant; manifest includes known variants.","name":"mode","in":"query"},{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Selected delivery size in pixels, if that size variant has already been generated."},"required":false,"description":"Selected delivery size in pixels, if that size variant has already been generated.","name":"size","in":"query"}],"responses":{"200":{"description":"Canvas export data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportConfigResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/canvas-templates":{"get":{"tags":["Canvases"],"summary":"List canvas templates","description":"Returns built-in templates plus any user-owned templates. Templates describe node prompts and edge definitions used to bootstrap canvases (e.g. \"Essential Mascot\", \"Bonzi Buddy\"). No credit cost.","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"List of canvas templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasTemplateListResponse"},"example":{"data":[{"id":"bonzi-buddy-7state","name":"Bonzi Buddy","description":"7 animated poses with rich interactions: idle, coding, thinking, waving, celebrating, sleeping, and greeting on click. Classic Bonzi Buddy personality with sounds. ~340 credits.","source":"builtin","nodes":[{"key":"idle","name":"Idle","imagePrompt":"Standing casually, looking around curiously with big expressive eyes, slight swaying, hands at sides, friendly relaxed expression","position":{"x":0,"y":0}}],"edges":[]}]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["Canvases"],"summary":"Create a canvas template","description":"Creates a reusable user-owned canvas template. Templates can later be applied via POST `/v1/collections/{id}/canvases` with `template_id`. No credit cost.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateBody"}}}},"responses":{"201":{"description":"Created template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasTemplateResponse"},"example":{"data":{"id":"a5eba03f-8c29-481b-98b9-5cfc778cfcc7","name":"test-template-tmp","created_at":"2026-04-19T09:42:35.319739+00:00","source":"user","public":false}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/canvas-templates/{id}":{"get":{"tags":["Canvases"],"summary":"Get canvas template details","description":"Returns the full template definition including node prompts, edges, and any declared inputs. Works for both built-in and user-owned templates. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Template details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasTemplateResponse"},"example":{"data":{"id":"claude-code-4state-lite","name":"Essential Mascot","description":"All 4 reactions (resting, coding, thinking, waving) at a lower cost. Uses smart routing to keep animations minimal. ~144 credits.","source":"builtin","nodes":[{"key":"idle","name":"Idle","imagePrompt":"Relaxed, calm, sitting on the floor or resting, eyes half-open, peaceful expression, breathing gently","position":{"x":0,"y":0}}],"edges":[],"inputs":[{"name":"claudeCode::isWorking","type":"boolean","default":false,"system":true}]}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"tags":["Canvases"],"summary":"Update a canvas template","description":"Updates name, description, public flag, or the template graph for a user-owned template. Built-in templates cannot be modified (returns 403). No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateBody"}}}},"responses":{"200":{"description":"Template updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CanvasTemplateResponse"},"example":{"data":{"id":"a5eba03f-8c29-481b-98b9-5cfc778cfcc7","user_id":"fda8417d-8789-4dce-aa64-c553a3de2ac0","name":"test-template-tmp","description":"Updated description","template":{"edges":[{"source":"a","target":"a","duration":4,"description":"A idling"}],"nodes":[{"key":"a","name":"A","position":{"x":0,"y":0},"imagePrompt":"pose A"}],"inputs":[]},"public":false,"created_at":"2026-04-19T09:42:35.319739+00:00","updated_at":"2026-04-19T09:42:35.319739+00:00"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"tags":["Canvases"],"summary":"Delete a canvas template","description":"Deletes a user-owned template. Built-in templates cannot be deleted (returns 403). Returns 204. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Template deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/jobs":{"get":{"tags":["Jobs"],"summary":"List generation jobs","description":"Returns paginated generation jobs owned by the caller, newest first. Use to track recent activity or find a specific job. Filter by status or collection. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":50,"description":"Page size. 1 to 100. Defaults to 50."},"required":false,"description":"Page size. 1 to 100. Defaults to 50.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of records to skip. Defaults to 0."},"required":false,"description":"Number of records to skip. Defaults to 0.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by status: pending, processing, completed, failed."},"required":false,"description":"Filter by status: pending, processing, completed, failed.","name":"status","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Filter to jobs for a specific collection."},"required":false,"description":"Filter to jobs for a specific collection.","name":"collection_id","in":"query"},{"schema":{"type":"string","description":"Filter by job type. Values: item_generation, image_generation, logo, animation, reverse, size_variant, size_variant_batch, export_animation, scene_generation."},"required":false,"description":"Filter by job type. Values: item_generation, image_generation, logo, animation, reverse, size_variant, size_variant_batch, export_animation, scene_generation.","name":"type","in":"query"}],"responses":{"200":{"description":"List of jobs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobListResponse"},"example":{"data":[{"id":"ccc8bbf9-d3b2-4d8b-b21f-c5f91c5fbffa","type":"scene_generation","status":"completed","collection_id":"21c247da-2359-47b2-97f9-da70bc1af688","output_asset_id":null,"cost_credits":3,"error":null,"created_at":"2026-04-14T11:14:49.18381+00:00","updated_at":"2026-04-14T11:15:47.524116+00:00","op_code":null,"input_data":{"cost":3,"scene":"A misty bamboo forest at dawn with golden sun rays piercing through the leaves","action":"stretching with arms wide and a relaxed grin","item_id":"7defa668-99ec-4f34-afa0-48599889958b","position":"center","aspect_ratio":"4:5","collection_id":"21c247da-2359-47b2-97f9-da70bc1af688"},"output_data":{"width":3712,"height":4608,"image_url":"image/png/5c08e718-acf3-4327-8ef5-895d0beefd4d.coach-ginger"}}],"meta":{"pagination":{"total":29,"limit":5,"offset":0,"has_more":true}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/jobs/{id}":{"get":{"tags":["Jobs"],"summary":"Long-poll a job to completion","description":"Returns job status and output URLs. Pass `?wait=true` to long-poll until the job completes or fails (up to ~60s). Returns 404 if the job does not exist or is not owned by the caller.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["true","false"],"description":"If true, long-poll until the job completes, fails, or timeout is reached. If false or omitted, return the current status immediately."},"required":false,"description":"If true, long-poll until the job completes, fails, or timeout is reached. If false or omitted, return the current status immediately.","name":"wait","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":120,"description":"Long-poll timeout in seconds when wait=true. 1 to 120. Defaults to 120. On timeout the response is 200 with the current (still pending) job state, not 408."},"required":false,"description":"Long-poll timeout in seconds when wait=true. 1 to 120. Defaults to 120. On timeout the response is 200 with the current (still pending) job state, not 408.","name":"timeout","in":"query"}],"responses":{"200":{"description":"Job details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResponse"},"example":{"data":{"id":"ccc8bbf9-d3b2-4d8b-b21f-c5f91c5fbffa","status":"completed","type":"scene_generation","collection_id":"21c247da-2359-47b2-97f9-da70bc1af688","cost_credits":3,"created_at":"2026-04-14T11:14:49.18381+00:00","updated_at":"2026-04-14T11:15:47.524116+00:00","item_id":"7defa668-99ec-4f34-afa0-48599889958b","item_name":"loop test - bamboo","urls":{"image":"https://storage.googleapis.com/masco-media/image/png/5c08e718-acf3-4327-8ef5-895d0beefd4d.coach-ginger?GoogleAccessId=...&Expires=...&Signature=..."}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/credits":{"get":{"tags":["Credits"],"summary":"Get credit balance","description":"Returns current credits split into `subscription` (monthly allowance) and `topup` (purchased or bonus), plus `total`. Use before kicking off a large generation run to confirm balance. No credit cost.","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Credit balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditsResponse"},"example":{"data":{"subscription":0,"topup":894,"total":894}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/styles":{"get":{"tags":["Styles"],"summary":"List available style presets","description":"Returns all built-in style presets (cartoon, flat, pixel, kawaii, etc.) with preview URLs where available. Use `id` in generation prompts or as a style hint. No credit cost.","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Available style presets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StylesResponse"},"example":{"data":[{"id":"cartoon","name":"Cartoon","description":"Fun, colorful with bold outlines","category":"classic","preview_url":"https://assets.masko.ai/7fced6/budget-buddy-2702/think-2bb9ff25.png"},{"id":"flat","name":"Flat","description":"Clean, minimal, geometric","category":"classic","preview_url":"https://assets.masko.ai/7fced6/turbo-9bb8/encourage-0791d248.png"},{"id":"pixel","name":"Pixel Art","description":"Retro 8-bit video game style","category":"retro","preview_url":"https://assets.masko.ai/7fced6/pixel-runner-f1fb/flex-06183f7f.png"}]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/upload":{"post":{"tags":["Upload"],"summary":"Upload an image by URL","description":"Fetches an image from a public URL and stores it as an `image` asset owned by the caller. Returns `data.asset_id` which can then be passed as a reference or as a `source_asset_id` to generation. No credit cost.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlBody"}}}},"responses":{"200":{"description":"Uploaded asset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResponse"},"example":{"data":{"asset_id":"e906ebb5-deb1-4010-82f9-f0182a3812e0"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/generate/preview":{"post":{"tags":["Generate"],"summary":"Preview an idea before creating a collection","description":"Synchronous, throwaway image generation for iterating on mascot ideas cheaply before committing to a collection. No collection required. Tweak the prompt, regenerate, compare, then use the winning prompt + a reference image in POST /v1/collections. Also supports `reference_image_urls` to check \"does this prompt resemble my sketch?\". Returns signed URLs with a 1-hour expiry - the images are not stored. Costs 1 credit per image (the `cost` field in the response confirms the amount). Returns 402 if credits are insufficient.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewBody"}}}},"responses":{"200":{"description":"Preview images","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResponse"},"example":{"data":{"images":[{"url":"https://storage.googleapis.com/masco-media/api-previews/.../3a0d33a8.jpeg?GoogleAccessId=...&Expires=...&Signature=...","expires_in":3600}],"cost":1}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/analyze":{"post":{"tags":["Analyze"],"summary":"Analyze an image or website URL","description":"Analyzes an image (by URL) or a public website and returns a description, style hints, a suggested mascot name, and a suggested prompt ready to feed into POST `/v1/collections`. When `type=url`, the response also includes a screenshot (omitted from example for brevity). No credit cost.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeBody"}}}},"responses":{"200":{"description":"Analysis result (image or url)","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/AnalyzeImageResponse"},{"$ref":"#/components/schemas/AnalyzeUrlResponse"}]},"example":{"data":{"description":"A whimsical, wide-eyed ginger cat character designed with a claymation-like aesthetic. The cat features a plump, rounded body, a matte terracotta finish with fine dark speckles, and a charmingly surprised facial expression characterized by large circular eyes and thin, stylized whiskers.","style_hints":["Claymation","Terracotta texture","Matte finish","Rounded minimalist forms","Speckled surface","Soft studio lighting","3D sculpture"],"suggested_name":"Terracotta Tom","suggested_prompt":"A high-quality 3D render of a chubby ginger cat mascot in a claymation style. The cat is sitting, has a surprised expression with wide white eyes, a tiny pink nose, and thin clay whiskers. The material is matte terracotta orange with subtle dark speckles. Soft lighting, white background, clean minimalist aesthetic."}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhook subscriptions","description":"Returns all webhook subscriptions owned by the caller, including `consecutive_failures` and `active` flag. Webhooks are auto-deactivated after repeated delivery failures. No credit cost.","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"List of webhooks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"},"example":{"data":[{"id":"7c358096-8521-463c-b9c3-fd81bddaffc3","url":"https://example.com","events":["job.completed"],"active":true,"consecutive_failures":3,"created_at":"2026-04-08T03:31:26.284516+00:00"}]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"tags":["Webhooks"],"summary":"Create a webhook subscription","description":"Creates a webhook subscription. Returns 201 with the subscription record including a one-time `secret` used to verify future HMAC signatures - store it immediately, it is never returned again. No credit cost.","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookBody"}}}},"responses":{"201":{"description":"Created webhook","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"},"example":{"data":{"id":"5863639e-ad3f-4d4e-9bb3-12d0088d7d52","url":"https://example.com/test-webhook","events":["job.completed","job.failed"],"created_at":"2026-04-19T09:42:34.430422+00:00","secret":"whsec_3abe7a98aab0fcdb5c3b97142cf90dabccca37aa42974a198e7bdedb1148ce93"}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/webhooks/{id}":{"delete":{"tags":["Webhooks"],"summary":"Delete a webhook subscription","description":"Removes the webhook subscription - no further events will be delivered. Returns 204. No credit cost.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Webhook deleted"},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}}},"x-tagGroups":[{"name":"Mascot","tags":["Collections","Items","Assets","References","Settings"]},{"name":"Creating content","tags":["Generate","Canvases"]},{"name":"Platform","tags":["Projects","Jobs","Webhooks","Credits","Styles","Upload","Analyze"]}]}