{
  "openapi": "3.0.0",
  "info": {
    "version": "1.0.0",
    "title": "Ditto API",
    "description": "Programmatically read and write data in your Ditto workspace."
  },
  "servers": [
    {
      "url": "https://api.dittowords.com/v2"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization"
      }
    },
    "schemas": {},
    "parameters": {}
  },
  "paths": {
    "/components": {
      "get": {
        "tags": ["Components"],
        "description": "Returns a list of components in your workspace.",
        "summary": "Fetch components",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Stringified JSON filter object. Supports the following filter fields:\n- `folders`: array of objects with `id` (folder developer ID or `root` for root-level components) and optional `excludeNestedFolders` (boolean)\n- `variants`: array of objects with `id` (variant developer ID, `base`, or `all`)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned components, or `null` for unassigned\n- `integrated`: boolean value to filter by components that are or are not marked as integrated into development\n\nBy default, only base text will be returned. Provide a variants filter to specify which variants of the filtered components to include.\n\nWhen pairing variants with a status or assignee filter, variant data will only be returned if both the base and variant status/assignee match the filter.\n\nBy default, folder filters search for components in that folder and its folder children. To skip searching folder children for a given folder, set `excludeNestedFolders` to `true`.\n\nExample: `{\"folders\":[{\"id\":\"folder-id\"}, {\"id\":\"folder-id-2\", \"excludeNestedFolders\":true}], \"variants\":[{\"id\":\"french\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\",\"tag-2\"],\"operator\":\"AND\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`"
            },
            "required": false,
            "description": "Stringified JSON filter object. Supports the following filter fields:\n- `folders`: array of objects with `id` (folder developer ID or `root` for root-level components) and optional `excludeNestedFolders` (boolean)\n- `variants`: array of objects with `id` (variant developer ID, `base`, or `all`)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned components, or `null` for unassigned\n- `integrated`: boolean value to filter by components that are or are not marked as integrated into development\n\nBy default, only base text will be returned. Provide a variants filter to specify which variants of the filtered components to include.\n\nWhen pairing variants with a status or assignee filter, variant data will only be returned if both the base and variant status/assignee match the filter.\n\nBy default, folder filters search for components in that folder and its folder children. To skip searching folder children for a given folder, set `excludeNestedFolders` to `true`.\n\nExample: `{\"folders\":[{\"id\":\"folder-id\"}, {\"id\":\"folder-id-2\", \"excludeNestedFolders\":true}], \"variants\":[{\"id\":\"french\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\",\"tag-2\"],\"operator\":\"AND\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`",
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["html", "html_paragraphs"],
              "description": "When set to `html` or `html_paragraphs`, includes HTML-formatted rich text in the response.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks."
            },
            "required": false,
            "description": "When set to `html` or `html_paragraphs`, includes HTML-formatted rich text in the response.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks.",
            "name": "richText",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of components matching the filter criteria",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The Developer ID of the component"
                      },
                      "text": {
                        "type": "string",
                        "description": "The plaintext content of the component. Returns the variant's text when variantId is not null."
                      },
                      "richText": {
                        "type": "string",
                        "description": "If a `richText` parameter is provided, this field contains the HTML-formatted version of the text, generated according to the specified format option. Not present if `richText` is omitted."
                      },
                      "notes": {
                        "type": "string",
                        "description": "The notes on the component. Returns the variant's notes when variantId is not null."
                      },
                      "characterLimit": {
                        "type": "number",
                        "nullable": true,
                        "description": "The character limit set on this component, or null if no limit is set. Returns the variant's character limit when variantId is not null."
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Array of tags associated with the component. Returns the base tags value in all responses; variants do not have their own tags."
                      },
                      "integrated": {
                        "type": "boolean",
                        "description": "Whether this component has been marked as integrated into development"
                      },
                      "variableIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Array of Developer IDs of variables used in this base or variant text"
                      },
                      "variantId": {
                        "type": "string",
                        "nullable": true,
                        "description": "The Developer ID of this variant, or null for base text"
                      },
                      "pluralForm": {
                        "type": "string",
                        "nullable": true,
                        "enum": ["one", "two", "few", "many", "zero", "other", null]
                      },
                      "folderId": {
                        "type": "string",
                        "nullable": true,
                        "description": "The Developer ID of the folder this component belongs to"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the component"
                      },
                      "status": {
                        "type": "string",
                        "description": "The status of the component. Returns the variant's status when variantId is not null. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                      },
                      "assignee": {
                        "type": "string",
                        "nullable": true,
                        "format": "email",
                        "description": "The email of the user assigned to this component, or null if unassigned. Returns the variant's assignee when variantId is not null."
                      }
                    },
                    "required": [
                      "id",
                      "text",
                      "notes",
                      "characterLimit",
                      "tags",
                      "integrated",
                      "variableIds",
                      "variantId",
                      "pluralForm",
                      "folderId",
                      "name",
                      "status",
                      "assignee"
                    ]
                  },
                  "example": [
                    {
                      "id": "component-item-dev-id",
                      "name": "Component Name",
                      "text": "Base text",
                      "status": "NONE",
                      "notes": "base notes",
                      "tags": ["baseTag1", "baseTag2"],
                      "assignee": "john@example.com",
                      "integrated": true,
                      "variableIds": [],
                      "folderId": "folder-dev-id",
                      "variantId": null,
                      "richText": "<strong>Base</strong> text"
                    },
                    {
                      "id": "component-item-dev-id",
                      "name": "Component Name",
                      "text": "French text",
                      "status": "WIP",
                      "notes": "base notes",
                      "tags": ["baseTag1", "baseTag2"],
                      "assignee": "john@example.com",
                      "integrated": true,
                      "variableIds": ["age", "name"],
                      "folderId": "folder-dev-id",
                      "variantId": "french",
                      "richText": "<em>French</em> text"
                    },
                    {
                      "id": "component-item-dev-id-2",
                      "name": "Component Name 2",
                      "text": "Some base text",
                      "status": "FINAL",
                      "notes": "base notes",
                      "tags": ["baseTag1", "baseTag2"],
                      "assignee": null,
                      "integrated": false,
                      "variableIds": ["age", "name"],
                      "folderId": null,
                      "variantId": null,
                      "richText": "Some <strong>base</strong> text"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Components"],
        "description": "Creates one or more library components in your workspace.\n\nThe operation is all-or-nothing: if any component is invalid, none are created.",
        "summary": "Create components",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "richText": {
                    "type": "string",
                    "enum": ["html"],
                    "description": "When set to 'html', all `text` values in this request (including plural and variant text) are parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup (for example links, lists, or headings) is dropped and its text content kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWhen omitted, text is saved as plaintext and any markup is stored literally."
                  },
                  "components": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "Optional preconfigured developer ID for the component. Must be unique within the workspace. If omitted, system will generate one automatically."
                        },
                        "text": {
                          "type": "string",
                          "description": "The component's text value"
                        },
                        "notes": {
                          "type": "string",
                          "nullable": true,
                          "description": "Optional notes for the component. Use null or omit to leave notes empty."
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Optional list of tags to assign to the component. Omit or pass an empty array for no tags."
                        },
                        "status": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Optional status for the component (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). Cannot be empty string. If omitted, defaults to 'NONE'. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                        },
                        "assignee": {
                          "type": "string",
                          "format": "email",
                          "description": "Optional email of the workspace user to assign to this component."
                        },
                        "characterLimit": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 1,
                          "description": "Optional character limit for the component text. Use null or omit to indicate no limit."
                        },
                        "integrated": {
                          "type": "boolean",
                          "description": "Mark the component as integrated into development. If omitted, defaults to false."
                        },
                        "variables": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Developer IDs of variables (the `id` field from GET /v2/variables) used in this component's text, plurals, or variants. Text fields support `{{variable_name}}` placeholders that will be resolved using the variables listed here. Placeholders whose names are not in this list are kept as literal text."
                        },
                        "plurals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "form": {
                                "type": "string",
                                "enum": ["one", "two", "few", "many", "zero", "other"],
                                "description": "The plural form"
                              },
                              "text": {
                                "type": "string",
                                "description": "The text for this plural form"
                              }
                            },
                            "required": ["form", "text"]
                          },
                          "description": "Optional plural forms for the component. The first plural form's text must match the component's display text. Each form may only appear once."
                        },
                        "variants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "variantId": {
                                "type": "string",
                                "description": "Developer ID of the variant"
                              },
                              "text": {
                                "type": "string",
                                "description": "The text for this variant"
                              },
                              "status": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Optional status for the component variant (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). Cannot be empty string. If omitted, defaults to 'NONE'. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                              },
                              "assignee": {
                                "type": "string",
                                "format": "email",
                                "description": "Optional email of the user to assign to this component variant."
                              },
                              "characterLimit": {
                                "type": "number",
                                "nullable": true,
                                "minimum": 1,
                                "description": "Optional character limit for the component variant text. Use null or omit to indicate no limit."
                              },
                              "notes": {
                                "type": "string",
                                "nullable": true,
                                "description": "Optional notes for the component variant. Use null or omit to leave notes empty."
                              },
                              "plurals": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "form": {
                                      "type": "string",
                                      "enum": ["one", "two", "few", "many", "zero", "other"],
                                      "description": "The plural form"
                                    },
                                    "text": {
                                      "type": "string",
                                      "description": "The text for this plural form"
                                    }
                                  },
                                  "required": ["form", "text"]
                                },
                                "description": "Optional plural forms for this variant"
                              }
                            },
                            "required": ["variantId", "text"]
                          },
                          "description": "Optional variant text values to set on the component at creation time. Each variantId must correspond to an existing variant in the workspace."
                        },
                        "name": {
                          "type": "string",
                          "description": "The name of the component"
                        },
                        "folderId": {
                          "type": "string",
                          "description": "The developer ID of the folder to add the component to. If omitted, the component will be added to the root folder."
                        }
                      },
                      "required": ["text", "name"]
                    },
                    "description": "Array of components to create"
                  }
                },
                "required": ["components"],
                "example": {
                  "components": [
                    {
                      "text": "Hello world",
                      "name": "Component One"
                    },
                    {
                      "developerId": "custom-id",
                      "text": "Custom ID example",
                      "name": "Custom Component",
                      "notes": "For the homepage CTA",
                      "characterLimit": 80
                    },
                    {
                      "text": "In folder",
                      "name": "Folder Component",
                      "folderId": "my-folder-id"
                    },
                    {
                      "text": "{{count}} items in your cart",
                      "name": "Cart Count",
                      "variables": ["count"],
                      "plurals": [
                        {
                          "form": "one",
                          "text": "{{count}} item in your cart"
                        },
                        {
                          "form": "other",
                          "text": "{{count}} items in your cart"
                        }
                      ]
                    },
                    {
                      "text": "Hello world",
                      "name": "Localized Component",
                      "variants": [
                        {
                          "variantId": "french",
                          "text": "Bonjour le monde"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer IDs of the created components",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Array of developer IDs for the created components"
                    }
                  },
                  "required": ["developerIds"],
                  "example": {
                    "developerIds": ["component-one", "custom-id", "folder-component"]
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Components"],
        "description": "Updates a set of components' base or variant text, plural forms, tags, status, assignee, notes, character limit, integrated, and variables.\n\nEach component is identified by its developer ID. Only provided fields are modified — omitted fields remain unchanged.\n\nA developer ID can appear at most once in `updates`. A request that repeats a developer ID is rejected with a 400 rather than silently applying the last write and discarding the rest — combine the changes into a single update instead.",
        "summary": "Update components",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variantId": {
                    "type": "string",
                    "description": "Developer ID of the target variant. If a component does not already have the target variant, it will be added. Omit if targeting base text."
                  },
                  "forceVariantCreation": {
                    "type": "boolean",
                    "description": "If true, and the provided variantId is not found, create the variant. A variant name will be generated based on the passed in ID."
                  },
                  "richText": {
                    "type": "string",
                    "enum": ["html"],
                    "description": "When set to 'html', all `text` values in this request (including plural text) are parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup (for example links, lists, or headings) is dropped and its text content kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWhen omitted, text is saved as plaintext and any markup is stored literally."
                  },
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The component's developer ID"
                        },
                        "text": {
                          "type": "string",
                          "description": "The text the component will be updated to. Text will remain unchanged if unset. **Note:** Cannot be combined with plurals in the same update object. To update both the display text and other plural forms at once, include the first plural form in the plurals upsert array instead."
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The set of tags that will be set on this component. Other tags will be removed. If unset tags will remain unchanged."
                        },
                        "status": {
                          "type": "string",
                          "description": "The status to set on this component (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). If not provided, status will remain unchanged. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                        },
                        "assignee": {
                          "type": "string",
                          "nullable": true,
                          "format": "email",
                          "description": "The email of the user to assign to the component. If null the assignee will be removed. If not provided, assignee will remain unchanged."
                        },
                        "integrated": {
                          "type": "boolean",
                          "description": "Mark the component as integrated or not integrated into development. If not provided, integration status will remain unchanged."
                        },
                        "notes": {
                          "type": "string",
                          "nullable": true,
                          "description": "Notes for the component. Use null or empty string to clear notes. If not provided, notes will remain unchanged."
                        },
                        "characterLimit": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 1,
                          "description": "Character limit for the component. Use null to remove the limit. If not provided, character limit will remain unchanged."
                        },
                        "variables": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Developer IDs of variables (the `id` field from GET /v2/variables) used in this update's text or plurals. Text fields support `{{variable_name}}` placeholders that will be resolved using the variables listed here. Placeholders whose names are not in this list are kept as literal text."
                        },
                        "plurals": {
                          "type": "object",
                          "properties": {
                            "upsert": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "form": {
                                    "type": "string",
                                    "enum": ["one", "two", "few", "many", "zero", "other"],
                                    "description": "The plural form"
                                  },
                                  "text": {
                                    "type": "string",
                                    "description": "The text for this plural form"
                                  }
                                },
                                "required": ["form", "text"]
                              },
                              "description": "Array of plural forms to create or update. If a plural with the given form already exists, its text will be updated. Otherwise, a new plural will be created. Each form may only appear once in the array."
                            },
                            "remove": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": ["one", "two", "few", "many", "zero", "other"]
                              },
                              "description": "Array of plural forms to remove from the text item. Each form may only appear once. A form cannot appear in both upsert and remove."
                            }
                          },
                          "description": "Optional plural form updates. Existing plural forms not mentioned in either upsert or remove are preserved. The order of plurals matters: the first plural form is the 'master' value whose text is used as the text item's display text. New plurals are appended after existing ones. If you need to change which plural is first, remove and re-add them in the desired order."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "description": "A new developer ID for this component. Must be unique within the workspace. Can be set alongside other field changes in the same update object."
                        },
                        "folderId": {
                          "type": "string",
                          "nullable": true,
                          "description": "The developer ID of the folder to move this component into. Provide null or \"root\" to move it to the library root (All Components). Omit to leave the component's folder unchanged."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "minItems": 1,
                    "description": "Array of updates to components."
                  }
                },
                "required": ["updates"],
                "example": {
                  "variantId": "french",
                  "updates": [
                    {
                      "developerId": "component-id-1",
                      "text": "Updated text",
                      "status": "REVIEW"
                    }
                  ]
                }
              },
              "examples": {
                "update_base_text": {
                  "summary": "Update base text",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "text": "Hello!"
                      }
                    ]
                  }
                },
                "update_variant_text": {
                  "summary": "Update variant text",
                  "value": {
                    "variantId": "french",
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "text": "Bonjour!"
                      }
                    ]
                  }
                },
                "update_with_variables": {
                  "summary": "Update text with variable placeholders",
                  "description": "Use `{{variable_name}}` placeholders in the text and list the variable developer IDs in `variables`. Variables not in the list are kept as literal text.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "text": "Hello, {{user_name}}!",
                        "variables": ["user_name"]
                      }
                    ]
                  }
                },
                "update_with_rich_text": {
                  "summary": "Update text with HTML rich text",
                  "description": "Set `richText` to `html` to have every `text` value in the request parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup such as links, lists, or headings is dropped while its text content is kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWithout this flag, markup is saved as plaintext.",
                  "value": {
                    "richText": "html",
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "text": "<strong>Updated</strong> text"
                      }
                    ]
                  }
                },
                "update_status": {
                  "summary": "Update status",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "status": "FINAL"
                      },
                      {
                        "developerId": "component-id-2",
                        "status": "REVIEW"
                      }
                    ]
                  }
                },
                "update_notes_and_limit": {
                  "summary": "Update notes and character limit",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "notes": "Keep this under the character limit",
                        "characterLimit": 60
                      }
                    ]
                  }
                },
                "update_assignee": {
                  "summary": "Update assignee",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "assignee": "john@example.com"
                      },
                      {
                        "developerId": "component-id-2",
                        "assignee": null
                      }
                    ]
                  }
                },
                "update_tags": {
                  "summary": "Update tags",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "tags": ["tag-1", "tag-2"]
                      }
                    ]
                  }
                },
                "add_plurals": {
                  "summary": "Add plural forms",
                  "value": {
                    "updates": [
                      {
                        "developerId": "component-id-1",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "item"
                            },
                            {
                              "form": "other",
                              "text": "items"
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a developer ID that does not match any existing component, a variant ID that does not exist (when forceVariantCreation is not set), an assignee email that does not correspond to a workspace member, a variable name not found in the workspace, or providing both `text` and `plurals` in the same update object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    },
                    "details": {
                      "type": "object",
                      "description": "Optional additional error details"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Component with developer ID \"component-id-1\" not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Components"],
        "description": "Deletes library components from the workspace by their developer IDs.",
        "summary": "Delete components",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "developerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of developer IDs for the library components to delete. Text items attached to a deleted component are not deleted — they are detached from that component and remain in their project as standalone text items."
                  }
                },
                "required": ["developerIds"],
                "example": {
                  "developerIds": ["component-id-1", "component-id-2"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a developer ID does not match any existing component in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Component with developer ID \"component-id-1\" not found"
                }
              }
            }
          }
        }
      }
    },
    "/components/export": {
      "get": {
        "tags": ["Components"],
        "description": "Returns components in your workspace in the provided format.",
        "summary": "Export components",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Stringified JSON filter object. Supports the following filter fields:\n- `folders`: array of objects with `id` (folder developer ID or `root` for root-level components) and optional `excludeNestedFolders` (boolean)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned components, or `null` for unassigned\n- `integrated`: boolean value to filter by components that are or are not marked as integrated into development\n\nBy default, folder filters search for components in that folder and its folder children. To skip searching folder children for a given folder, set `excludeNestedFolders` to `true`.\n\nExample: `{\"folders\":[{\"id\":\"folder-id\"},{\"id\":\"folder-id-2\",\"excludeNestedFolders\":true}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\"],\"operator\":\"OR\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`"
            },
            "required": false,
            "description": "Stringified JSON filter object. Supports the following filter fields:\n- `folders`: array of objects with `id` (folder developer ID or `root` for root-level components) and optional `excludeNestedFolders` (boolean)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned components, or `null` for unassigned\n- `integrated`: boolean value to filter by components that are or are not marked as integrated into development\n\nBy default, folder filters search for components in that folder and its folder children. To skip searching folder children for a given folder, set `excludeNestedFolders` to `true`.\n\nExample: `{\"folders\":[{\"id\":\"folder-id\"},{\"id\":\"folder-id-2\",\"excludeNestedFolders\":true}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\"],\"operator\":\"OR\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`",
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["html", "html_paragraphs"],
              "description": "When set to `html` or `html_paragraphs`, returns HTML-formatted rich text instead of plain text.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks."
            },
            "required": false,
            "description": "When set to `html` or `html_paragraphs`, returns HTML-formatted rich text instead of plain text.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks.",
            "name": "richText",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "By default, base text will be returned. Provide a variant parameter to specify which variant of the filtered base text items to return."
            },
            "required": false,
            "description": "By default, base text will be returned. Provide a variant parameter to specify which variant of the filtered base text items to return.",
            "name": "variantId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["json_icu", "json_i18next", "json_vue_i18n", "ios-strings", "ios-stringsdict", "android", "arb"],
              "description": "Output format for exported components."
            },
            "required": true,
            "description": "Output format for exported components.",
            "name": "format",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["default", "alphabetical"],
              "description": "Order in which variables are indexed in positional format exports (`ios-strings`, `ios-stringsdict`, `android`). \"alphabetical\" assigns indices by variable name (a=1, b=2, ...); \"default\" preserves the existing creation-order assignment."
            },
            "required": false,
            "description": "Order in which variables are indexed in positional format exports (`ios-strings`, `ios-stringsdict`, `android`). \"alphabetical\" assigns indices by variable name (a=1, b=2, ...); \"default\" preserves the existing creation-order assignment.",
            "name": "variableSort",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": ["true"],
                  "title": "true"
                },
                {
                  "type": "string",
                  "enum": ["false"],
                  "title": "false"
                }
              ],
              "description": "When `true`, omits the `__variant-name` and `__variant-description` keys from variant exports in JSON formats (`json_i18next`, `json_vue_i18n`, `json_icu`). Defaults to `false`. Has no effect on any other formats nor any base text (non-variant) exports, which never include these keys."
            },
            "required": false,
            "description": "When `true`, omits the `__variant-name` and `__variant-description` keys from variant exports in JSON formats (`json_i18next`, `json_vue_i18n`, `json_icu`). Defaults to `false`. Has no effect on any other formats nor any base text (non-variant) exports, which never include these keys.",
            "name": "excludeVariantMetadata",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": ["true"],
                  "title": "true"
                },
                {
                  "type": "string",
                  "enum": ["false"],
                  "title": "false"
                }
              ],
              "description": "When `true`, adds a `__variables_used` key to `json_i18next` and `json_vue_i18n` exports: a deduplicated, alphabetical array of the names of the variables used in the exported strings. Defaults to `false`. Has no effect on other formats."
            },
            "required": false,
            "description": "When `true`, adds a `__variables_used` key to `json_i18next` and `json_vue_i18n` exports: a deduplicated, alphabetical array of the names of the variables used in the exported strings. Defaults to `false`. Has no effect on other formats.",
            "name": "includeVariableSummary",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns components matching the filter criteria in the provided format",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "For `json_icu`, `json_i18next`, `json_vue_i18n` formats, object keys are developer-ids (strings) and values are text (strings). Variant exports in these formats also include `__variant-name` and `__variant-description` keys (strings) unless `excludeVariantMetadata=true`. When `includeVariableSummary=true`, `json_i18next` and `json_vue_i18n` exports also include a `__variables_used` key, whose value is an array of variable names. For `arb`, values are text (strings) except for the optional top-level `@@locale` key (string) and `@<developer-id>` metadata keys, which are objects.",
                  "additionalProperties": {
                    "oneOf": [
                      {
                        "type": "string",
                        "title": "Text",
                        "description": "The text value for the developer-id key, the `__variant-name`/`__variant-description` value for variant exports, or the `@@locale` value for `arb` exports"
                      },
                      {
                        "type": "object",
                        "title": "Metadata",
                        "description": "ARB metadata for a `@<developer-id>` key: optional `description` (from the text item's notes) and/or `placeholders` (variable name to ARB type).",
                        "properties": {
                          "description": {
                            "type": "string"
                          },
                          "placeholders": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      {
                        "type": "array",
                        "title": "Variables used",
                        "description": "The `__variables_used` value when `includeVariableSummary=true`: a deduplicated, alphabetical array of the names of the variables used in the export (`json_i18next` and `json_vue_i18n` only)",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "example": {
                    "@@locale": "en",
                    "component-item-dev-id": "<em>Some other</em> text",
                    "component-item-dev-id-2": "Some <strong>base</strong> text",
                    "@component-item-dev-id-2": {
                      "placeholders": {
                        "username": {
                          "type": "String"
                        }
                      }
                    }
                  }
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "For iOS .strings format",
                  "example": "\"component-dev-id-continue\" = \"Continue\";"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "For Android .xml and iOS .stringsdict formats",
                  "example": "<string name=\"continue-dev-id\" ditto_api_id=\"continue-dev-id\">Continue</string>"
                }
              }
            }
          },
          "400": {
            "description": "Error for when variantId is not found, format is incorrect, or one or more filters are invalid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message indicating incorrect parameters"
                    },
                    "details": {
                      "type": "object",
                      "description": "Optional additional error details"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Variant with id \"<variantId>\" not found"
                }
              }
            }
          }
        }
      }
    },
    "/components/publish": {
      "post": {
        "tags": ["Components"],
        "description": "Publishes an existing project text item to the component library, turning it into a reusable library component.\n\nThe text item's current text, variables, variants, and other fields are carried over to the new component, and the text item becomes its first linked instance. The new component keeps the text item's existing developer ID. The text item must not already be a library instance.",
        "summary": "Publish a text item to the library",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "textItemId": {
                    "type": "string",
                    "description": "Developer ID of the text item to publish. It must not already be a library instance."
                  },
                  "name": {
                    "type": "string",
                    "description": "The name of the new library component."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The developer ID of the folder to add the component to. If omitted, the component will be added to the library root."
                  }
                },
                "required": ["textItemId", "name"],
                "example": {
                  "textItemId": "text-item-id-1",
                  "name": "New Component",
                  "folderId": "my-folder-id"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer ID of the newly created library component",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerId": {
                      "type": "string",
                      "description": "Developer ID of the newly created library component. This is the same developer ID the text item had before publishing."
                    }
                  },
                  "required": ["developerId"],
                  "example": {
                    "developerId": "text-item-id-1"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the text item developer ID does not match any existing text item, the text item is already a library instance, or the folder ID does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "1 text item with developer ID text-item-id-1 not found"
                }
              }
            }
          }
        }
      }
    },
    "/components/link": {
      "patch": {
        "tags": ["Components"],
        "description": "Links one or more existing text items to an existing library component by developer ID, so they share the component's text going forward.\n\nEach linked text item takes on the component's current text, variables, variants, and other fields. Text items already linked to a different component are skipped.",
        "summary": "Link text items to a component",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "componentId": {
                    "type": "string",
                    "description": "Developer ID of the library component to link text items to."
                  },
                  "textItemIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the text items to link to this component. Text items already linked to a different component are skipped."
                  }
                },
                "required": ["componentId", "textItemIds"],
                "example": {
                  "componentId": "component-id-1",
                  "textItemIds": ["text-item-id-1", "text-item-id-2"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the link operation, the number of text items actually linked, and the developer IDs of any that were skipped because they're already linked to a different component",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the link operation was successful"
                    },
                    "linkedCount": {
                      "type": "number",
                      "description": "The number of text items actually linked to the component."
                    },
                    "skippedDeveloperIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Developer IDs from the request that were skipped because they're already linked to a different component."
                    }
                  },
                  "required": ["success", "linkedCount", "skippedDeveloperIds"],
                  "example": {
                    "success": true,
                    "linkedCount": 2,
                    "skippedDeveloperIds": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the component developer ID or a text item developer ID does not match any existing component or text item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Component with developer ID component-id-1 not found"
                }
              }
            }
          }
        }
      }
    },
    "/components/unlink": {
      "patch": {
        "tags": ["Components"],
        "description": "Unlinks one or more text items from their library component by developer ID.\n\nEach unlinked text item keeps its current text but gets a freshly generated developer ID, and future edits to the library component no longer affect it. Every text item linked to a component shares that component's developer ID with its sibling instances, so a given developer ID unlinks every text item that currently carries it, not just one. Pass `projectId` to scope the unlink to only the instances in one project, leaving instances elsewhere untouched.",
        "summary": "Unlink text items from a component",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "textItemIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the text items to unlink from their library component. Each must currently be a library instance. Every text item linked to a component shares that component's developer ID with its sibling instances, so a given developer ID unlinks every text item that currently carries it, not just one — scope this with projectId to affect only the instances in one project."
                  },
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the project to scope the unlink to. If provided, only instances of the given developer IDs within this project are unlinked; instances in other projects are left untouched. If omitted, every instance of each given developer ID is unlinked, regardless of project."
                  }
                },
                "required": ["textItemIds"],
                "example": {
                  "textItemIds": ["text-item-id-1", "text-item-id-2"]
                }
              },
              "examples": {
                "unlink_all_instances": {
                  "summary": "Unlink every instance of a developer ID",
                  "value": {
                    "textItemIds": ["text-item-id-1"]
                  }
                },
                "unlink_scoped_to_project": {
                  "summary": "Unlink only the instances in one project",
                  "description": "Only instances of the given developer IDs within this project are unlinked; instances elsewhere are left untouched.",
                  "value": {
                    "textItemIds": ["text-item-id-1"],
                    "projectId": "my-project-id"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the unlink operation and the number of text items actually unlinked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the unlink operation was successful"
                    },
                    "unlinkedCount": {
                      "type": "number",
                      "description": "The number of text items actually unlinked. This can exceed the number of developer IDs given, since every instance sharing a given developer ID is unlinked."
                    }
                  },
                  "required": ["success", "unlinkedCount"],
                  "example": {
                    "success": true,
                    "unlinkedCount": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a text item developer ID does not match any existing text item in scope (or, if projectId was given, no instance of it exists in that project), or the text item is not linked to a library component",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Text items are not linked to a library component: text-item-id-1"
                }
              }
            }
          }
        }
      }
    },
    "/componentFolders": {
      "get": {
        "tags": ["Component Folders"],
        "description": "Returns all folders in your component library, with their developer IDs, names, and parent folder (by developer ID; null when the folder sits directly under the library root).\n\nFolders are a separate namespace from project folders.",
        "summary": "Fetch component folders",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of all folders in the component library",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The developer ID of the folder"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the folder"
                      },
                      "parentId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Developer ID of the parent folder, or null if the folder sits directly under the library root"
                      }
                    },
                    "required": ["id", "name", "parentId"]
                  },
                  "example": [
                    {
                      "id": "inputs",
                      "name": "Inputs",
                      "parentId": null
                    },
                    {
                      "id": "text-fields",
                      "name": "Text Fields",
                      "parentId": "inputs"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Component Folders"],
        "description": "Creates one or more folders in the component library.",
        "summary": "Create component folders",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folders": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "The name of the new folder"
                        },
                        "developerId": {
                          "type": "string",
                          "description": "Optional preconfigured developer ID for the folder. Must be unique within the workspace. If omitted, one is generated automatically from the name."
                        },
                        "parentId": {
                          "type": "string",
                          "description": "Developer ID of the parent folder to nest the new folder inside (from list_component_folders). Omit or set to \"root\" to create the folder at the library root."
                        }
                      },
                      "required": ["name"]
                    },
                    "minItems": 1,
                    "description": "Array of new folders to create"
                  }
                },
                "required": ["folders"],
                "example": {
                  "folders": [
                    {
                      "name": "Inputs"
                    },
                    {
                      "name": "Text Fields",
                      "developerId": "text-fields",
                      "parentId": "inputs"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer IDs of the created folders, in request order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Array of developer IDs for the created folders, in request order"
                    }
                  },
                  "required": ["developerIds"],
                  "example": {
                    "developerIds": ["inputs", "text-fields"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a parentId not matching any existing folder in the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Folder id not found"
                }
              }
            }
          },
          "409": {
            "description": "Returned when a supplied developer ID already exists in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the conflict"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "already exists in workspace"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Component Folders"],
        "description": "Updates a set of component folders.\n\nEach folder is identified by its developer ID. Only provided fields are modified — omitted fields remain unchanged.",
        "summary": "Update component folders",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The folder's current developer ID"
                        },
                        "name": {
                          "type": "string",
                          "description": "New name for the folder. If not provided, name remains unchanged."
                        },
                        "parentId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Developer ID of the folder to move this folder into. Provide null or \"root\" to move it to the library root. Omit to leave the folder's parent unchanged."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "description": "A new developer ID for this folder. Must be unique within the workspace. Can be set alongside a name or parent change in the same update object."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "minItems": 1,
                    "description": "Array of updates to folders"
                  }
                },
                "required": ["updates"],
                "example": {
                  "updates": [
                    {
                      "developerId": "text-fields",
                      "name": "Inputs — Text Fields"
                    }
                  ]
                }
              },
              "examples": {
                "rename_folder": {
                  "summary": "Rename a folder",
                  "value": {
                    "updates": [
                      {
                        "developerId": "text-fields",
                        "name": "Inputs — Text Fields"
                      }
                    ]
                  }
                },
                "move_folder": {
                  "summary": "Move a folder to a new parent",
                  "value": {
                    "updates": [
                      {
                        "developerId": "text-fields",
                        "parentId": "inputs"
                      }
                    ]
                  }
                },
                "move_to_root": {
                  "summary": "Move a folder to the library root",
                  "value": {
                    "updates": [
                      {
                        "developerId": "text-fields",
                        "parentId": null
                      }
                    ]
                  }
                },
                "update_developer_id": {
                  "summary": "Change a folder's developer ID",
                  "value": {
                    "updates": [
                      {
                        "developerId": "text-fields",
                        "newDeveloperId": "input-fields"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a developer ID that does not match any existing folder in the workspace, a parentId that does not match any existing folder, or a parent move that would create a circular folder hierarchy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Folder id not found"
                }
              }
            }
          },
          "409": {
            "description": "Returned when a supplied newDeveloperId already exists in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the conflict"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "already exists in workspace"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Component Folders"],
        "description": "Deletes folders from the component library.",
        "summary": "Delete component folders",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "developerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the folders to delete. Components and subfolders inside a deleted folder are moved to its parent folder (or the library root), not deleted."
                  }
                },
                "required": ["developerIds"],
                "example": {
                  "developerIds": ["text-fields"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a developer ID does not match any existing folder in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Folder id not found"
                }
              }
            }
          }
        }
      }
    },
    "/projects": {
      "get": {
        "tags": ["Projects"],
        "description": "Returns a list of Ditto projects in your workspace.",
        "summary": "Fetch projects",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of projects in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The Developer ID of the project"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the project"
                      },
                      "baseId": {
                        "type": "string",
                        "nullable": true,
                        "description": "The Developer ID of the base the project is connected to, or null if not connected to a base"
                      }
                    },
                    "required": ["id", "name", "baseId"]
                  },
                  "example": [
                    {
                      "id": "my-first-project",
                      "name": "My First Project",
                      "baseId": "my-base"
                    },
                    {
                      "id": "my-second-project",
                      "name": "My Second Project",
                      "baseId": "my-base"
                    },
                    {
                      "id": "project-in-folder",
                      "name": "Project in Folder",
                      "baseId": "another-base"
                    },
                    {
                      "id": "standalone-project",
                      "name": "Standalone Project",
                      "baseId": null
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Projects"],
        "description": "Creates a new Ditto project in your workspace.\n\nProjects hold project-scoped text items, as opposed to library components which are reusable across projects.",
        "summary": "Create a project",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The name of the new project."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The developer ID of the folder to create the project in. If omitted, the project is created at the workspace root."
                  },
                  "baseId": {
                    "type": "string",
                    "description": "The Developer ID of the base to connect the new project to. If omitted, the project will not be connected to a base."
                  }
                },
                "required": ["name"],
                "example": {
                  "name": "My New Project",
                  "folderId": "my-folder-id",
                  "baseId": "my-base"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer ID and name of the created project, as well as the developer ID of the connected base (or null).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The Developer ID of the created project"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name of the created project"
                    },
                    "baseId": {
                      "type": "string",
                      "nullable": true,
                      "description": "The Developer ID of the base the project is connected to, or null if not connected to a base"
                    }
                  },
                  "required": ["id", "name", "baseId"],
                  "example": {
                    "id": "my-new-project",
                    "name": "My New Project",
                    "baseId": "my-base"
                  }
                },
                "examples": {
                  "no_base": {
                    "summary": "Project not connected to a base",
                    "value": {
                      "id": "my-new-project",
                      "name": "My New Project",
                      "baseId": null
                    }
                  },
                  "connected_to_base": {
                    "summary": "Project connected to a base",
                    "value": {
                      "id": "my-new-project",
                      "name": "My New Project",
                      "baseId": "my-base"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projectBlocks": {
      "get": {
        "tags": ["Project Blocks"],
        "description": "Returns the blocks in a Ditto project, in display order.\n\nBlocks group text items within a project.",
        "summary": "Fetch project blocks",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Developer ID of the project to list blocks for"
            },
            "required": true,
            "description": "Developer ID of the project to list blocks for",
            "name": "projectId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of blocks in the project, in display order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The Developer ID of the block"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the block"
                      }
                    },
                    "required": ["id", "name"]
                  },
                  "example": [
                    {
                      "id": "header",
                      "name": "Header"
                    },
                    {
                      "id": "footer",
                      "name": "Footer"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Returned when the project id does not match any project in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Project with ID my-project not found"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Project Blocks"],
        "description": "Creates one or more blocks in a Ditto project.\n\nNew blocks are appended to the end of the project.",
        "summary": "Create project blocks",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the project the new blocks will be added to"
                  },
                  "blocks": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "The name of the new block. If omitted, an auto-numbered name is used (e.g. 'Block 1')."
                        },
                        "developerId": {
                          "type": "string",
                          "description": "Optional preconfigured developer ID for the block. Must be unique within the project (blocks in different projects may reuse the same developer ID). If omitted, one is generated automatically from the name."
                        }
                      }
                    },
                    "minItems": 1,
                    "description": "Array of new blocks to create"
                  }
                },
                "required": ["projectId", "blocks"],
                "example": {
                  "projectId": "my-project",
                  "blocks": [
                    {
                      "name": "Hero Section"
                    },
                    {
                      "developerId": "custom-block-id",
                      "name": "Footer"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer IDs of the created blocks, in request order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Array of developer IDs for the created blocks, in request order"
                    }
                  },
                  "required": ["developerIds"],
                  "example": {
                    "developerIds": ["hero-section", "custom-block-id"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: the project id not matching any project in the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Project with ID my-project not found"
                }
              }
            }
          },
          "409": {
            "description": "Returned when a supplied developer ID already exists in the project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the conflict"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Block developer ID header already exists in project my-project"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Project Blocks"],
        "description": "Updates a set of blocks in a Ditto project.\n\nEach block is identified by its developer ID. Only provided fields are modified — omitted fields remain unchanged.",
        "summary": "Update project blocks",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the project the blocks belong to"
                  },
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The block's current developer ID"
                        },
                        "name": {
                          "type": "string",
                          "description": "New name for the block. If not provided, name remains unchanged."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "description": "A new developer ID for this block. Must be unique within the project. Can be set alongside a name change in the same update object."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "minItems": 1,
                    "description": "Array of updates to blocks"
                  }
                },
                "required": ["projectId", "updates"],
                "example": {
                  "projectId": "my-project",
                  "updates": [
                    {
                      "developerId": "hero-section",
                      "name": "Hero"
                    }
                  ]
                }
              },
              "examples": {
                "update_name": {
                  "summary": "Rename a block",
                  "value": {
                    "projectId": "my-project",
                    "updates": [
                      {
                        "developerId": "hero-section",
                        "name": "Hero"
                      }
                    ]
                  }
                },
                "update_developer_id": {
                  "summary": "Change a block's developer ID",
                  "value": {
                    "projectId": "my-project",
                    "updates": [
                      {
                        "developerId": "hero-section",
                        "newDeveloperId": "hero"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: the project id not matching any project in the workspace, a developer ID that does not match any existing block in the project, or a newDeveloperId that already exists in the project.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Block id not found"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Project Blocks"],
        "description": "Deletes blocks from a Ditto project.",
        "summary": "Delete project blocks",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the project the blocks belong to"
                  },
                  "developerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the blocks to delete. Text items in a deleted block are not deleted — they are unassigned and moved to the end of the project's root level."
                  }
                },
                "required": ["projectId", "developerIds"],
                "example": {
                  "projectId": "my-project",
                  "developerIds": ["hero-section", "footer"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the project id does not match any project in the workspace, or a developer ID does not match any existing block in the project.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Block id not found"
                }
              }
            }
          }
        }
      }
    },
    "/textItems": {
      "get": {
        "tags": ["Text Items"],
        "description": "Returns a list of text items in your workspace.",
        "summary": "Fetch text items",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Stringified JSON filter object. Supports the following filter fields:\n- `projects`: array of objects with `id` (project developer ID)\n- `bases`: array of objects with `id` (base developer ID)\n- `variants`: array of objects with `id` (variant developer ID, `base`, or `all`)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned text items, or `null` for unassigned\n- `integrated`: boolean value to filter by items that are or are not integrated into development\n\nWithout any filters, the response will include text items from all projects and no base text items. If a `projects` filter is provided, only text items from the specified projects will be returned. If a `bases` filter is provided, only text items from the specified bases will be returned. The `projects` and `bases` filters may be used together to return items from both sources. (More details about bases coming soon!)\n\nBy default, only the base text will be returned for each text item. Provide a variants filter to specify which variants of the filtered text items to include. Use `all` to return all variants, including base text. If individual variants are specified, base text will only be returned if `base` is included in the filter.\n\nFor each text item that has plurals defined, separate entries will be returned for each plural form, plus the primary text with `pluralForm: null`. This applies to base text and variants.\n\nThe status and assignee filters apply only to project text items. Base text items do not contain these fields and will be returned unfiltered. When pairing variants with a status or assignee filter, variant data will only be returned if both the base and variant status/assignee match the filter.\n\nExample: `{\"projects\":[{\"id\":\"project-id\"}], \"variants\":[{\"id\":\"french\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\",\"tag-2\"],\"operator\":\"AND\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`"
            },
            "required": false,
            "description": "Stringified JSON filter object. Supports the following filter fields:\n- `projects`: array of objects with `id` (project developer ID)\n- `bases`: array of objects with `id` (base developer ID)\n- `variants`: array of objects with `id` (variant developer ID, `base`, or `all`)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned text items, or `null` for unassigned\n- `integrated`: boolean value to filter by items that are or are not integrated into development\n\nWithout any filters, the response will include text items from all projects and no base text items. If a `projects` filter is provided, only text items from the specified projects will be returned. If a `bases` filter is provided, only text items from the specified bases will be returned. The `projects` and `bases` filters may be used together to return items from both sources. (More details about bases coming soon!)\n\nBy default, only the base text will be returned for each text item. Provide a variants filter to specify which variants of the filtered text items to include. Use `all` to return all variants, including base text. If individual variants are specified, base text will only be returned if `base` is included in the filter.\n\nFor each text item that has plurals defined, separate entries will be returned for each plural form, plus the primary text with `pluralForm: null`. This applies to base text and variants.\n\nThe status and assignee filters apply only to project text items. Base text items do not contain these fields and will be returned unfiltered. When pairing variants with a status or assignee filter, variant data will only be returned if both the base and variant status/assignee match the filter.\n\nExample: `{\"projects\":[{\"id\":\"project-id\"}], \"variants\":[{\"id\":\"french\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\",\"tag-2\"],\"operator\":\"AND\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`",
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["id", "project_order"],
              "description": "Sort order for the returned text items (default: `id`):\n- `id` sorts all items alphabetically by developer ID.\n- `project_order` groups items by project, returned alphabetically by project developer ID, then sorts within projects based on the custom sort order set up in the web app."
            },
            "required": false,
            "description": "Sort order for the returned text items (default: `id`):\n- `id` sorts all items alphabetically by developer ID.\n- `project_order` groups items by project, returned alphabetically by project developer ID, then sorts within projects based on the custom sort order set up in the web app.",
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["html", "html_paragraphs"],
              "description": "When set to `html` or `html_paragraphs`, includes HTML-formatted rich text in the response.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks."
            },
            "required": false,
            "description": "When set to `html` or `html_paragraphs`, includes HTML-formatted rich text in the response.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks.",
            "name": "richText",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of text items matching the filter criteria",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The Developer ID of the project text item"
                          },
                          "text": {
                            "type": "string",
                            "description": "The plaintext content of the project text item. Returns the variant's text when variantId is not null."
                          },
                          "richText": {
                            "type": "string",
                            "description": "If a `richText` parameter is provided, this field contains the HTML-formatted version of the text, generated according to the specified format option. Not present if `richText` is omitted."
                          },
                          "notes": {
                            "type": "string",
                            "description": "The notes on the project text item. Returns the variant's notes when variantId is not null."
                          },
                          "characterLimit": {
                            "type": "number",
                            "nullable": true,
                            "description": "The character limit set on this project text item, or null if no limit is set. Returns the variant's character limit when variantId is not null."
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Array of tags associated with the project text item. Returns the base tags value in all responses; variants do not have their own tags."
                          },
                          "integrated": {
                            "type": "boolean",
                            "description": "Whether this project text item has been marked as integrated into development"
                          },
                          "variableIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Array of Developer IDs of variables used in this base or variant text"
                          },
                          "variantId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The Developer ID of this variant, or null for base text"
                          },
                          "pluralForm": {
                            "type": "string",
                            "nullable": true,
                            "enum": ["one", "two", "few", "many", "zero", "other", null]
                          },
                          "projectId": {
                            "type": "string",
                            "description": "The Developer ID of the project this text item belongs to"
                          },
                          "baseId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The Developer ID of the base this text item's project is connected to, or null if not connected."
                          },
                          "baseTextItemId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The Developer ID of the base text item this text item was derived from, or null if not represented in a base."
                          },
                          "status": {
                            "type": "string",
                            "description": "The status of the text item. Returns the variant's status when variantId is not null. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                          },
                          "assignee": {
                            "type": "string",
                            "nullable": true,
                            "format": "email",
                            "description": "The email of the user assigned to this text item, or null if unassigned. Returns the variant's assignee when variantId is not null."
                          },
                          "blockName": {
                            "type": "string",
                            "nullable": true,
                            "description": "The name of the block this text item belongs to, or null if it is not in a block."
                          }
                        },
                        "required": [
                          "id",
                          "text",
                          "notes",
                          "characterLimit",
                          "tags",
                          "integrated",
                          "variableIds",
                          "variantId",
                          "pluralForm",
                          "projectId",
                          "baseId",
                          "baseTextItemId",
                          "status",
                          "assignee",
                          "blockName"
                        ],
                        "title": "Project"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The Developer ID of the base text item"
                          },
                          "text": {
                            "type": "string",
                            "description": "The plaintext content of the base text item. Returns the variant's text when variantId is not null."
                          },
                          "richText": {
                            "type": "string",
                            "description": "If a `richText` parameter is provided, this field contains the HTML-formatted version of the text, generated according to the specified format option. Not present if `richText` is omitted."
                          },
                          "notes": {
                            "type": "string",
                            "description": "The notes on the base text item. Returns the variant's notes when variantId is not null."
                          },
                          "characterLimit": {
                            "type": "number",
                            "nullable": true,
                            "description": "The character limit set on this base text item, or null if no limit is set. Returns the variant's character limit when variantId is not null."
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Array of tags associated with the base text item. Returns the base tags value in all responses; variants do not have their own tags."
                          },
                          "integrated": {
                            "type": "boolean",
                            "description": "Whether this base text item has been marked as integrated into development"
                          },
                          "variableIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Array of Developer IDs of variables used in this base or variant text"
                          },
                          "variantId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The Developer ID of this variant, or null for base text"
                          },
                          "pluralForm": {
                            "type": "string",
                            "nullable": true,
                            "enum": ["one", "two", "few", "many", "zero", "other", null]
                          },
                          "projectId": {
                            "nullable": true,
                            "description": "Always set to null, to indicate that this is a base text item not a project text item"
                          },
                          "baseId": {
                            "type": "string",
                            "description": "The Developer ID of the base this text item belongs to"
                          },
                          "folderId": {
                            "type": "string",
                            "nullable": true,
                            "description": "The Developer ID of the folder this text item belongs to, or null if it is not in a folder."
                          }
                        },
                        "required": [
                          "id",
                          "text",
                          "notes",
                          "characterLimit",
                          "tags",
                          "integrated",
                          "variableIds",
                          "variantId",
                          "pluralForm",
                          "projectId",
                          "baseId",
                          "folderId"
                        ],
                        "title": "Base"
                      }
                    ]
                  },
                  "example": [
                    {
                      "id": "base-text-item-dev-id",
                      "text": "Save changes",
                      "richText": "Save changes",
                      "variantId": null,
                      "pluralForm": null,
                      "projectId": null,
                      "baseId": "base-dev-id",
                      "folderId": "buttons-folder-dev-id",
                      "notes": "base notes",
                      "characterLimit": null,
                      "tags": ["baseTag1", "baseTag2"],
                      "integrated": true,
                      "variableIds": []
                    },
                    {
                      "id": "text-item-dev-id",
                      "text": "Save changes",
                      "richText": "<strong>Save</strong> changes",
                      "variantId": null,
                      "pluralForm": null,
                      "projectId": "project-dev-id",
                      "baseId": "base-dev-id",
                      "baseTextItemId": "base-text-item-dev-id",
                      "blockName": "block name",
                      "status": "NONE",
                      "assignee": "john@example.com",
                      "notes": "base notes",
                      "characterLimit": null,
                      "tags": ["baseTag1", "baseTag2"],
                      "integrated": true,
                      "variableIds": []
                    },
                    {
                      "id": "text-item-dev-id",
                      "text": "Enregistrer les modifications",
                      "richText": "<em>Enregistrer</em> les modifications",
                      "variantId": "french",
                      "pluralForm": null,
                      "projectId": "project-dev-id",
                      "baseId": "base-dev-id",
                      "baseTextItemId": "base-text-item-dev-id",
                      "blockName": "block name",
                      "status": "WIP",
                      "assignee": "john@example.com",
                      "notes": "french notes",
                      "characterLimit": 40,
                      "tags": ["baseTag1", "baseTag2"],
                      "integrated": true,
                      "variableIds": []
                    },
                    {
                      "id": "another-text-item",
                      "text": "Hello {{name}}, you have 3 messages",
                      "richText": "Hello {{name}}, you have 3 messages",
                      "variantId": null,
                      "pluralForm": "other",
                      "projectId": "another-project",
                      "baseId": null,
                      "baseTextItemId": null,
                      "blockName": null,
                      "status": "FINAL",
                      "assignee": null,
                      "notes": "base notes",
                      "characterLimit": 60,
                      "tags": ["baseTag1", "baseTag2"],
                      "integrated": false,
                      "variableIds": ["name"]
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Text Items"],
        "description": "Creates a set of text items in a project.\n\nSupports plural forms, variant text, variable placeholders, notes, character limits, tags, status, assignee, and placing the item inside a block.",
        "summary": "Create text items",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the project the new text items will be added to"
                  },
                  "richText": {
                    "type": "string",
                    "enum": ["html"],
                    "description": "When set to 'html', all `text` values in this request (including plural and variant text) are parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup (for example links, lists, or headings) is dropped and its text content kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWhen omitted, text is saved as plaintext and any markup is stored literally."
                  },
                  "textItems": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "Optional preconfigured developer ID for the text item. Must be unique within the workspace. If omitted, system will generate one automatically."
                        },
                        "text": {
                          "type": "string",
                          "description": "The text item's text value"
                        },
                        "notes": {
                          "type": "string",
                          "nullable": true,
                          "description": "Optional notes for the text item. Use null or omit to leave notes empty."
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Optional list of tags to assign to the text item. Omit or pass an empty array for no tags."
                        },
                        "status": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Optional status for the text item (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). Cannot be empty string. If omitted, defaults to 'NONE'. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                        },
                        "assignee": {
                          "type": "string",
                          "format": "email",
                          "description": "Optional email of the workspace user to assign to this text item."
                        },
                        "characterLimit": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 1,
                          "description": "Optional character limit for the text item text. Use null or omit to indicate no limit."
                        },
                        "integrated": {
                          "type": "boolean",
                          "description": "Mark the text item as integrated into development. If omitted, defaults to false."
                        },
                        "variables": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Developer IDs of variables (the `id` field from GET /v2/variables) used in this text item's text, plurals, or variants. Text fields support `{{variable_name}}` placeholders that will be resolved using the variables listed here. Placeholders whose names are not in this list are kept as literal text."
                        },
                        "plurals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "form": {
                                "type": "string",
                                "enum": ["one", "two", "few", "many", "zero", "other"],
                                "description": "The plural form"
                              },
                              "text": {
                                "type": "string",
                                "description": "The text for this plural form"
                              }
                            },
                            "required": ["form", "text"]
                          },
                          "description": "Optional plural forms for the text item. The first plural form's text must match the text item's display text. Each form may only appear once."
                        },
                        "variants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "variantId": {
                                "type": "string",
                                "description": "Developer ID of the variant"
                              },
                              "text": {
                                "type": "string",
                                "description": "The text for this variant"
                              },
                              "status": {
                                "type": "string",
                                "minLength": 1,
                                "description": "Optional status for the text item variant (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). Cannot be empty string. If omitted, defaults to 'NONE'. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                              },
                              "assignee": {
                                "type": "string",
                                "format": "email",
                                "description": "Optional email of the user to assign to this text item variant."
                              },
                              "characterLimit": {
                                "type": "number",
                                "nullable": true,
                                "minimum": 1,
                                "description": "Optional character limit for the text item variant text. Use null or omit to indicate no limit."
                              },
                              "notes": {
                                "type": "string",
                                "nullable": true,
                                "description": "Optional notes for the text item variant. Use null or omit to leave notes empty."
                              },
                              "plurals": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "form": {
                                      "type": "string",
                                      "enum": ["one", "two", "few", "many", "zero", "other"],
                                      "description": "The plural form"
                                    },
                                    "text": {
                                      "type": "string",
                                      "description": "The text for this plural form"
                                    }
                                  },
                                  "required": ["form", "text"]
                                },
                                "description": "Optional plural forms for this variant"
                              }
                            },
                            "required": ["variantId", "text"]
                          },
                          "description": "Optional variant text values to set on the text item at creation time. Each variantId must correspond to an existing variant in the workspace."
                        },
                        "blockId": {
                          "type": "string",
                          "description": "Developer ID of the block to place this new text item in (from GET /v2/projectBlocks or list_project_blocks). If omitted, the text item is added at the project's root level, outside any block."
                        }
                      },
                      "required": ["text"]
                    },
                    "description": "Array of new text items to create"
                  }
                },
                "required": ["projectId", "textItems"],
                "example": {
                  "projectId": "project-id",
                  "textItems": [
                    {
                      "text": "Hello world"
                    },
                    {
                      "developerId": "custom-dev-id",
                      "text": "Custom ID example",
                      "notes": "Shown on the welcome screen",
                      "characterLimit": 80
                    },
                    {
                      "text": "{{count}} items in your cart",
                      "variables": ["count"],
                      "plurals": [
                        {
                          "form": "one",
                          "text": "{{count}} item in your cart"
                        },
                        {
                          "form": "other",
                          "text": "{{count}} items in your cart"
                        }
                      ]
                    },
                    {
                      "text": "Hello world",
                      "developerId": "localized-greeting",
                      "variants": [
                        {
                          "variantId": "french",
                          "text": "Bonjour le monde"
                        }
                      ]
                    },
                    {
                      "text": "Welcome to the homepage",
                      "blockId": "header"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer IDs of the created text items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Array of developer IDs for the created text items"
                    }
                  },
                  "required": ["developerIds"],
                  "example": {
                    "developerIds": ["hello-world", "custom-dev-id"]
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Text Items"],
        "description": "Updates a set of text items' base or variant text, tags, status, assignee, and plural forms.\n\nDeprecated — use PATCH /textItems instead.",
        "summary": "Update text items",
        "deprecated": true,
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variantId": {
                    "type": "string",
                    "description": "Developer ID of the target variant. If a text item does not already have the target variant, it will be added. Omit if targeting base text."
                  },
                  "forceVariantCreation": {
                    "type": "boolean",
                    "description": "If true, and the provided variantId is not found, create the variant. A variant name will be generated based on the passed in ID."
                  },
                  "richText": {
                    "type": "string",
                    "enum": ["html"],
                    "description": "When set to 'html', all `text` values in this request (including plural text) are parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup (for example links, lists, or headings) is dropped and its text content kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWhen omitted, text is saved as plaintext and any markup is stored literally."
                  },
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The text item's developer ID"
                        },
                        "text": {
                          "type": "string",
                          "description": "The text the text item will be updated to. Text will remain unchanged if unset. **Note:** Cannot be combined with plurals in the same update object. To update both the display text and other plural forms at once, include the first plural form in the plurals upsert array instead."
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The set of tags that will be set on this text item. Other tags will be removed. If unset tags will remain unchanged."
                        },
                        "status": {
                          "type": "string",
                          "description": "The status to set on this text item (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). If not provided, status will remain unchanged. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                        },
                        "assignee": {
                          "type": "string",
                          "nullable": true,
                          "format": "email",
                          "description": "The email of the user to assign to the text item. If null the assignee will be removed. If not provided, assignee will remain unchanged."
                        },
                        "integrated": {
                          "type": "boolean",
                          "description": "Mark the text item as integrated or not integrated into development. If not provided, integration status will remain unchanged."
                        },
                        "notes": {
                          "type": "string",
                          "nullable": true,
                          "description": "Notes for the text item. Use null or empty string to clear notes. If not provided, notes will remain unchanged."
                        },
                        "characterLimit": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 1,
                          "description": "Character limit for the text item. Use null to remove the limit. If not provided, character limit will remain unchanged."
                        },
                        "variables": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Developer IDs of variables (the `id` field from GET /v2/variables) used in this update's text or plurals. Text fields support `{{variable_name}}` placeholders that will be resolved using the variables listed here. Placeholders whose names are not in this list are kept as literal text."
                        },
                        "plurals": {
                          "type": "object",
                          "properties": {
                            "upsert": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "form": {
                                    "type": "string",
                                    "enum": ["one", "two", "few", "many", "zero", "other"],
                                    "description": "The plural form"
                                  },
                                  "text": {
                                    "type": "string",
                                    "description": "The text for this plural form"
                                  }
                                },
                                "required": ["form", "text"]
                              },
                              "description": "Array of plural forms to create or update. If a plural with the given form already exists, its text will be updated. Otherwise, a new plural will be created. Each form may only appear once in the array."
                            },
                            "remove": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": ["one", "two", "few", "many", "zero", "other"]
                              },
                              "description": "Array of plural forms to remove from the text item. Each form may only appear once. A form cannot appear in both upsert and remove."
                            }
                          },
                          "description": "Optional plural form updates. Existing plural forms not mentioned in either upsert or remove are preserved. The order of plurals matters: the first plural form is the 'master' value whose text is used as the text item's display text. New plurals are appended after existing ones. If you need to change which plural is first, remove and re-add them in the desired order."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "description": "A new developer ID for this text item. Must be unique within the workspace. Can be set alongside other field changes in the same update object."
                        },
                        "blockId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Developer ID of the block to move this text item into (from GET /v2/projectBlocks or list_project_blocks). Pass null to move it to the project's root level, outside any block. If omitted, block assignment is left unchanged. The item is placed at the end of the target block/root."
                        },
                        "projectId": {
                          "type": "string",
                          "description": "Developer ID of the project the target text item belongs to. Required if 2+ text items are derived from the same base text item and still share its Developer ID, to target the correct individual instance."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "description": "Array of updates to text items."
                  }
                },
                "required": ["updates"],
                "example": {
                  "variantId": "french",
                  "updates": [
                    {
                      "developerId": "greeting",
                      "text": "Bonjour!",
                      "status": "FINAL",
                      "assignee": "john@example.com"
                    }
                  ]
                }
              },
              "examples": {
                "update_base_text": {
                  "summary": "Update base text",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "text": "Hello!"
                      }
                    ]
                  }
                },
                "update_variant_text": {
                  "summary": "Update variant text",
                  "value": {
                    "variantId": "french",
                    "updates": [
                      {
                        "developerId": "greeting",
                        "text": "Bonjour!"
                      }
                    ]
                  }
                },
                "update_status": {
                  "summary": "Update status",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "status": "FINAL"
                      },
                      {
                        "developerId": "welcome-message",
                        "status": "REVIEW"
                      }
                    ]
                  }
                },
                "update_assignee": {
                  "summary": "Update assignee",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "assignee": "john@example.com"
                      },
                      {
                        "developerId": "welcome-message",
                        "assignee": null
                      }
                    ]
                  }
                },
                "add_plurals": {
                  "summary": "Add plural forms to a text item",
                  "description": "Creates plural forms on a text item. New forms are appended after any existing plurals.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "item"
                            },
                            {
                              "form": "other",
                              "text": "items"
                            }
                          ]
                        }
                      }
                    ]
                  }
                },
                "update_and_remove_plurals": {
                  "summary": "Update and remove plural forms",
                  "description": "Updates existing plural forms and removes others in a single request. A form cannot appear in both upsert and remove. Forms in remove must exist on the text item.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "updated item"
                            }
                          ],
                          "remove": ["many"]
                        }
                      }
                    ]
                  }
                },
                "update_variant_plurals": {
                  "summary": "Update plural forms on a variant",
                  "description": "Plural forms can also be managed on variants by providing a variantId.",
                  "value": {
                    "variantId": "french",
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "élément"
                            },
                            {
                              "form": "other",
                              "text": "éléments"
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: duplicate plural forms in the upsert array, a form appearing in both upsert and remove, attempting to remove a plural form that does not exist on the text item, or providing both `text` and `plurals` in the same update object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    },
                    "details": {
                      "type": "object",
                      "description": "Optional additional error details"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Cannot remove plural forms that do not exist on text item \"item-count\": many"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Text Items"],
        "description": "Updates a set of text items' base or variant text, plural forms, tags, status, assignee, notes, character limit, integrated, variables, and block placement.\n\nEach text item is identified by its developer ID. Only provided fields are modified — omitted fields remain unchanged.",
        "summary": "Update text items",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variantId": {
                    "type": "string",
                    "description": "Developer ID of the target variant. If a text item does not already have the target variant, it will be added. Omit if targeting base text."
                  },
                  "forceVariantCreation": {
                    "type": "boolean",
                    "description": "If true, and the provided variantId is not found, create the variant. A variant name will be generated based on the passed in ID."
                  },
                  "richText": {
                    "type": "string",
                    "enum": ["html"],
                    "description": "When set to 'html', all `text` values in this request (including plural text) are parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup (for example links, lists, or headings) is dropped and its text content kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWhen omitted, text is saved as plaintext and any markup is stored literally."
                  },
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The text item's developer ID"
                        },
                        "text": {
                          "type": "string",
                          "description": "The text the text item will be updated to. Text will remain unchanged if unset. **Note:** Cannot be combined with plurals in the same update object. To update both the display text and other plural forms at once, include the first plural form in the plurals upsert array instead."
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The set of tags that will be set on this text item. Other tags will be removed. If unset tags will remain unchanged."
                        },
                        "status": {
                          "type": "string",
                          "description": "The status to set on this text item (for example: 'NONE', 'WIP', 'REVIEW', 'FINAL'). If not provided, status will remain unchanged. These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set)."
                        },
                        "assignee": {
                          "type": "string",
                          "nullable": true,
                          "format": "email",
                          "description": "The email of the user to assign to the text item. If null the assignee will be removed. If not provided, assignee will remain unchanged."
                        },
                        "integrated": {
                          "type": "boolean",
                          "description": "Mark the text item as integrated or not integrated into development. If not provided, integration status will remain unchanged."
                        },
                        "notes": {
                          "type": "string",
                          "nullable": true,
                          "description": "Notes for the text item. Use null or empty string to clear notes. If not provided, notes will remain unchanged."
                        },
                        "characterLimit": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 1,
                          "description": "Character limit for the text item. Use null to remove the limit. If not provided, character limit will remain unchanged."
                        },
                        "variables": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Developer IDs of variables (the `id` field from GET /v2/variables) used in this update's text or plurals. Text fields support `{{variable_name}}` placeholders that will be resolved using the variables listed here. Placeholders whose names are not in this list are kept as literal text."
                        },
                        "plurals": {
                          "type": "object",
                          "properties": {
                            "upsert": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "form": {
                                    "type": "string",
                                    "enum": ["one", "two", "few", "many", "zero", "other"],
                                    "description": "The plural form"
                                  },
                                  "text": {
                                    "type": "string",
                                    "description": "The text for this plural form"
                                  }
                                },
                                "required": ["form", "text"]
                              },
                              "description": "Array of plural forms to create or update. If a plural with the given form already exists, its text will be updated. Otherwise, a new plural will be created. Each form may only appear once in the array."
                            },
                            "remove": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": ["one", "two", "few", "many", "zero", "other"]
                              },
                              "description": "Array of plural forms to remove from the text item. Each form may only appear once. A form cannot appear in both upsert and remove."
                            }
                          },
                          "description": "Optional plural form updates. Existing plural forms not mentioned in either upsert or remove are preserved. The order of plurals matters: the first plural form is the 'master' value whose text is used as the text item's display text. New plurals are appended after existing ones. If you need to change which plural is first, remove and re-add them in the desired order."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "description": "A new developer ID for this text item. Must be unique within the workspace. Can be set alongside other field changes in the same update object."
                        },
                        "blockId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Developer ID of the block to move this text item into (from GET /v2/projectBlocks or list_project_blocks). Pass null to move it to the project's root level, outside any block. If omitted, block assignment is left unchanged. The item is placed at the end of the target block/root."
                        },
                        "projectId": {
                          "type": "string",
                          "description": "Developer ID of the project the target text item belongs to. Required if 2+ text items are derived from the same base text item and still share its Developer ID, to target the correct individual instance."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "description": "Array of updates to text items."
                  }
                },
                "required": ["updates"],
                "example": {
                  "variantId": "french",
                  "updates": [
                    {
                      "developerId": "greeting",
                      "text": "Bonjour!",
                      "status": "FINAL",
                      "assignee": "john@example.com"
                    }
                  ]
                }
              },
              "examples": {
                "update_base_text": {
                  "summary": "Update base text",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "text": "Hello!"
                      }
                    ]
                  }
                },
                "update_variant_text": {
                  "summary": "Update variant text",
                  "value": {
                    "variantId": "french",
                    "updates": [
                      {
                        "developerId": "greeting",
                        "text": "Bonjour!"
                      }
                    ]
                  }
                },
                "update_with_variables": {
                  "summary": "Update text with variable placeholders",
                  "description": "Use `{{variable_name}}` placeholders in the text and list the variable developer IDs in `variables`. Variables not in the list are kept as literal text.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "text": "Hello, {{user_name}}!",
                        "variables": ["user_name"]
                      }
                    ]
                  }
                },
                "update_with_rich_text": {
                  "summary": "Update text with HTML rich text",
                  "description": "Set `richText` to `html` to have every `text` value in the request parsed as HTML and saved as rich text. Supported formatting: `<strong>`/`<b>`, `<em>`/`<i>`, `<u>`, `<s>`, and `<br>` for line breaks. `<sup>` and `<sub>` are only supported for workspaces with superscript and subscript enabled. Unsupported markup such as links, lists, or headings is dropped while its text content is kept.\n\nNote: Fully-bolded strings will have that bold styling stripped, as Figma does not support bolding an entire text layer this way.\n\nWithout this flag, markup is saved as plaintext.",
                  "value": {
                    "richText": "html",
                    "variantId": "korean",
                    "updates": [
                      {
                        "developerId": "homepage.section.inspiration",
                        "text": "<strong>Inspiration</strong> for your next trip"
                      }
                    ]
                  }
                },
                "update_status": {
                  "summary": "Update status",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "status": "FINAL"
                      },
                      {
                        "developerId": "welcome-message",
                        "status": "REVIEW"
                      }
                    ]
                  }
                },
                "update_notes_and_limit": {
                  "summary": "Update notes and character limit",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "notes": "Keep this short",
                        "characterLimit": 40
                      }
                    ]
                  }
                },
                "update_assignee": {
                  "summary": "Update assignee",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "assignee": "john@example.com"
                      },
                      {
                        "developerId": "welcome-message",
                        "assignee": null
                      }
                    ]
                  }
                },
                "move_to_block": {
                  "summary": "Move a text item into a block, or back to the project root",
                  "description": "Set blockId to a block's developer ID (see GET /projectBlocks) to move the item into that block, or to null to move it back to the project's root level. Omit blockId to leave placement unchanged.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "greeting",
                        "blockId": "header"
                      },
                      {
                        "developerId": "welcome-message",
                        "blockId": null
                      }
                    ]
                  }
                },
                "add_plurals": {
                  "summary": "Add plural forms to a text item",
                  "description": "Creates plural forms on a text item. New forms are appended after any existing plurals.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "item"
                            },
                            {
                              "form": "other",
                              "text": "items"
                            }
                          ]
                        }
                      }
                    ]
                  }
                },
                "update_and_remove_plurals": {
                  "summary": "Update and remove plural forms",
                  "description": "Updates existing plural forms and removes others in a single request. A form cannot appear in both upsert and remove. Forms in remove must exist on the text item.",
                  "value": {
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "updated item"
                            }
                          ],
                          "remove": ["many"]
                        }
                      }
                    ]
                  }
                },
                "update_variant_plurals": {
                  "summary": "Update plural forms on a variant",
                  "description": "Plural forms can also be managed on variants by providing a variantId.",
                  "value": {
                    "variantId": "french",
                    "updates": [
                      {
                        "developerId": "item-count",
                        "plurals": {
                          "upsert": [
                            {
                              "form": "one",
                              "text": "élément"
                            },
                            {
                              "form": "other",
                              "text": "éléments"
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a developer ID that does not match any existing text item, a variant ID that does not exist (when forceVariantCreation is not set), a variable name not found in the workspace, duplicate plural forms in the upsert array, a form appearing in both upsert and remove, attempting to remove a plural form that does not exist on the text item, or providing both `text` and `plurals` in the same update object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    },
                    "details": {
                      "type": "object",
                      "description": "Optional additional error details"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Cannot remove plural forms that do not exist on text item \"item-count\": many"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Text Items"],
        "description": "Deletes text items by their developer IDs.",
        "summary": "Delete text items",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "developerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Array of developer IDs for the text items to delete. Cannot be library instances."
                  }
                },
                "required": ["developerIds"],
                "example": {
                  "developerIds": ["greeting", "welcome-message"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/textItems/export": {
      "get": {
        "tags": ["Text Items"],
        "description": "Returns text items in your workspace in the desired export format.",
        "summary": "Export text items",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Stringified JSON filter object. Supports the following filter fields:\n- `projects`: array of objects with `id` (project developer ID)\n- `bases`: array of objects with `id` (base developer ID)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned text items, or `null` for unassigned\n- `integrated`: boolean value to filter by items that are or are not integrated into development\n\nWithout any filters, the export will include text items from all projects and no base text items. If a `projects` filter is provided, only text items from the specified projects will be exported. If a `bases` filter is provided, only text items from the specified bases will be exported. The `projects` and `bases` filters may be used together to export items from both sources. (More details about bases coming soon!)\n\nThe status and assignee filters apply only to project text items. Base text items do not contain these fields and will be exported unfiltered.\n\nExample: `{\"projects\":[{\"id\":\"project-id\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\"],\"operator\":\"OR\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`"
            },
            "required": false,
            "description": "Stringified JSON filter object. Supports the following filter fields:\n- `projects`: array of objects with `id` (project developer ID)\n- `bases`: array of objects with `id` (base developer ID)\n- `statuses`: array of status strings (`NONE`, `WIP`, `REVIEW`, `FINAL`). These are stored status keys; by default the web app and Figma plugin display them as NONE = \"Draft\", WIP = \"In Progress\", REVIEW = \"In Review\", FINAL = \"Final\" (a workspace may rename these or replace the set entirely, so none of these keys are guaranteed to exist — read the workspace's actual statuses from GET /v2/statuses or the list_statuses MCP tool rather than assuming this set).\n- `tags`: object with `values` (array of tag strings) and optional `operator` (`AND` or `OR`, defaults to `OR`)\n- `assignee`: email string to match assigned text items, or `null` for unassigned\n- `integrated`: boolean value to filter by items that are or are not integrated into development\n\nWithout any filters, the export will include text items from all projects and no base text items. If a `projects` filter is provided, only text items from the specified projects will be exported. If a `bases` filter is provided, only text items from the specified bases will be exported. The `projects` and `bases` filters may be used together to export items from both sources. (More details about bases coming soon!)\n\nThe status and assignee filters apply only to project text items. Base text items do not contain these fields and will be exported unfiltered.\n\nExample: `{\"projects\":[{\"id\":\"project-id\"}], \"statuses\":[\"NONE\",\"WIP\",\"FINAL\",\"REVIEW\"], \"tags\":{\"values\":[\"tag-1\"],\"operator\":\"OR\"}, \"assignee\":\"user@example.com\", \"integrated\":true}`",
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["id", "project_order"],
              "description": "Sort order for the returned text items (default: `id`):\n- `id` sorts all items alphabetically by developer ID.\n- `project_order` groups items by project, returned alphabetically by project developer ID, then sorts within projects based on the custom sort order set up in the web app."
            },
            "required": false,
            "description": "Sort order for the returned text items (default: `id`):\n- `id` sorts all items alphabetically by developer ID.\n- `project_order` groups items by project, returned alphabetically by project developer ID, then sorts within projects based on the custom sort order set up in the web app.",
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["html", "html_paragraphs"],
              "description": "When set to `html` or `html_paragraphs`, returns HTML-formatted rich text instead of plain text.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks."
            },
            "required": false,
            "description": "When set to `html` or `html_paragraphs`, returns HTML-formatted rich text instead of plain text.\n- `html_paragraphs` wraps all text in `<p>` tags. Matches legacy behavior.\n- `html` exports without wrapping tags and uses `<br />` for line breaks.",
            "name": "richText",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "By default, base text will be returned. Provide a variant parameter to specify which variant of the filtered base text items to return."
            },
            "required": false,
            "description": "By default, base text will be returned. Provide a variant parameter to specify which variant of the filtered base text items to return.",
            "name": "variantId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["json_icu", "json_i18next", "json_vue_i18n", "ios-strings", "ios-stringsdict", "android", "arb"],
              "description": "Output format for exported text items."
            },
            "required": true,
            "description": "Output format for exported text items.",
            "name": "format",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["default", "alphabetical"],
              "description": "Order in which variables are indexed in positional format exports (`ios-strings`, `ios-stringsdict`, `android`). \"alphabetical\" assigns indices by variable name (a=1, b=2, ...); \"default\" preserves the existing creation-order assignment."
            },
            "required": false,
            "description": "Order in which variables are indexed in positional format exports (`ios-strings`, `ios-stringsdict`, `android`). \"alphabetical\" assigns indices by variable name (a=1, b=2, ...); \"default\" preserves the existing creation-order assignment.",
            "name": "variableSort",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": ["true"],
                  "title": "true"
                },
                {
                  "type": "string",
                  "enum": ["false"],
                  "title": "false"
                }
              ],
              "description": "When `true`, omits the `__variant-name` and `__variant-description` keys from variant exports in JSON formats (`json_i18next`, `json_vue_i18n`, `json_icu`). Defaults to `false`. Has no effect on any other formats nor any base text (non-variant) exports, which never include these keys."
            },
            "required": false,
            "description": "When `true`, omits the `__variant-name` and `__variant-description` keys from variant exports in JSON formats (`json_i18next`, `json_vue_i18n`, `json_icu`). Defaults to `false`. Has no effect on any other formats nor any base text (non-variant) exports, which never include these keys.",
            "name": "excludeVariantMetadata",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": ["true"],
                  "title": "true"
                },
                {
                  "type": "string",
                  "enum": ["false"],
                  "title": "false"
                }
              ],
              "description": "When `true`, adds a `__variables_used` key to `json_i18next` and `json_vue_i18n` exports: a deduplicated, alphabetical array of the names of the variables used in the exported strings. Defaults to `false`. Has no effect on other formats."
            },
            "required": false,
            "description": "When `true`, adds a `__variables_used` key to `json_i18next` and `json_vue_i18n` exports: a deduplicated, alphabetical array of the names of the variables used in the exported strings. Defaults to `false`. Has no effect on other formats.",
            "name": "includeVariableSummary",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns text item developer id - text item value key/value pairs in the desired format.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "For `json_icu`, `json_i18next`, `json_vue_i18n` formats, object keys are developer-ids (strings) and values are text (strings). Variant exports in these formats also include `__variant-name` and `__variant-description` keys (strings) unless `excludeVariantMetadata=true`. When `includeVariableSummary=true`, `json_i18next` and `json_vue_i18n` exports also include a `__variables_used` key, whose value is an array of variable names. For `arb`, values are text (strings) except for the optional top-level `@@locale` key (string) and `@<developer-id>` metadata keys, which are objects.",
                  "additionalProperties": {
                    "oneOf": [
                      {
                        "type": "string",
                        "title": "Text",
                        "description": "The text value for the developer-id key, the `__variant-name`/`__variant-description` value for variant exports, or the `@@locale` value for `arb` exports"
                      },
                      {
                        "type": "object",
                        "title": "Metadata",
                        "description": "ARB metadata for a `@<developer-id>` key: optional `description` (from the text item's notes) and/or `placeholders` (variable name to ARB type).",
                        "properties": {
                          "description": {
                            "type": "string"
                          },
                          "placeholders": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      },
                      {
                        "type": "array",
                        "title": "Variables used",
                        "description": "The `__variables_used` value when `includeVariableSummary=true`: a deduplicated, alphabetical array of the names of the variables used in the export (`json_i18next` and `json_vue_i18n` only)",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "example": {
                    "@@locale": "en",
                    "user-account-header": "{FullName}'s Account",
                    "user-account-settings-label": "Account Settings",
                    "user-account-settings-payment-header": "Payment Details",
                    "welcome-header": "Welcome to Acme Inc., {FirstName}",
                    "no-notifications-label": "No new notifications",
                    "@welcome-header": {
                      "placeholders": {
                        "FirstName": {
                          "type": "String"
                        }
                      }
                    }
                  }
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "For iOS .strings format",
                  "example": "\"component-dev-id-continue\" = \"Continue\";"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string",
                  "description": "For Android .xml and iOS .stringsdict formats",
                  "example": "<string name=\"primary_phone_number\" ditto_api_id=\"primary-phone-number\">Primary phone number</string>..."
                }
              }
            }
          },
          "400": {
            "description": "Error for when variantId is not found, format is incorrect, or one or more filters are invalid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message indicating incorrect parameters"
                    },
                    "details": {
                      "type": "object",
                      "description": "Optional additional error details"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Variant with id \"<variantId>\" not found"
                }
              }
            }
          }
        }
      }
    },
    "/textItems/linkFigmaNodes": {
      "post": {
        "tags": ["Text Items"],
        "description": "Links one or more Figma text nodes to an existing text item in a Figma-linked project, so those nodes become Figma instances of that text item.\n\nThe nodes must already have been synced to Ditto through the Ditto Figma plugin. Pass `figma.branchId` to link nodes inside a branch file; without it, nodes are looked up in the project's main Figma file.\n\nThe link is recorded in Ditto right away, but Ditto writes to a Figma file only from the plugin. So the Figma layer doesn't reflect the link — and later edits to the text item don't reach that layer — until someone next opens the Ditto Figma plugin on the file.\n\nNodes are handled independently rather than all-or-nothing: the response reports an outcome per node ID — `linked`, `already_linked`, `not_found` (sync the file from the plugin, then retry), `not_text_node`, `wrong_file_or_branch`, or `main_component_text_node` (link instance text nodes directly, or link the main component's text from the Figma plugin).",
        "summary": "Link Figma nodes to a text item",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "projectId": {
                    "type": "string",
                    "description": "Developer ID of the Ditto project linked to the Figma file containing these nodes."
                  },
                  "textItemId": {
                    "type": "string",
                    "description": "Developer ID of the existing Ditto text item to link these Figma nodes to."
                  },
                  "figma": {
                    "type": "object",
                    "properties": {
                      "nodeIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "minItems": 1,
                        "maxItems": 50,
                        "description": "Figma text node IDs to link. Max 50 per request."
                      },
                      "branchId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Provide the Figma branch ID (obtained from the branch file's Figma URL) of the branch file linked to Ditto, to link nodes within that branch file. If omitted, the file searched for linking will always be the main Figma file."
                      }
                    },
                    "required": ["nodeIds"],
                    "description": "Figma nodes and branch context to link."
                  }
                },
                "required": ["projectId", "textItemId", "figma"],
                "example": {
                  "projectId": "project-id-1",
                  "textItemId": "greeting",
                  "figma": {
                    "nodeIds": ["1:23", "1:24"],
                    "branchId": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the resolved project, text item, and branch context, plus 1 result per distinct Figma node ID",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "projectId": {
                      "type": "string"
                    },
                    "textItemId": {
                      "type": "string"
                    },
                    "branchId": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "figmaNodeId": {
                            "type": "string"
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "linked",
                              "already_linked",
                              "not_found",
                              "not_text_node",
                              "wrong_file_or_branch",
                              "main_component_text_node"
                            ]
                          },
                          "linkedTextItemId": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": ["figmaNodeId", "outcome"]
                      }
                    }
                  },
                  "required": ["projectId", "textItemId", "branchId", "results"],
                  "example": {
                    "projectId": "project-id-1",
                    "textItemId": "greeting",
                    "branchId": null,
                    "results": [
                      {
                        "figmaNodeId": "1:23",
                        "outcome": "linked",
                        "linkedTextItemId": "greeting"
                      },
                      {
                        "figmaNodeId": "1:24",
                        "outcome": "not_found",
                        "message": "This Figma text node is not in the cache for the target project context. Sync first, then retry."
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the project is not linked to Figma",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Project \"project-id-1\" is not linked to Figma."
                }
              }
            }
          },
          "404": {
            "description": "Returned when the project doesn't exist, or the text item doesn't exist in that project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing what was not found"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Text item \"greeting\" was not found in project \"project-id-1\"."
                }
              }
            }
          }
        }
      }
    },
    "/variables": {
      "get": {
        "tags": ["Variables"],
        "description": "Returns a list of the variables in the workspace.",
        "summary": "Fetch variables",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of variables in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_]+$"
                          },
                          "type": {
                            "type": "string",
                            "enum": ["number"]
                          },
                          "data": {
                            "type": "object",
                            "properties": {
                              "example": {
                                "anyOf": [
                                  {
                                    "type": "number",
                                    "title": "Number"
                                  },
                                  {
                                    "type": "string",
                                    "title": "String"
                                  }
                                ]
                              },
                              "fallback": {
                                "anyOf": [
                                  {
                                    "type": "number",
                                    "title": "Number"
                                  },
                                  {
                                    "type": "string",
                                    "title": "String"
                                  }
                                ]
                              }
                            },
                            "required": ["example"]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "type", "data", "id"],
                        "title": "Number"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_]+$"
                          },
                          "type": {
                            "type": "string",
                            "enum": ["string"]
                          },
                          "data": {
                            "type": "object",
                            "properties": {
                              "example": {
                                "type": "string"
                              },
                              "fallback": {
                                "type": "string"
                              }
                            },
                            "required": ["example"]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "type", "data", "id"],
                        "title": "String"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_]+$"
                          },
                          "type": {
                            "type": "string",
                            "enum": ["hyperlink"]
                          },
                          "data": {
                            "type": "object",
                            "properties": {
                              "text": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              }
                            },
                            "required": ["text", "url"]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "type", "data", "id"],
                        "title": "Hyperlink"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_]+$"
                          },
                          "type": {
                            "type": "string",
                            "enum": ["list"]
                          },
                          "data": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "type", "data", "id"],
                        "title": "List"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_]+$"
                          },
                          "type": {
                            "type": "string",
                            "enum": ["map"]
                          },
                          "data": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "string"
                            }
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": ["name", "type", "data", "id"],
                        "title": "Map"
                      }
                    ]
                  },
                  "example": [
                    {
                      "id": "Age",
                      "name": "Age",
                      "type": "number",
                      "data": {
                        "example": 21,
                        "fallback": "18"
                      }
                    },
                    {
                      "id": "Jobs",
                      "name": "Jobs",
                      "type": "string",
                      "data": {
                        "example": "Engineer",
                        "fallback": "Designer"
                      }
                    },
                    {
                      "id": "Link",
                      "name": "Link",
                      "type": "hyperlink",
                      "data": {
                        "text": "View",
                        "url": "https://www.google.com/"
                      }
                    },
                    {
                      "id": "List",
                      "name": "List",
                      "type": "list",
                      "data": ["true", "false"]
                    },
                    {
                      "id": "Map",
                      "name": "Map",
                      "type": "map",
                      "data": {
                        "0": "Zero",
                        "1": "One",
                        "2": "Two"
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Variables"],
        "description": "Creates variables in your workspace.\n\nThe shape of `data` depends on `type`: string and number take an `example` and an optional `fallback`, hyperlink takes `text` and `url`, list takes an array of strings, and map takes an object of string keys to string values.\n\nEither every variable is created or none is.",
        "summary": "Create variables",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variables": {
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": ["string"]
                            },
                            "data": {
                              "type": "object",
                              "properties": {
                                "example": {
                                  "type": "string"
                                },
                                "fallback": {
                                  "type": "string"
                                }
                              },
                              "required": ["example"]
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_]+$",
                              "description": "The variable's name, which doubles as its developer ID. Letters, numbers, and underscores only, and unique within the workspace."
                            }
                          },
                          "required": ["type", "data", "name"],
                          "title": "String"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": ["number"]
                            },
                            "data": {
                              "type": "object",
                              "properties": {
                                "example": {
                                  "anyOf": [
                                    {
                                      "type": "number",
                                      "title": "Number"
                                    },
                                    {
                                      "type": "string",
                                      "title": "String"
                                    }
                                  ]
                                },
                                "fallback": {
                                  "anyOf": [
                                    {
                                      "type": "number",
                                      "title": "Number"
                                    },
                                    {
                                      "type": "string",
                                      "title": "String"
                                    }
                                  ]
                                }
                              },
                              "required": ["example"]
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_]+$",
                              "description": "The variable's name, which doubles as its developer ID. Letters, numbers, and underscores only, and unique within the workspace."
                            }
                          },
                          "required": ["type", "data", "name"],
                          "title": "Number"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": ["hyperlink"]
                            },
                            "data": {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "string"
                                },
                                "url": {
                                  "type": "string"
                                }
                              },
                              "required": ["text", "url"]
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_]+$",
                              "description": "The variable's name, which doubles as its developer ID. Letters, numbers, and underscores only, and unique within the workspace."
                            }
                          },
                          "required": ["type", "data", "name"],
                          "title": "Hyperlink"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": ["list"]
                            },
                            "data": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_]+$",
                              "description": "The variable's name, which doubles as its developer ID. Letters, numbers, and underscores only, and unique within the workspace."
                            }
                          },
                          "required": ["type", "data", "name"],
                          "title": "List"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string",
                              "enum": ["map"]
                            },
                            "data": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string"
                              }
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_]+$",
                              "description": "The variable's name, which doubles as its developer ID. Letters, numbers, and underscores only, and unique within the workspace."
                            }
                          },
                          "required": ["type", "data", "name"],
                          "title": "Map"
                        }
                      ]
                    },
                    "minItems": 1,
                    "description": "Array of new variables to create"
                  }
                },
                "required": ["variables"],
                "example": {
                  "variables": [
                    {
                      "name": "user_name",
                      "type": "string",
                      "data": {
                        "example": "Jane Doe",
                        "fallback": "there"
                      }
                    },
                    {
                      "name": "help_link",
                      "type": "hyperlink",
                      "data": {
                        "text": "Learn more",
                        "url": "https://dittowords.com"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the names of the created variables",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "names": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Names of the created variables, in request order"
                    }
                  },
                  "required": ["names"],
                  "example": {
                    "names": ["user_name", "help_link"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a name that isn't unique in the workspace, a name repeated within the request, or data that doesn't match the variable's type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Variables"],
        "description": "Renames variables or changes their type or value.\n\nEither every update is applied or none is.",
        "summary": "Update variables",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "description": "The variable's current name, which is also its developer ID"
                        },
                        "newName": {
                          "type": "string",
                          "pattern": "^[A-Za-z0-9_]+$",
                          "description": "A new name for this variable. A variable's name is its developer ID, so renaming it changes how it's referenced: every {{placeholder}} using it is rewritten to match. If not provided, the name remains unchanged."
                        },
                        "type": {
                          "type": "string",
                          "enum": ["string", "number", "hyperlink", "list", "map"],
                          "description": "A new type for this variable. Must be sent together with `data`, even when the value itself stays the same. If not provided, the type remains unchanged."
                        },
                        "data": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "example": {
                                  "anyOf": [
                                    {
                                      "type": "number",
                                      "title": "Number"
                                    },
                                    {
                                      "type": "string",
                                      "title": "String"
                                    }
                                  ]
                                },
                                "fallback": {
                                  "anyOf": [
                                    {
                                      "type": "number",
                                      "title": "Number"
                                    },
                                    {
                                      "type": "string",
                                      "title": "String"
                                    }
                                  ]
                                }
                              },
                              "required": ["example"],
                              "title": "Number"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "example": {
                                  "type": "string"
                                },
                                "fallback": {
                                  "type": "string"
                                }
                              },
                              "required": ["example"],
                              "title": "String"
                            },
                            {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "string"
                                },
                                "url": {
                                  "type": "string"
                                }
                              },
                              "required": ["text", "url"],
                              "title": "Hyperlink"
                            },
                            {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "title": "List"
                            },
                            {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string"
                              },
                              "title": "Map"
                            }
                          ],
                          "description": "The variable's new value. String and number variables have `example` and an optional `fallback`, and hyperlink variables have `text` and `url`; those fields are fixed, so sending only some of them leaves the rest as they were — send an empty string to clear one. A list variable's value is an array of strings, and a map variable's is an object of string keys to string values; that value is the variable's entire content, so what you send replaces it outright. If not provided, the value remains unchanged."
                        }
                      },
                      "required": ["name"]
                    },
                    "minItems": 1,
                    "description": "Array of updates to variables"
                  }
                },
                "required": ["updates"],
                "example": {
                  "updates": [
                    {
                      "name": "user_name",
                      "newName": "customer_name"
                    },
                    {
                      "name": "help_link",
                      "data": {
                        "text": "Read the docs",
                        "url": "https://dittowords.com/docs"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the variables that changed, and those already in the requested state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updated": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Names of the variables that changed"
                    },
                    "unchanged": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Names of the variables that were already in the requested state"
                    }
                  },
                  "required": ["updated", "unchanged"],
                  "example": {
                    "updated": ["customer_name"],
                    "unchanged": ["help_link"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: a name that isn't unique in the workspace, a name repeated within the request, or data that doesn't match the variable's type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Returned when a name doesn't match any variable in the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "message": "Variable name not found: user_name"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Variables"],
        "description": "Permanently deletes variables from your workspace.\n\nThis can't be undone, and either every variable in the request is deleted or none is.",
        "summary": "Delete variables",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "names": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Names of the variables to delete, which are also their developer IDs. All must exist, and none can still be used by a text item or library component."
                  }
                },
                "required": ["names"],
                "example": {
                  "names": ["user_name", "help_link"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the names of the deleted variables",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "names": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Names of the deleted variables"
                    }
                  },
                  "required": ["names"],
                  "example": {
                    "names": ["user_name", "help_link"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a variable is still used by a text item or library component.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Returned when a name doesn't match any variable in the workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "message": "Variable name not found: user_name"
                }
              }
            }
          }
        }
      }
    },
    "/statuses": {
      "get": {
        "tags": ["Statuses"],
        "description": "Returns the statuses which text items and library components in the workspace can be set to, in workflow order — from earliest (a first draft) to latest (ready to ship).\n\nA workspace can rename the default statuses or replace the set entirely, so none of the defaults are guaranteed to exist. Read the available statuses here before setting a status or filtering by one rather than assuming any particular key is valid.",
        "summary": "Fetch statuses",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of statuses in the workspace, in workflow order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The status's stable identifier. This is the value to send when setting the `status` field on a text item or library component, and when querying with a `statuses` filter — never the display name"
                      },
                      "name": {
                        "type": "string",
                        "description": "The status's display name, for use anywhere the status is shown to a person — as it appears in the web app and Figma plugin. Not accepted as an identifier when setting or filtering by status"
                      }
                    },
                    "required": ["id", "name"]
                  },
                  "example": [
                    {
                      "id": "NONE",
                      "name": "Draft"
                    },
                    {
                      "id": "WIP",
                      "name": "In Progress"
                    },
                    {
                      "id": "REVIEW",
                      "name": "In Review"
                    },
                    {
                      "id": "FINAL",
                      "name": "Final"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/variants": {
      "get": {
        "tags": ["Variants"],
        "description": "Returns a list of the variants in the workspace.",
        "summary": "Fetch variants",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Returns an array of variants in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The Developer ID of the variant. Keywords 'all' and 'base' are reserved"
                      },
                      "name": {
                        "type": "string",
                        "description": "The name of the variant"
                      },
                      "description": {
                        "type": "string",
                        "description": "The description provided for the variant. Empty string if no description exists"
                      },
                      "localeCode": {
                        "type": "string",
                        "nullable": true,
                        "description": "The variant's locale code (for example, 'es', 'fr-ca'), or null if it is not locale-scoped. When translating, this is the authoritative target locale — do not infer the locale from the variant's name."
                      }
                    },
                    "required": ["id", "name", "description", "localeCode"]
                  },
                  "example": [
                    {
                      "id": "all-1",
                      "name": "all",
                      "description": ""
                    },
                    {
                      "id": "french",
                      "name": "French",
                      "description": "French translations"
                    },
                    {
                      "id": "spanish",
                      "name": "Spanish",
                      "description": ""
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Variants"],
        "description": "Creates one or more variants in the workspace.\n\nA variant is a named alternative that text items and library components can each have their own text for — most often a locale to translate into, but also a tone or brand variation. Creating a variant adds no text on its own; use the text item endpoints to set a text item's text for that variant.\n\nRead the developer IDs off the response rather than assuming them — a developer ID you don't specify is generated from the name.",
        "summary": "Create variants",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variants": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "description": "The variant's name. Must be unique within the workspace; 'base' is reserved."
                        },
                        "developerId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Optional preconfigured developer ID for the variant. Must be unique within the workspace, and 'base' and 'all' are reserved. Accepted in any casing and stored lowercase. Characters outside letters, numbers, hyphens, and underscores are stripped. If omitted, one is generated from the name."
                        },
                        "description": {
                          "type": "string",
                          "description": "Optional description of what the variant is for."
                        },
                        "localeCode": {
                          "type": "string",
                          "enum": [
                            "af",
                            "ar",
                            "ar-ae",
                            "ar-bh",
                            "ar-dz",
                            "ar-eg",
                            "ar-iq",
                            "ar-jo",
                            "ar-kw",
                            "ar-lb",
                            "ar-ly",
                            "ar-ma",
                            "ar-om",
                            "ar-qa",
                            "ar-sa",
                            "ar-sy",
                            "ar-tn",
                            "ar-ye",
                            "az",
                            "be",
                            "bg",
                            "bs",
                            "ca",
                            "cs",
                            "cy",
                            "da",
                            "de",
                            "de-at",
                            "de-ch",
                            "de-li",
                            "de-lu",
                            "el",
                            "en",
                            "en-au",
                            "en-bz",
                            "en-ca",
                            "en-gb",
                            "en-ie",
                            "en-jm",
                            "en-nz",
                            "en-sg",
                            "en-tt",
                            "en-us",
                            "en-za",
                            "es",
                            "es-ar",
                            "es-bo",
                            "es-cl",
                            "es-co",
                            "es-cr",
                            "es-do",
                            "es-ec",
                            "es-gt",
                            "es-hn",
                            "es-mx",
                            "es-ni",
                            "es-pa",
                            "es-pe",
                            "es-pr",
                            "es-py",
                            "es-sv",
                            "es-uy",
                            "es-ve",
                            "et",
                            "eu",
                            "fa",
                            "fi",
                            "fo",
                            "fr",
                            "fr-be",
                            "fr-ca",
                            "fr-ch",
                            "fr-lu",
                            "ga",
                            "gd",
                            "he",
                            "hi",
                            "hr",
                            "hu",
                            "hy",
                            "id",
                            "is",
                            "it",
                            "it-ch",
                            "ja",
                            "ka",
                            "kk",
                            "ko",
                            "ku",
                            "lt",
                            "lv",
                            "mk",
                            "ml",
                            "ms",
                            "mt",
                            "nb",
                            "nl",
                            "nl-be",
                            "nn",
                            "no",
                            "pa",
                            "pl",
                            "pt",
                            "pt-br",
                            "rm",
                            "ro",
                            "ro-md",
                            "ru",
                            "ru-md",
                            "sk",
                            "sl",
                            "sq",
                            "sr",
                            "sv",
                            "sv-fi",
                            "th",
                            "tn",
                            "tr",
                            "ts",
                            "uk",
                            "ur",
                            "ve",
                            "vi",
                            "wen",
                            "xh",
                            "yi",
                            "zh-cn",
                            "zh-hk",
                            "zh-sg",
                            "zh-tw",
                            "zu"
                          ],
                          "description": "Locale code for the variant, from the set Ditto supports. Casing does not matter on the way in — 'fr-CA' and 'fr-ca' are both accepted — and the code is stored lowercase, which is the form reads return. Not every language-region pairing exists in the set, so pick one of the listed values rather than composing your own. At most one variant per workspace can hold a given locale code. Set this whenever the variant represents a language: translation tools treat it as the authoritative target locale."
                        }
                      },
                      "required": ["name"]
                    },
                    "minItems": 1,
                    "description": "Array of new variants to create"
                  }
                },
                "required": ["variants"],
                "example": {
                  "variants": [
                    {
                      "name": "Spanish",
                      "localeCode": "es"
                    },
                    {
                      "name": "Canadian French",
                      "developerId": "fr-ca",
                      "description": "French translations for Canada"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer IDs of the created variants, in request order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "developerIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Array of developer IDs for the created variants, in request order"
                    }
                  },
                  "required": ["developerIds"],
                  "example": {
                    "developerIds": ["spanish", "fr-ca"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: the same name, developer ID, or locale code appearing twice in one request; a reserved developer ID.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Duplicate locale codes in request: es"
                }
              }
            }
          },
          "409": {
            "description": "Returned when a name, developer ID, or locale code is already in use by another variant in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the conflict"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Locale code already attached to another variant: es. A locale code can belong to at most one variant."
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Variants"],
        "description": "Updates one or more variants in the workspace, identified by their current developer IDs.\n\nOnly provided fields are modified. The whole batch is rejected if any update is invalid.",
        "summary": "Update variants",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updates": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "developerId": {
                          "type": "string",
                          "description": "The variant's current developer ID"
                        },
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "description": "New name for the variant. If not provided, the name is unchanged."
                        },
                        "newDeveloperId": {
                          "type": "string",
                          "minLength": 1,
                          "description": "A new developer ID for this variant. Must be unique within the workspace, and is accepted in any casing and stored lowercase. Renaming a variant does not change its developer ID, so set this only when the key used to refer to the variant should change too. No text is lost or orphaned: text items and library components reference a variant by an internal id, not its developer ID. What has to be updated to match is outside Ditto — CLI output, integration configs, and code naming the old developer ID. Can be set alongside other field changes in the same update object."
                        },
                        "description": {
                          "type": "string",
                          "description": "New description for the variant. Pass an empty string to clear it. If not provided, unchanged."
                        },
                        "localeCode": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "af",
                            "ar",
                            "ar-ae",
                            "ar-bh",
                            "ar-dz",
                            "ar-eg",
                            "ar-iq",
                            "ar-jo",
                            "ar-kw",
                            "ar-lb",
                            "ar-ly",
                            "ar-ma",
                            "ar-om",
                            "ar-qa",
                            "ar-sa",
                            "ar-sy",
                            "ar-tn",
                            "ar-ye",
                            "az",
                            "be",
                            "bg",
                            "bs",
                            "ca",
                            "cs",
                            "cy",
                            "da",
                            "de",
                            "de-at",
                            "de-ch",
                            "de-li",
                            "de-lu",
                            "el",
                            "en",
                            "en-au",
                            "en-bz",
                            "en-ca",
                            "en-gb",
                            "en-ie",
                            "en-jm",
                            "en-nz",
                            "en-sg",
                            "en-tt",
                            "en-us",
                            "en-za",
                            "es",
                            "es-ar",
                            "es-bo",
                            "es-cl",
                            "es-co",
                            "es-cr",
                            "es-do",
                            "es-ec",
                            "es-gt",
                            "es-hn",
                            "es-mx",
                            "es-ni",
                            "es-pa",
                            "es-pe",
                            "es-pr",
                            "es-py",
                            "es-sv",
                            "es-uy",
                            "es-ve",
                            "et",
                            "eu",
                            "fa",
                            "fi",
                            "fo",
                            "fr",
                            "fr-be",
                            "fr-ca",
                            "fr-ch",
                            "fr-lu",
                            "ga",
                            "gd",
                            "he",
                            "hi",
                            "hr",
                            "hu",
                            "hy",
                            "id",
                            "is",
                            "it",
                            "it-ch",
                            "ja",
                            "ka",
                            "kk",
                            "ko",
                            "ku",
                            "lt",
                            "lv",
                            "mk",
                            "ml",
                            "ms",
                            "mt",
                            "nb",
                            "nl",
                            "nl-be",
                            "nn",
                            "no",
                            "pa",
                            "pl",
                            "pt",
                            "pt-br",
                            "rm",
                            "ro",
                            "ro-md",
                            "ru",
                            "ru-md",
                            "sk",
                            "sl",
                            "sq",
                            "sr",
                            "sv",
                            "sv-fi",
                            "th",
                            "tn",
                            "tr",
                            "ts",
                            "uk",
                            "ur",
                            "ve",
                            "vi",
                            "wen",
                            "xh",
                            "yi",
                            "zh-cn",
                            "zh-hk",
                            "zh-sg",
                            "zh-tw",
                            "zu",
                            null
                          ],
                          "description": "Locale code for the variant, from the set Ditto supports. Casing does not matter on the way in — 'fr-CA' and 'fr-ca' are both accepted — and the code is stored lowercase, which is the form reads return. Not every language-region pairing exists in the set, so pick one of the listed values rather than composing your own. At most one variant per workspace can hold a given locale code. Set this whenever the variant represents a language: translation tools treat it as the authoritative target locale. Moving a locale onto a different variant re-points the variant-scoped style guides and AI translation targeting that resolve a locale to a variant. Pass null to clear it. If not provided, unchanged."
                        }
                      },
                      "required": ["developerId"]
                    },
                    "minItems": 1,
                    "description": "Array of updates to variants"
                  }
                },
                "required": ["updates"],
                "example": {
                  "updates": [
                    {
                      "developerId": "spanish",
                      "description": "Spanish translations for Mexico",
                      "localeCode": "es-mx"
                    },
                    {
                      "developerId": "fr-ca",
                      "name": "French (Canada)",
                      "newDeveloperId": "french-canada"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: an update that changes nothing; the same value being claimed by two updates in one request; a reserved developer ID.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Duplicate new developer IDs in request: french-canada"
                }
              }
            }
          },
          "404": {
            "description": "Returned when a developer ID does not match any existing variant in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Variants not found: spanish"
                }
              }
            }
          },
          "409": {
            "description": "Returned when a name, developer ID, or locale code an update claims is already held by another variant in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the conflict"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Couldn't update variant \"spanish\": Variant with same name already exists!"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Variants"],
        "description": "Deletes variants from the workspace by their developer IDs. This can't be undone.",
        "summary": "Delete variants",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "developerIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the variants to delete. A variant can't be deleted while any text item or library component still has text for it, and one such variant rejects the whole batch. Style guides scoped to a deleted variant survive but stop being variant-scoped."
                  }
                },
                "required": ["developerIds"],
                "example": {
                  "developerIds": ["fr-ca"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a text item or library component still has text for a variant, or the variant is attached to a legacy project or component",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Can't delete variants while text items or library components still have text for them: fr-ca. Remove that text from every text item and library component first, then retry."
                }
              }
            }
          },
          "404": {
            "description": "Returned when a developer ID does not match any existing variant in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Variant not found: fr-ca"
                }
              }
            }
          }
        }
      }
    },
    "/styleguides": {
      "get": {
        "tags": ["Style guides"],
        "description": "Returns the style guides created in the workspace, with their sections and rules.\n\nEach rule includes its developer ID, which can be used with PATCH/DELETE /styleguides/rules. The built-in default style guide is not included.",
        "summary": "Get style guides",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated list of style guide developer IDs to return."
            },
            "required": false,
            "description": "Comma-separated list of style guide developer IDs to return.",
            "name": "developerIds",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "The workspace-created style guides.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "styleguides": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "developerId": {
                            "type": "string",
                            "description": "The style guide's developer ID."
                          },
                          "name": {
                            "type": "string",
                            "description": "The style guide's name."
                          },
                          "description": {
                            "type": "string",
                            "description": "The style guide's description."
                          },
                          "variant": {
                            "type": "object",
                            "nullable": true,
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The variant's developer ID."
                              },
                              "name": {
                                "type": "string",
                                "description": "The variant's name."
                              },
                              "localeCode": {
                                "type": "string",
                                "nullable": true,
                                "description": "BCP-47 locale code, or null."
                              }
                            },
                            "required": ["id", "name", "localeCode"],
                            "description": "The variant/locale this guide is scoped to, or null for a base guide."
                          },
                          "sections": {
                            "type": "array",
                            "items": {
                              "oneOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "sectionId": {
                                      "type": "string",
                                      "description": "The section's ID, used to attach rules to this section."
                                    },
                                    "name": {
                                      "type": "string",
                                      "description": "The section's name."
                                    },
                                    "kind": {
                                      "type": "string",
                                      "enum": ["rules"]
                                    },
                                    "rules": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "developerId": {
                                            "type": "string",
                                            "description": "The rule's developer ID. Use this to update or delete the rule."
                                          },
                                          "name": {
                                            "type": "string",
                                            "description": "The rule's name."
                                          },
                                          "description": {
                                            "type": "string",
                                            "description": "What the rule enforces."
                                          },
                                          "examples": {
                                            "type": "array",
                                            "items": {
                                              "type": "object",
                                              "properties": {
                                                "from": {
                                                  "type": "string",
                                                  "description": "Text that violates the rule."
                                                },
                                                "to": {
                                                  "type": "string",
                                                  "description": "Corrected version of the text."
                                                }
                                              },
                                              "required": ["from", "to"]
                                            },
                                            "description": "Before/after examples illustrating the rule."
                                          },
                                          "tags": {
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            },
                                            "description": "Tags scoping the rule to specific text surfaces; empty means it applies everywhere."
                                          }
                                        },
                                        "required": ["developerId", "name", "description", "examples", "tags"]
                                      }
                                    }
                                  },
                                  "required": ["sectionId", "name", "kind", "rules"],
                                  "title": "Rules section"
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "sectionId": {
                                      "type": "string",
                                      "description": "The section's ID, used to attach rules to this section."
                                    },
                                    "name": {
                                      "type": "string",
                                      "description": "The section's name."
                                    },
                                    "kind": {
                                      "type": "string",
                                      "enum": ["wordlist"]
                                    },
                                    "rules": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "developerId": {
                                            "type": "string",
                                            "description": "The entry's developer ID. Use this to update or delete the entry."
                                          },
                                          "term": {
                                            "type": "string",
                                            "description": "The preferred term this entry governs."
                                          },
                                          "disallowed": {
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            },
                                            "description": "Disallowed words or phrases that should be replaced with the term."
                                          },
                                          "description": {
                                            "type": "string",
                                            "description": "Guidance on when and why to use the term."
                                          },
                                          "tags": {
                                            "type": "array",
                                            "items": {
                                              "type": "string"
                                            },
                                            "description": "Tags scoping the entry to specific text surfaces; empty means it applies everywhere."
                                          }
                                        },
                                        "required": ["developerId", "term", "disallowed", "description", "tags"]
                                      }
                                    }
                                  },
                                  "required": ["sectionId", "name", "kind", "rules"],
                                  "title": "Word list section"
                                }
                              ]
                            },
                            "description": "The guide's sections, in display order, including empty ones."
                          }
                        },
                        "required": ["developerId", "name", "description", "variant", "sections"]
                      },
                      "description": "The style guides created in the workspace, with their sections and rules."
                    }
                  },
                  "required": ["styleguides"],
                  "example": {
                    "styleguides": [
                      {
                        "developerId": "product-guide",
                        "name": "Acme Inc.",
                        "description": "Voice and tone for Acme Inc. product text.",
                        "variant": null,
                        "sections": [
                          {
                            "sectionId": "foundations",
                            "name": "Foundations",
                            "kind": "rules",
                            "rules": [
                              {
                                "developerId": "be-concise",
                                "name": "Be concise",
                                "description": "Remove filler words so text is easy to scan.",
                                "examples": [
                                  {
                                    "from": "Please click the button below",
                                    "to": "Click below"
                                  }
                                ],
                                "tags": []
                              }
                            ]
                          },
                          {
                            "sectionId": "word-list",
                            "name": "Word List",
                            "kind": "wordlist",
                            "rules": [
                              {
                                "developerId": "ai-agent",
                                "term": "AI agent",
                                "disallowed": ["Bot"],
                                "description": "Use 'AI agent' instead of 'bot'.",
                                "tags": []
                              }
                            ]
                          }
                        ]
                      },
                      {
                        "developerId": "marketing-guide",
                        "name": "French",
                        "description": "Localized guidance for French text.",
                        "variant": {
                          "id": "french",
                          "name": "French",
                          "localeCode": "fr-FR"
                        },
                        "sections": []
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Style guides"],
        "description": "Creates a new style guide in your workspace.\n\nUse POST /styleguides/rules afterward to add rules to a section.",
        "summary": "Create a style guide",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The name of the new style guide."
                  },
                  "description": {
                    "type": "string",
                    "minLength": 1,
                    "description": "A description of the style guide's purpose."
                  },
                  "sections": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sectionId": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "kind": {
                          "type": "string",
                          "enum": ["rules", "wordlist"]
                        }
                      },
                      "required": ["sectionId", "name", "kind"]
                    },
                    "description": "Sections to organize rules and word list entries into. If omitted, a default set of sections is used.\n\nEach section's sectionId must be unique within the style guide, and the list must include at least one 'rules' section and one 'wordlist' section."
                  },
                  "enabledByDefault": {
                    "type": "boolean",
                    "description": "Whether this style guide is enabled by default for all projects. Defaults to true."
                  },
                  "variantId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Developer ID of a variant to scope this style guide to — its rules then apply only to text in that variant. Currently, this is only supported for variants with a locale code. Omit for a style guide that should apply to all text.\n\nScoping a style guide to a variant is how it's associated with a locale, because a locale in Ditto is a variant's locale code. Use GET /v2/variants to find the variant whose locale code matches the locale you want, rather than inferring it from the variant's name."
                  }
                },
                "required": ["name", "description"],
                "example": {
                  "name": "Acme Inc.",
                  "description": "Voice and tone for Acme Inc. product text.",
                  "sections": [
                    {
                      "sectionId": "foundations",
                      "name": "Foundations",
                      "kind": "rules"
                    },
                    {
                      "sectionId": "word-list",
                      "name": "Word List",
                      "kind": "wordlist"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the developer ID and name of the created style guide",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The Developer ID of the created style guide"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name of the created style guide"
                    }
                  },
                  "required": ["id", "name"],
                  "example": {
                    "id": "acme-inc",
                    "name": "Acme Inc."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes:\n- a missing required field (name or description)\n- sections missing a 'rules' or 'wordlist' section\n- duplicate sectionIds within the sections list\n- a variantId that doesn't have a locale code",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "At least one wordlist section is required"
                }
              }
            }
          },
          "404": {
            "description": "Returned when variantId does not match any variant in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Variant with developer ID 'french' not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Style guides"],
        "description": "Updates a style guide's name, description, enabled-by-default setting, or sections.\n\nEach style guide is identified by its developer ID. Only provided fields are modified.",
        "summary": "Update a style guide",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "developerId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Developer ID of the style guide to update. Use 'default' to update the built-in Ditto Style Guide's enabled-by-default setting."
                  },
                  "newDeveloperId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "A new developer ID for this style guide. Must be unique among the workspace's style guides. Can be set alongside other field changes in the same update. Not supported for the built-in Ditto Style Guide."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "description": "New name for the style guide. If not provided, name remains unchanged."
                  },
                  "description": {
                    "type": "string",
                    "minLength": 1,
                    "description": "New description for the style guide. If not provided, description remains unchanged."
                  },
                  "enabledByDefault": {
                    "type": "boolean",
                    "description": "Whether this style guide is enabled by default for all projects."
                  },
                  "variantId": {
                    "type": "string",
                    "nullable": true,
                    "minLength": 1,
                    "description": "Developer ID of a variant to scope this style guide to — its rules then apply only to text in that variant. Currently, this is only supported for variants with a locale code. Pass null to clear the variant so the style guide applies to all text. If not provided, the variant is unchanged.\n\nScoping a style guide to a variant is how it's associated with a locale, because a locale in Ditto is a variant's locale code. Use GET /v2/variants to find the variant whose locale code matches the locale you want, rather than inferring it from the variant's name."
                  },
                  "sections": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sectionId": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "kind": {
                          "type": "string",
                          "enum": ["rules", "wordlist"]
                        }
                      },
                      "required": ["sectionId", "name", "kind"]
                    },
                    "description": "Full replacement list of sections — the array you pass replaces all existing sections.\n\nEach section's sectionId must be unique within the style guide, and the list must include at least one 'rules' section and one 'wordlist' section. Rules belonging to a removed section are automatically moved to the first remaining rules section."
                  }
                },
                "required": ["developerId"],
                "example": {
                  "developerId": "acme-inc",
                  "name": "Acme Inc. Style Guide"
                }
              },
              "examples": {
                "rename": {
                  "summary": "Rename a style guide",
                  "value": {
                    "developerId": "acme-inc",
                    "name": "Acme Inc. Style Guide"
                  }
                },
                "toggle_enabled": {
                  "summary": "Toggle whether it's enabled by default",
                  "value": {
                    "developerId": "acme-inc",
                    "enabledByDefault": false
                  }
                },
                "toggle_default_guide": {
                  "summary": "Toggle the built-in Ditto Style Guide",
                  "value": {
                    "developerId": "default",
                    "enabledByDefault": false
                  }
                },
                "update_sections": {
                  "summary": "Replace the sections list",
                  "value": {
                    "developerId": "acme-inc",
                    "sections": [
                      {
                        "sectionId": "foundations",
                        "name": "Foundations",
                        "kind": "rules"
                      },
                      {
                        "sectionId": "word-list",
                        "name": "Word List",
                        "kind": "wordlist"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes:\n- no fields provided to update\n- a sections update missing a 'rules' or 'wordlist' section\n- duplicate sectionIds within the sections list\n- a variantId that doesn't have a locale code",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "At least one wordlist section is required"
                }
              }
            }
          },
          "404": {
            "description": "Returned when the developer ID does not match any style guide in the workspace, or variantId does not match any variant in it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Style guide with developer ID 'acme-inc' not found"
                }
              }
            }
          }
        }
      }
    },
    "/styleguides/rules": {
      "post": {
        "tags": ["Style guides"],
        "description": "Creates one or more rules in a style guide section.\n\nThe operation is all-or-nothing: if any rule is invalid, none are created.",
        "summary": "Create style guide rules",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "styleguideId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Developer ID of the style guide to attach the rules to (from GET /styleguides)."
                  },
                  "sectionId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "ID of the section within the style guide to attach the rules to (from GET /styleguides)."
                  },
                  "rules": {
                    "anyOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "description": {
                              "type": "string",
                              "description": "What the rule or entry represents. Defaults to an empty string."
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Tags scoping the rule or entry to specific text surfaces; empty means it applies everywhere."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Whether the rule is enabled. Defaults to true."
                            },
                            "name": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The rule's name. (rules sections)"
                            },
                            "examples": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "from": {
                                    "type": "string",
                                    "description": "Text that violates the rule."
                                  },
                                  "to": {
                                    "type": "string",
                                    "description": "Corrected version of the text."
                                  }
                                },
                                "required": ["from", "to"]
                              },
                              "description": "Before/after examples illustrating the rule. Defaults to an empty array."
                            }
                          },
                          "required": ["name"],
                          "additionalProperties": false
                        },
                        "minItems": 1,
                        "title": "Rules"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "description": {
                              "type": "string",
                              "description": "What the rule or entry represents. Defaults to an empty string."
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Tags scoping the rule or entry to specific text surfaces; empty means it applies everywhere."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Whether the rule is enabled. Defaults to true."
                            },
                            "term": {
                              "type": "string",
                              "minLength": 1,
                              "description": "The preferred term this entry governs. (wordlist sections)"
                            },
                            "disallowed": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Disallowed words or phrases that should be replaced with the term. Defaults to an empty array."
                            }
                          },
                          "required": ["term"],
                          "additionalProperties": false
                        },
                        "minItems": 1,
                        "title": "Word list rules"
                      }
                    ],
                    "description": "The rules to create — every item must use the same shape: {name, description, examples, tags, enabled} for a 'rules' section, or {term, disallowed, description, tags, enabled} for a 'wordlist' section. The shape must also match the target section's kind."
                  }
                },
                "required": ["styleguideId", "sectionId", "rules"],
                "example": {
                  "styleguideId": "acme-inc",
                  "sectionId": "foundations",
                  "rules": [
                    {
                      "name": "Be concise",
                      "description": "Remove filler words so text is easy to scan.",
                      "examples": [
                        {
                          "from": "Please click the button below",
                          "to": "Click below"
                        }
                      ],
                      "tags": []
                    }
                  ]
                }
              },
              "examples": {
                "create_style_rules": {
                  "summary": "Create rules in a 'rules' section",
                  "value": {
                    "styleguideId": "acme-inc",
                    "sectionId": "foundations",
                    "rules": [
                      {
                        "name": "Be concise",
                        "description": "Remove filler words so text is easy to scan.",
                        "examples": [
                          {
                            "from": "Please click the button below",
                            "to": "Click below"
                          }
                        ]
                      },
                      {
                        "name": "Use sentence case for headings",
                        "enabled": false
                      }
                    ]
                  }
                },
                "create_wordlist_entries": {
                  "summary": "Create entries in a 'wordlist' section",
                  "value": {
                    "styleguideId": "acme-inc",
                    "sectionId": "word-list",
                    "rules": [
                      {
                        "term": "AI agent",
                        "disallowed": ["bot", "chatbot"],
                        "description": "Use 'AI agent' instead of 'bot'."
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns the Developer IDs of the created rules, in request order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Developer IDs of the created rules, in request order."
                    }
                  },
                  "required": ["ids"],
                  "example": {
                    "ids": ["be-concise"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: an empty rules array, a rule missing its required field ('name' for a 'rules' section, 'term' for a 'wordlist' section), or a rule shape that doesn't match the target section's kind.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Section 'word-list' is a wordlist; each entry must provide 'term' (and optional 'disallowed')."
                }
              }
            }
          },
          "404": {
            "description": "Returned when the style guide developer ID or section ID does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Style guide with developer ID 'acme-inc' not found"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": ["Style guides"],
        "description": "Updates a set of style guide rules, each identified by its Developer ID.\n\nOnly provided fields are modified. The operation is all-or-nothing: if any update is invalid, none are applied.",
        "summary": "Update style guide rules",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "updates": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "ruleId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Developer ID of the rule to update (from POST /styleguides/rules or GET /styleguides)."
                            },
                            "description": {
                              "type": "string",
                              "description": "Updated description. If not provided, description remains unchanged."
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Replaces all existing tags."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Whether the rule is enabled."
                            },
                            "name": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Updated name. Only valid for rules in a 'rules' section."
                            },
                            "examples": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "from": {
                                    "type": "string",
                                    "description": "Text that violates the rule."
                                  },
                                  "to": {
                                    "type": "string",
                                    "description": "Corrected version of the text."
                                  }
                                },
                                "required": ["from", "to"]
                              },
                              "description": "Replaces all existing examples. Only valid for rules in a 'rules' section."
                            }
                          },
                          "required": ["ruleId"],
                          "additionalProperties": false,
                          "title": "Rule"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "ruleId": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Developer ID of the rule to update (from POST /styleguides/rules or GET /styleguides)."
                            },
                            "description": {
                              "type": "string",
                              "description": "Updated description. If not provided, description remains unchanged."
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Replaces all existing tags."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Whether the rule is enabled."
                            },
                            "term": {
                              "type": "string",
                              "minLength": 1,
                              "description": "Updated preferred term. Only valid for rules in a 'wordlist' section."
                            },
                            "disallowed": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Replaces all existing disallowed words/phrases. Only valid for rules in a 'wordlist' section."
                            }
                          },
                          "required": ["ruleId"],
                          "additionalProperties": false,
                          "title": "Word list rule"
                        }
                      ]
                    },
                    "minItems": 1,
                    "description": "Rules to update, identified by ruleId. Only provided fields are changed. Use 'name'/'examples' for a rule in a 'rules' section, or 'term'/'disallowed' for a rule in a 'wordlist' section — the shape must match that rule's own section."
                  }
                },
                "required": ["updates"],
                "example": {
                  "updates": [
                    {
                      "ruleId": "be-concise",
                      "description": "Updated description"
                    }
                  ]
                }
              },
              "examples": {
                "update_style_rule": {
                  "summary": "Update a rule in a 'rules' section",
                  "value": {
                    "updates": [
                      {
                        "ruleId": "be-concise",
                        "name": "Be extremely concise",
                        "examples": [
                          {
                            "from": "Please click the button below",
                            "to": "Click below"
                          }
                        ]
                      }
                    ]
                  }
                },
                "update_wordlist_entry": {
                  "summary": "Update an entry in a 'wordlist' section",
                  "value": {
                    "updates": [
                      {
                        "ruleId": "ai-agent",
                        "term": "AI agent",
                        "disallowed": ["bot", "chatbot", "virtual assistant"]
                      }
                    ]
                  }
                },
                "disable_rule": {
                  "summary": "Disable a rule without deleting it",
                  "value": {
                    "updates": [
                      {
                        "ruleId": "be-concise",
                        "enabled": false
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the update operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the update was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation. Common causes include: providing both 'name' and 'term' (or both 'examples' and 'disallowed') for the same update, or a field that doesn't match the rule's own section kind (e.g. 'term' for a rule in a 'rules' section).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Rule 'be-concise' is in a rules section; use 'name'/'examples' instead of 'term'/'disallowed'."
                }
              }
            }
          },
          "404": {
            "description": "Returned when a ruleId does not match any rule in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Rule id not found: missing-rule"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": ["Style guides"],
        "description": "Deletes style guide rules by their Developer IDs.\n\nThis cannot be undone. The operation is all-or-nothing: if any ruleId does not exist, none are deleted.",
        "summary": "Delete style guide rules",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ruleIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "description": "Developer IDs of the rules to delete (from POST /styleguides/rules or GET /styleguides)."
                  }
                },
                "required": ["ruleIds"],
                "example": {
                  "ruleIds": ["be-concise", "ai-agent"]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Returns success status of the deletion operation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "description": "Indicates whether the deletion was successful"
                    }
                  },
                  "required": ["success"],
                  "example": {
                    "success": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when the request body fails validation, for example an empty ruleIds array.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Invalid 'ruleIds' input: Must have at least one rule ID."
                }
              }
            }
          },
          "404": {
            "description": "Returned when a ruleId does not match any rule in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Rule id not found: missing-rule"
                }
              }
            }
          }
        }
      }
    },
    "/activity": {
      "get": {
        "tags": ["Activity"],
        "description": "Returns a paginated list of activity items (change events) in your workspace, optionally filtered by project, text item, library component, or entity type.",
        "summary": "Fetch activity",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated list of project developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters)."
            },
            "required": false,
            "description": "Comma-separated list of project developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters).",
            "name": "projectIds",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated list of text item developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters)."
            },
            "required": false,
            "description": "Comma-separated list of text item developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters).",
            "name": "textItemIds",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated list of library component developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters)."
            },
            "required": false,
            "description": "Comma-separated list of library component developer IDs to filter activity for. Activity matching any of the provided project, text item, or component IDs is included (OR logic across all three ID filters).",
            "name": "componentIds",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["textItem", "component", "variant", "variable"],
              "description": "Narrows results to a single entity type (AND logic with the ID filters). One of: `textItem` (text item changes), `component` (library component changes), `variant` (variant changes on text items or components), `variable` (variable changes). When combined with `projectIds`, `textItemIds`, or `componentIds`, only activity that matches both the ID filters and this entity type is returned."
            },
            "required": false,
            "description": "Narrows results to a single entity type (AND logic with the ID filters). One of: `textItem` (text item changes), `component` (library component changes), `variant` (variant changes on text items or components), `variable` (variable changes). When combined with `projectIds`, `textItemIds`, or `componentIds`, only activity that matches both the ID filters and this entity type is returned.",
            "name": "entityType",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Maximum number of activity items to return (default: 50, max: 200)"
            },
            "required": false,
            "description": "Maximum number of activity items to return (default: 50, max: 200)",
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "The `nextCursor` value from a previous response, used to fetch the next page"
            },
            "required": false,
            "description": "The `nextCursor` value from a previous response, used to fetch the next page",
            "name": "cursor",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Returns a paginated list of activity items matching the requested filters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "activity": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "The type of change that occurred"
                          },
                          "date": {
                            "type": "string",
                            "description": "ISO 8601 timestamp of when the change occurred"
                          },
                          "user": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "Display name of the user who made the change"
                              },
                              "email": {
                                "type": "string",
                                "nullable": true,
                                "description": "Email address of the user who made the change, or null if not available"
                              }
                            },
                            "required": ["name", "email"]
                          },
                          "projectId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Developer ID of the project this change belongs to, or null if not project-scoped"
                          },
                          "textItemIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Developer IDs of text items affected by this change"
                          },
                          "componentId": {
                            "type": "string",
                            "nullable": true,
                            "description": "Developer ID of the library component affected by this change, or null if not component-scoped"
                          },
                          "data": {
                            "nullable": true,
                            "description": "Change-type-specific data payload"
                          }
                        },
                        "required": ["type", "date", "user", "projectId", "textItemIds", "componentId"]
                      },
                      "description": "List of activity items matching the requested filters"
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true,
                      "description": "Opaque cursor for fetching the next page of results. Pass as the `cursor` query parameter in the next request. Null if there are no more results."
                    }
                  },
                  "required": ["activity", "nextCursor"],
                  "example": {
                    "activity": [
                      {
                        "type": "edit",
                        "date": "2024-06-01T12:34:56.000Z",
                        "user": {
                          "name": "Alice"
                        },
                        "projectId": "my-project",
                        "textItemIds": ["welcome-header"],
                        "componentId": null,
                        "data": {}
                      }
                    ],
                    "nextCursor": "NmExODU2MmI3ZDllMDAyNzk5OTk1ZWVi"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Returned when a provided developer ID does not match any resource in the workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Error message describing the validation failure"
                    }
                  },
                  "required": ["message"]
                },
                "example": {
                  "message": "Project id not found: nonexistent-project"
                }
              }
            }
          }
        }
      }
    }
  }
}
