Tools reference
Every tool the server exposes, grouped the way it's grouped in the changelog: identity, discovery, generation, design import, and design editing. Each tool's required scope and Abyssale role are noted beside it — the Owner can always use every tool regardless of role. See Permissions for a single table of what every tool can actually do before you authorize one.
Reading a design before generating from it is worth doing every time: an unknown layer or attribute name in a generation call is silently accepted and does nothing — there is no error to tell you the name was wrong.
Identity
get_me
Look up who you're signed in as and which Abyssale workspace you're connected to.
Read-only. No scope required beyond being signed in · role Admin, Manager, Designer, or Operator
This tool has no parameters.
Example
// Result
{
"user_uuid": "6b1f7e3a-2e77-4f2a-9a5b-9c1f9d6a2b10",
"company_uuid": "0e5a2c9d-8b4a-4a3d-9e6f-1a2b3c4d5e6f",
"company_name": "Acme Inc."
}Discovery
get_remaining_credits
Shows how many generation credits (image/video renders) and AI credits (text-to-image, remove-background, etc.) this workspace has left this billing period.
Read-only · scope read:credits · role Admin, Manager, Designer, or Operator
This tool has no parameters.
Example
// Result
{
"generation_credits": { "available": 842, "limit": 1000, "consumed": 158, "extra": 0 },
"ai_credits": { "available": 88, "limit": 100, "consumed": 12, "extra": 0 }
}available and limit are null when the workspace has unlimited credits of that type.
list_designs
List the designs in your workspace, most recently edited first unless sort says otherwise. Use this to browse what exists, or to get a design id — the generation tools need an id, not a name. Prefer search_designs if you already know roughly what the design is called.
Excludes: designs in projects you can't open, shared workspace templates (copy them into the workspace first), designs with no project or a deleted project, and drafts.
Read-only · scope read:design · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
type | enum or list of: static, animated, printer, printer_multipage | No | Only designs of this kind — one, or several. |
orientation | enum: portrait, landscape, square | No | Only designs with at least one format of this shape. |
size | list of strings <width>x<height> | No | Only designs with a format of one of these sizes, in the design's unit (1080x1920, 210x297 mm). |
format | list of strings | No | Only designs with a format of one of these names (the format id from get_design). |
updated_since | string, ISO 8601 date | No | Only designs last edited at or after this date. |
created_since | string, ISO 8601 date | No | Only designs created at or after this date. |
project_id | string (uuid) | No | Only designs in this project — its id from list_projects or a design's project_id. |
sort | enum: updated, created, name | No | updated (last edited) by default. |
order | enum: asc, desc | No | desc (newest first) for the dates, asc (A to Z) for name by default. |
page | integer, min 1 | No | 1-based page number. Defaults to 1. |
per_page | integer, 1–100 | No | Designs per page. Defaults to 25. |
Example
// Call
{ "type": "static", "per_page": 2 }// Result
{
"summary": "Showing 2 of 46 designs (page 1). Ask for page 2, or narrow the search, to see more. Sorted by last edited, newest first.",
"designs": [
{
"id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b",
"name": "Black Friday banner",
"type": "static",
"project_name": "Q4 Campaign",
"project_id": "1a2b3c4d-5e6f-4a3b-8c9d-0e1f2a3b4c5d",
"updated_at_ts": 1767222000,
"preview_url": "https://cdn.abyssale.com/previews/8f2c1a3e.png"
}
],
"total_count": 46,
"page": 1,
"per_page": 2,
"has_more": true,
"sort": "updated",
"order": "desc"
}summary says in words what the page is — how many of how many, the order, and when nothing matched, what to try next. It is in both the text and the structured result, because some clients show the model only one of the two.
search_designs
Find designs when the user describes which one they want — "the black friday banner", "my instagram design", "the summer sale story". Use query first: its words are matched in any order, each in the design name or the project name, ignoring case and the hyphens or underscores names are written with. name and project are strict filters for one exact phrase. Returns design ids, which the generation tools require. Same search as the REST API's GET /designs.
Read-only · scope read:design · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string, min 1 char | No | Words to find, in any order, each in the design or project name. At most 8 words. |
name | string, min 1 char | No | One exact phrase in the design's name. |
project | string, min 1 char | No | One exact phrase in the project name. |
project_id | string (uuid) | No | Only designs in this project. |
type | enum or list of: static, animated, printer, printer_multipage | No | Only designs of this kind — one, or several. |
orientation | enum: portrait, landscape, square | No | Only designs with at least one format of this shape. |
size | list of strings <width>x<height> | No | Only designs with a format of one of these sizes, in the design's unit (1080x1920, 210x297 mm). |
format | list of strings | No | Only designs with a format of one of these names (the format id from get_design). |
updated_since | string, ISO 8601 date | No | Only designs last edited at or after this date. |
created_since | string, ISO 8601 date | No | Only designs created at or after this date. |
sort | enum: updated, created, name | No | updated (last edited) by default. |
order | enum: asc, desc | No | Defaults as in list_designs. |
page | integer, min 1 | No | 1-based page number. Defaults to 1. |
per_page | integer, 1–100 | No | Designs per page. Defaults to 25. |
Example
// Call
{ "query": "black friday" }// Result — same shape as list_designs
{
"summary": "1 design. Sorted by last edited, newest first.",
"designs": [
{
"id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b",
"name": "Black-Friday banner",
"type": "static",
"project_name": "Q4 Campaign",
"project_id": "1a2b3c4d-5e6f-4a3b-8c9d-0e1f2a3b4c5d",
"updated_at_ts": 1767222000,
"preview_url": "https://cdn.abyssale.com/previews/8f2c1a3e.png"
}
],
"total_count": 1,
"page": 1,
"per_page": 25,
"has_more": false,
"sort": "updated",
"order": "desc"
}When project matches several projects, the result adds matched_project_count and the summary says to pass project_id. When nothing matches, the summary names every filter it applied and suggests the next try (query instead of name, or dropping type).
list_projects
List the projects (campaigns/folders that group designs) in your workspace, alphabetically. Only projects you can open are listed. Pass a project's id as project_id to search_designs or list_designs.
Read-only · scope read:project · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string, min 1 char | No | Only projects whose name contains this text. |
page | integer, min 1 | No | 1-based page number. Defaults to 1. |
per_page | integer, 1–100 | No | Projects per page. Defaults to 25. |
Example
// Result
{
"summary": "5 projects.",
"projects": [
{ "id": "1a2b3c4d-5e6f-4a3b-8c9d-0e1f2a3b4c5d", "name": "Q4 Campaign", "created_at_ts": 1755000000 }
],
"total_count": 5,
"page": 1,
"per_page": 25,
"has_more": false
}create_project
Create a new project (folder for designs) in your workspace. Fails if a project with this name already exists — it does not overwrite one.
Mutates state — creates a new project. Scope write:project · role Admin or Manager
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string, 2–100 characters | Yes | The project's name. |
Example
// Call
{ "name": "Q1 Campaign" }// Result
{ "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "name": "Q1 Campaign", "created_at_ts": 1767312000 }list_fonts
List fonts available for text and button elements — roughly 1,149 Google Fonts (always available) plus this workspace's own custom uploads. Filter rather than browse: by name (exact names first), by category for a style ("an elegant serif"), by weight for a weight and by style for italic — "bold" is weight: 700 and "italic" is style: "italic", not part of a name. The returned id is the value to set under a text/button element's font attribute when generating. Same search as the REST API's GET /fonts.
Read-only · scope read:font · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string, min 1 char | No | Text in the font name, ignoring case, accents, spaces and hyphens. Exact names come first. |
category | enum: serif, sans-serif, display, handwriting, monospace | No | Only Google fonts of this style. |
weight | integer, 100–900 by hundreds | No | Only fonts with this weight — upright, or italic with style: "italic". |
style | enum: normal, italic | No | Only fonts with a variant in this style. Apply italic at generation with text markup: <w=italic>…</w>. |
type | enum: google, custom | No | Only fonts of this kind. Omit for both. |
page | integer, min 1 | No | 1-based page number. Defaults to 1. |
per_page | integer, 1–100 | No | Fonts per page. Defaults to 25. |
Example
// Call
{ "name": "roboto", "weight": 700 }// Result
{
"summary": "1 font.",
"fonts": [
{ "id": "font_roboto", "name": "Roboto", "available_weights": [100, 300, 400, 500, 700, 900, "700-italic"], "category": "sans-serif", "type": "google" }
],
"total_count": 1,
"page": 1,
"per_page": 25,
"has_more": false
}Italic weights arrive as strings shaped like "700-italic", not a separate boolean. A name search that contains a weight word ("Montserrat Bold") and finds nothing says, in summary, which weight to pass instead.
get_design
Look up a design's layers and which attributes can be overridden — call this before any generation tool rather than guessing. Works on any design type; the type it returns tells you which tool generates it:
type | Generate with |
|---|---|
static | generate_static_banner, or generate_banners_async for several formats at once or AI image properties |
animated (video, GIF, HTML5) | generate_banners_async |
printer (PDF) | generate_banners_async |
printer_multipage | generate_multipage_pdf |
Read-only · scope read:design · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
Example
// Call
{ "design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b" }// Result
{
"id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b",
"name": "Black Friday banner",
"type": "static",
"formats": [
{ "id": "facebook-post", "uid": "fmt_9a1b", "width": 1200, "height": 630, "unit": "px", "preview_url": "https://cdn.abyssale.com/previews/fb-post.png" }
],
"elements": [
{ "name": "title", "type": "text", "attributes": [{ "id": "payload" }, { "id": "font" }, { "id": "color" }] },
{ "name": "background", "type": "image", "attributes": [{ "id": "src" }] }
],
"variables": ["first_name"]
}variables lists the design-wide text variables (names without braces), when the design has any. Override them under elements.vars, e.g. {"vars": {"first_name": "Alex"}}.
printer_multipage designs come back with only id/name/type/note — per-page detail isn't exposed by this tool; use get_design_as_import instead.
get_design_as_import
Return a design's entire structure — every format, layer, animation tween, printer bleed/safe DPI, or every page for printer_multipage designs — in the exact shape a design-import payload takes. Different from get_design/get_design_format, which trim to what generation can override: this is the full, unfiltered structure. Works on every design type, including printer_multipage. Useful for explaining how a design is built, as a worked example, or as the payload import_design_from_json accepts to recreate/duplicate the design.
Read-only · scope read:design · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
Example
// Result (trimmed)
{
"payload": { "name": "Black Friday banner", "type": "static", "formats": ["…"] },
"warnings": [],
"version": "1"
}get_design_format
Look up the current values, layout and overridable attributes for one format of a design, flattened. Call get_design first to see which formats and layers exist; use this once you've picked a format_specifier to see its concrete current state before overriding anything.
Read-only · scope read:design · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
format_specifier | string, min 1 char | Yes | A format's id (slug) or uid, from get_design's formats[]. |
Example
// Call
{ "design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b", "format_specifier": "facebook-post" }// Result (trimmed)
{
"id": "facebook-post",
"uid": "fmt_9a1b",
"width": 1200,
"height": 630,
"unit": "px",
"preview_url": "https://cdn.abyssale.com/previews/fb-post.png",
"elements": [
{ "name": "title", "type": "text", "attributes": [{ "id": "payload", "value": "Up to 50% off" }] }
],
"variables": ["first_name"]
}variables works the same as on get_design: override them under elements.vars.
printer_multipage designs have no formats — expect format_not_found for any format_specifier on one of those.
get_design_import_example
Returns one full worked payload for import_design_from_json's payload argument, downloaded verbatim from developers.abyssale.com's own example gallery — not hand-written. Use static-multi-format when the design needs more than one format: it's the only example that shows the format-keyed layout/properties shape a single-format example can't teach.
The same examples are also published as MCP resources under abyssale://design-import-examples/*; use this tool instead if your client doesn't surface MCP resources.
Read-only · scope read:design (no live data — bundled static examples, grouped here for consistency) · role: any signed-in role — not role-gated
| Parameter | Type | Required | Description |
|---|---|---|---|
type | enum: static, static-multi-format, animated, animated-video, printer, printer-multipage | Yes | Which example to fetch. |
Example
// Call
{ "type": "static" }// Result (trimmed)
{ "slug": "static", "title": "Static design (3 formats)", "payload": { "name": "…", "type": "static" } }Generation
Every tool in this group spends credits — see Permissions for what and how much. Call get_design (and get_design_format for one specific format) first to find valid template_format_name and elements keys — an unknown layer or attribute name is silently accepted and does nothing, with no error.
generate_static_banner
Generate a single image from a static design, synchronously — you get the file URL back immediately, no polling. Only works on static designs; animated, printer and printer_multipage designs fail with template_not_static — use generate_banners_async for animated and printer designs, and generate_multipage_pdf for printer_multipage. Rendering is capped at 10 seconds server-side; most renders finish in a few hundred milliseconds.
Mutates state, spends generation credits (amount varies — see Understanding Abyssale credits); can overwrite an existing visual via original_visual_id · scope generate:banner · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Must be a static design. |
template_format_name | string, min 1 char | No | Format to generate, e.g. facebook-post. Omit for the design's first format. |
elements | object of objects | No | Overrides keyed by layer name, e.g. {"title": {"payload": "Sale"}}. Every value must be an object. |
image_file_type | enum: png, jpeg, webp, avif, pdf, auto | No | Omitted/auto picks jpeg, or png for a transparent background. |
original_visual_id | uuid | No | Regenerate an existing visual in place, keeping its share URL. |
file_compression_level | integer, 1–100 | No | Higher is better quality (less compression). |
Example
// Call
{
"design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b",
"template_format_name": "facebook-post",
"elements": { "title": { "payload": "Up to 50% off" } }
}// Result
{
"id": "b2d4e6f8-1a3c-4e5f-8a9b-2c3d4e5f6a7b",
"version": 3,
"sharing_id": "c3d5e7f9-2b4d-4e5f-9a0b-3c4d5e6f7a8b",
"file": {
"type": "jpeg",
"url": "https://api.abyssale.com/files/b2d4e6f8.jpeg",
"cdn_url": "https://cdn.abyssale.com/files/b2d4e6f8.jpeg",
"filename": "black-friday-banner.jpeg"
},
"format": { "id": "facebook-post", "unit": "px", "width": 1200, "height": 630 }
}generate_banners_async
Generate one or more formats of a static, animated, or printer design asynchronously — video, HTML5, GIF, multi-format in one call, and AI image properties (text_to_image, remove_bg) that generate_static_banner doesn't support. printer_multipage designs aren't supported here — use generate_multipage_pdf.
By default this waits internally up to ~60 seconds and returns the finished result directly if it lands in time — most single/simple-format jobs do. If it's still not done, you get back generation_request_id with is_finalized: false; poll it with check_generation_status.
Mutates state, spends generation credits (amount varies — see Understanding Abyssale credits; and AI credits if elements uses text_to_image or remove_bg); can overwrite an existing visual via original_visual_id · scope generate:banner · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Static, animated, or printer — not printer_multipage. |
template_format_names | array of strings | No | Which formats to generate. Omit for every format. |
elements | object of objects | No | Overrides keyed by layer name; image elements also accept AI properties. |
image_file_type | enum: png, jpeg, webp, avif, gif, pdf, html5, mp4, auto | No | Must match the design's type: static → png/jpeg/webp/avif/pdf; animated → html5/mp4/gif; printer → pdf. |
file_compression_level | integer, 1–100 | No | Higher is better quality. |
html5 | object: page_title, click_tag, ad_network (each up to 255 characters), include_backup_image, repeat (−1 to 100) | No | Animated designs only. |
gif | object: max_fps (2–9), repeat (−1 to 100) | No | Animated designs only. |
video | object: fps (2–30) | No | Animated designs only. |
print | object: color_profile (uuid), display_crop_marks | No | Printer designs only. |
original_visual_id | uuid | No | Regenerate an existing visual in place — requires exactly one resulting format. |
callback_url | url | No | Abyssale sends the job result to this URL when the job is done, instead of you polling. The URL can be outside Abyssale. Only useful with a publicly reachable server, not from a chat session. |
wait_for_result | boolean, default true | No | false skips the internal wait and returns the id immediately. |
Example
// Call
{ "design_id": "9c3d2b1a-...", "image_file_type": "mp4", "wait_for_result": false }// Result — not finalized yet
{
"generation_request_id": "d4e6f8a0-3c5e-4f60-9a1b-4c5d6e7f8a9b",
"is_finalized": false,
"banners": [],
"errors": []
}generate_multipage_pdf
Generate a print-ready multi-page PDF from a printer_multipage design — the only generation tool that works on that design type. Pages have no id/name of their own: call get_design_as_import first and address the Nth entry of payload.pages[] here as pages.page_N (1-indexed).
Same internal wait/fallback behavior as generate_banners_async. Deliberately does not accept original_visual_id — unsafe on this endpoint.
Mutates state, spends generation credits (amount varies — see Understanding Abyssale credits) · scope generate:banner · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Must be a printer_multipage design. |
pages | object of objects of objects | Yes | Per-page element overrides, keyed page_1, page_2, … (1-indexed). |
print | object: color_profile (uuid), display_crop_marks | No | Print output options. |
callback_url | url | No | Abyssale sends the job result to this URL when the job is done, instead of you polling. The URL can be outside Abyssale. Only useful with a publicly reachable server, not from a chat session. |
wait_for_result | boolean, default true | No | false skips the internal wait and returns the id immediately. |
Example
// Call
{
"design_id": "0d4e3c2b-...",
"pages": { "page_1": { "headline": { "payload": "Catalog 2027" } } }
}// Result — same shape as check_generation_status
{
"generation_request_id": "e5f7a9b1-4d6f-4a71-9b2c-5d6e7f8a9b0c",
"is_finalized": true,
"banners": [
{ "id": "…", "version": 1, "sharing_id": "…", "file": { "type": "pdf", "url": "…", "filename": "catalog-2027.pdf" }, "format": { "unit": "mm", "width": 210, "height": 297 } }
],
"errors": []
}check_generation_status
Check the status of a generation started by generate_banners_async or generate_multipage_pdf. is_finalized: false means still rendering — call again later rather than in a tight loop. Once is_finalized: true, every requested format is accounted for as either a success (banners) or a failure (errors, with a reason). Results are kept for 7 days; after that this answers generation_request_gone.
Read-only · scope generate:banner (same scope as the tools it polls — a client that can't generate has no legitimate reason to poll a job it couldn't have started) · role Admin, Manager, Designer, or Operator
| Parameter | Type | Required | Description |
|---|---|---|---|
generation_request_id | string, min 1 char | Yes | The id returned by generate_banners_async or generate_multipage_pdf. |
Example
// Result
{
"generation_request_id": "d4e6f8a0-3c5e-4f60-9a1b-4c5d6e7f8a9b",
"is_finalized": true,
"banners": [
{ "id": "…", "version": 1, "sharing_id": "…", "file": { "type": "mp4", "url": "…", "cdn_url": "…", "filename": "banner.mp4" }, "format": { "id": "facebook-post", "unit": "px", "width": 1200, "height": 630 } }
],
"errors": []
}Design import
import_design_from_json
Create a design (or workspace template) from a JSON structure — the same shape get_design_as_import returns. By default waits internally up to ~60 seconds and returns the finished result if it lands in time; otherwise hands back import_id with is_finalized: false for check_design_import_status to poll.
Mutates state — creates a new design or template. Scope import:design · role Admin, Manager, or Designer
| Parameter | Type | Required | Description |
|---|---|---|---|
payload | object | Yes | The design to create, in the shape get_design_as_import returns. |
validate_only | boolean | No | Check the payload without creating anything. |
strict | boolean, default false | No | When true, a text layer that cannot fit its box even at its minimum font size makes the import fail (you see FAILED / text_fit_failed when checking the import status) instead of importing with a warning. |
wait_for_result | boolean, default true | No | false skips the internal wait and returns the id immediately. |
payload.target says where the import lands: {"kind": "design", "project_uuid": "…"} creates a design in that project (the default, and project_uuid is required for it), while {"kind": "workspace_template"} creates a reusable workspace template, which has no project.
How to supply an image
payload images can be (1) an already-hosted https URL — preferred, atomic; (2) an inline data:image/…;base64,… URI, atomic — larger ones are accepted, but keeping each to 100 KB or less is recommended; or (3) a bare filename for a file on the caller's own machine, which is not atomic — it returns WAITING_FOR_VALIDATION with one presigned upload command per layer, and only resolves once those uploads run. Prefer (1) or (2) whenever possible.
With (3), a layer must use the same file across all its formats; use https URLs if a layer needs a different image per format.
Example
// Call
{ "payload": { "name": "New banner", "type": "static", "formats": ["…"] } }// Result — created immediately
{
"import_id": "f6a8b0c2-5e70-4b82-ac3d-6e7f8a9b0c1d",
"status": "DONE",
"is_finalized": true,
"name": "New banner",
"warnings": [],
"result": { "kind": "design", "uuid": "a1b2c3d4-...", "project_uuid": "1a2b3c4d-..." }
}// Result — waiting on a local-file upload
{
"import_id": "f6a8b0c2-5e70-4b82-ac3d-6e7f8a9b0c1d",
"status": "WAITING_FOR_VALIDATION",
"is_finalized": false,
"warnings": [],
"uploads": [
{
"layer_name": "background",
"max_bytes": 5000000,
"upload_command": "curl -sf -F 'key=...' -F 'policy=...' -F 'file=@<LOCAL_FILE_PATH>' https://s3.amazonaws.com/..."
}
]
}check_design_import_status
Check the status of a design import started by import_design_from_json.
status | Meaning |
|---|---|
WAITING_FOR_VALIDATION | At least one image upload command hasn't been run yet. Run it, then check again: calling this tool once the files are uploaded is what starts processing. |
QUEUED, PROCESSING | Still going — check again later. |
DONE | Finished: result.uuid is the created design's id. |
FAILED | Finished with an error: error has the reason. |
DONE and FAILED come with is_finalized: true.
Re-checks a waiting import (starts processing once uploaded files are in); costs nothing · scope import:design (same scope as the tool it polls) · role Admin, Manager, or Designer
| Parameter | Type | Required | Description |
|---|---|---|---|
import_id | string, min 1 char | Yes | The id returned by import_design_from_json. |
Example
// Result
{
"import_id": "f6a8b0c2-5e70-4b82-ac3d-6e7f8a9b0c1d",
"status": "DONE",
"is_finalized": true,
"warnings": [],
"result": { "kind": "design", "uuid": "a1b2c3d4-...", "project_uuid": "1a2b3c4d-..." }
}Upload commands from import_design_from_json stay valid for one hour from when the import was created; after that the import is dead and has to be started over.
Design editing
Change or remove a design that already exists. Creating one is import_design_from_json's job. Every tool here needs a role that can manage designs, plus access to the design's project. A design you can't open fails with template_not_found, the same as an id that doesn't exist.
rename_design
Rename a design. Only the name changes: layers, formats and generated banners stay as they are.
Mutates state. Scope write:design · role Admin, Manager, or Designer
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
name | string, 1–100 characters | Yes | The new name. Leading and trailing spaces are removed. |
Example
// Call
{ "design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b", "name": "Black Friday banner — final" }// Result
{ "id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b", "name": "Black Friday banner — final" }move_design
Move a design to another project in the same workspace. The design keeps its id, content and generated banners, but its review/approval status is reset. Moving a design to the project it's already in changes nothing.
Destructive — resets the design's review/approval status. Scope write:design · role Admin, Manager, or Designer, with access to both the current project and the destination
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
project_id | string, min 1 char | Yes | Destination project id from list_projects. |
Example
// Call
{ "design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b", "project_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e" }// Result
{
"id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b",
"name": "Black Friday banner",
"project_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e"
}If you can't open the destination project, including a private project you aren't a member of, the call fails with project_not_found. That's the same rule list_projects applies, so any project it lists is a valid destination.
delete_design
Permanently delete a design. You can't undo a deletion through the MCP server, so the tool asks the model to confirm with you, naming the design, before it runs. Banners already generated from the design are kept.
Destructive. Scope delete:design · role Admin, Manager, or Designer
| Parameter | Type | Required | Description |
|---|---|---|---|
design_id | string, min 1 char | Yes | Design id from list_designs or search_designs. |
Example
// Call
{ "design_id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b" }// Result
{ "id": "8f2c1a3e-4b5d-4e6f-9a8b-7c6d5e4f3a2b", "name": "Black Friday banner" }| Error | Cause |
|---|---|
design_in_open_product | The design is attached to a product that isn't closed. |
template_not_found | The design doesn't exist, was already deleted, or is in a project you can't open. |
role_access_denied | Your role on the workspace can't manage designs. |
