{
  "openapi": "3.1.1",
  "info": {
    "title": "Sketchboard draw.io to SVG API",
    "version": "1.0.0",
    "summary": "Convert a draw.io (diagrams.net) or Excalidraw file into a clean SVG and an editable board.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://sketchboarddrawiotosvg.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Convert a draw.io (diagrams.net) or Excalidraw file into a clean SVG and an editable board.",
        "description": "Reads a .drawio / diagrams.net XML file (plain or compressed pages) or an Excalidraw .excalidraw file, maps shapes, connectors, arrowheads, labels and styles to Sketchboard, and returns a standalone SVG plus a Sketchboard board you can keep editing. It lists what was mapped and what was drawn as a plain shape.\n\nMethodology:\n- Compressed pages are decoded the way diagrams.net writes them: base64 → raw DEFLATE (RFC 1951, inflated by the platform’s own decoder with a 30 MB cap) → URI-decoding → XML. Plain pages are read directly. No DTDs or external entities are processed.\n- Every mxCell with vertex=\"1\" becomes a shape at its mxGeometry (children of groups and containers are offset by their parents). The style’s shape name or first keyword picks the Sketchboard shape (ellipse, rhombus → diamond, cylinder3 → cylinder, process → predefined process, mxgraph.flowchart.* → the matching flowchart shape, note, actor, cloud, document …); unknown shapes are drawn as rectangles and listed in the warnings.\n- Edges (edge=\"1\") become connectors glued to their source and target; exitX/exitY and entryX/entryY on a side become that port. edgeStyle=orthogonal/elbow → elbow route around shapes, curved=1 → curved, otherwise straight; waypoints are kept. Arrowheads map by name (classic/block → triangle, open → arrow, oval → circle, diamond, ER crow’s feet …; endFill=0 → the open variant).\n- Styles: fillColor, strokeColor, strokeWidth, dashed, opacity, rotation, fontColor, fontSize (× 1.15 for the larger default type), align. HTML labels keep their text with line breaks; markup is removed.\n- Excalidraw: rectangles, ellipses, diamonds, bound text (as the shape’s label), text, arrows and lines with bindings and arrowheads, freedraw strokes and frames are imported; roughness above 0 on most elements switches the board to the hand-drawn style. Images and embeds are skipped and counted.\n- The SVG is drawn by Sketchboard’s renderer, so line jitter in the hand-drawn style is seeded by the element ids and identical on every run.\n\ndraw.io and diagrams.net are trademarks of JGraph Ltd; Excalidraw is a trademark of its owners. Sketchboard reads files you provide and is not affiliated with either project. Shape libraries are not copied: unknown stencils become plain rectangles.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "sketchboard_drawio_to_svg",
        "x-owner-app": "sketchboard",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SketchboardDrawioToSvgInput"
              },
              "examples": {
                "example1": {
                  "summary": "Order handling flow (plain draw.io XML)",
                  "value": {
                    "diagram": "\u003cmxfile host=\"Sketchboard sample\"\u003e\u003cdiagram id=\"p1\" name=\"Order handling\"\u003e\u003cmxGraphModel dx=\"800\" dy=\"600\" grid=\"1\" gridSize=\"10\"\u003e\u003croot\u003e\u003cmxCell id=\"0\"/\u003e\u003cmxCell id=\"1\" parent=\"0\"/\u003e\u003cmxCell id=\"a\" value=\"Order received\" style=\"rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"40\" y=\"40\" width=\"140\" height=\"60\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"b\" value=\"In stock?\" style=\"rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"50\" y=\"150\" width=\"120\" height=\"80\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"c\" value=\"Pack and\u0026lt;br\u0026gt;ship\" style=\"shape=process;whiteSpace=wrap;html=1;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"40\" y=\"290\" width=\"140\" height=\"60\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"d\" value=\"Order from supplier\" style=\"shape=document;whiteSpace=wrap;html=1;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"260\" y=\"160\" width=\"140\" height=\"60\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"e\" value=\"Stock DB\" style=\"shape=cylinder3;whiteSpace=wrap;html=1;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"280\" y=\"20\" width=\"80\" height=\"90\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"f\" value=\"Delivery note\" style=\"text;html=1;align=left;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"200\" y=\"305\" width=\"120\" height=\"30\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"e1\" style=\"edgeStyle=orthogonalEdgeStyle;html=1;endArrow=classic;\" edge=\"1\" parent=\"1\" source=\"a\" target=\"b\"\u003e\u003cmxGeometry relative=\"1\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"e2\" value=\"yes\" style=\"edgeStyle=orthogonalEdgeStyle;html=1;\" edge=\"1\" parent=\"1\" source=\"b\" target=\"c\"\u003e\u003cmxGeometry relative=\"1\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"e3\" value=\"no\" style=\"html=1;endArrow=block;endFill=0;dashed=1;\" edge=\"1\" parent=\"1\" source=\"b\" target=\"d\"\u003e\u003cmxGeometry relative=\"1\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003cmxCell id=\"e4\" style=\"curved=1;html=1;endArrow=oval;startArrow=diamondThin;startFill=0;\" edge=\"1\" parent=\"1\" source=\"b\" target=\"e\"\u003e\u003cmxGeometry relative=\"1\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003c/root\u003e\u003c/mxGraphModel\u003e\u003c/diagram\u003e\u003c/mxfile\u003e"
                  }
                },
                "example2": {
                  "summary": "The same diagram, compressed, in hand-drawn style",
                  "value": {
                    "diagram": "\u003cmxfile host=\"Sketchboard sample\" compressed=\"true\"\u003e\u003cdiagram id=\"p1\" name=\"Order handling\"\u003eUzV2zq1wL0osyPDNT0nNUTUySKlQNXZRNTKyMDAAkiCBSoiAGUwgvSgzBSJkiBAIzqxKhQqClRm7Ao0uys8vgbByK5xTc0DGw7RCzHLDIQs1uCCxKDUPaAJhDYkQDWWJOaVQZ/gXpaQWAYWKUpNTM8tSUyAKiksqc6AKivJL81KA4sYuhqrGTuUZmSWpwQWJySDZcmCAAMUySnJzoNJpmTk5zvk5+UVgvcYpiakWaclA8eKSovzsVCQZs2SL1KQ0oAzUQalFJanQEMXiKbAQ1Efuqfm5qSVFlUAlUA0m0ACHRgCMW56ZUpIB1Q8Ty0jNTM+AGmoGFUsshvDT4QYjAhDIgIYh9vBMwghPzzxw8OUnZ6sau2EGZkZ+blIp0EISAzItLc0oGWtAppglmZmaUScgTVED0hDGRw5JaAJDCUkLKoRkMkZIBiQCwxBoaB4wTZrlAK1ySgImVLN0EKs4I7MAI3CLMxILQMyCovzk1GIiApn6ac/Iko6JD5pXsWTmtKL8XFDYlBYU5GSCRHCEVEp+cmku2Kd0CCq4n2HJC8anR1ilYoRVMDiPGhm4QP2GJXiSK3MygWVfkTF9wgeWjWBpCTN4YCqQQweW4igJnTSM0HFJzQHWBmDn5eWXQEMPKYiA3gSlGqQQSMzJTM8DsnNS00Ay1AgQWE0KDRBjA1PiyiNjaiQYqHOR/Jyakp4aDOXmF5Vk5Kfn5yXmuCJEkYMjNS/FsagovxyUjHISi4szQaU3xEiQOfiDBGhtfmkROKkhKu2SxKL0VKgqcL2DGXBFqTmJJcB4QzGKolAAKkVLGZWpxZSFDHmBAK1pkQMBXGXQIxCMMQIhLx8jDLDHfVIOuCUAEnIDVulAEQMgLyWxOAPepKJaeIDrA3qEhwmG55NLi0BtR4iHsIdEPjD4wA2YxKISmFhKZmJufl5KSEYmsOSASCGFEtUCBlx8UT9ggFxEyx0sh9RDMHYFAA==\u003c/diagram\u003e\u003cdiagram id=\"p2\" name=\"Notes\"\u003e\u003cmxGraphModel\u003e\u003croot\u003e\u003cmxCell id=\"0\"/\u003e\u003cmxCell id=\"1\" parent=\"0\"/\u003e\u003cmxCell id=\"n\" value=\"Second page\" style=\"shape=note;\" vertex=\"1\" parent=\"1\"\u003e\u003cmxGeometry x=\"0\" y=\"0\" width=\"160\" height=\"80\" as=\"geometry\"/\u003e\u003c/mxCell\u003e\u003c/root\u003e\u003c/mxGraphModel\u003e\u003c/diagram\u003e\u003c/mxfile\u003e",
                    "style": "sketchy"
                  }
                },
                "example3": {
                  "summary": "An Excalidraw drawing",
                  "value": {
                    "diagram": "{\"type\":\"excalidraw\",\"version\":2,\"source\":\"sketchboard-sample\",\"elements\":[{\"id\":\"r1\",\"type\":\"rectangle\",\"x\":0,\"y\":0,\"width\":160,\"height\":70,\"angle\":0,\"strokeColor\":\"#1e1e1e\",\"backgroundColor\":\"#a5d8ff\",\"fillStyle\":\"hachure\",\"strokeWidth\":2,\"strokeStyle\":\"solid\",\"roughness\":1,\"opacity\":100,\"roundness\":{\"type\":3},\"groupIds\":[],\"isDeleted\":false},{\"id\":\"t1\",\"type\":\"text\",\"x\":20,\"y\":22,\"width\":120,\"height\":25,\"text\":\"Idea\",\"fontSize\":20,\"fontFamily\":1,\"textAlign\":\"center\",\"strokeColor\":\"#1e1e1e\",\"containerId\":\"r1\",\"isDeleted\":false},{\"id\":\"e1\",\"type\":\"ellipse\",\"x\":260,\"y\":-10,\"width\":140,\"height\":90,\"angle\":0,\"strokeColor\":\"#1e1e1e\",\"backgroundColor\":\"#b2f2bb\",\"strokeWidth\":2,\"strokeStyle\":\"dashed\",\"roughness\":1,\"opacity\":100,\"isDeleted\":false},{\"id\":\"a1\",\"type\":\"arrow\",\"x\":160,\"y\":35,\"width\":100,\"height\":0,\"points\":[[0,0],[100,0]],\"strokeColor\":\"#1e1e1e\",\"strokeWidth\":2,\"roughness\":1,\"opacity\":100,\"startArrowhead\":null,\"endArrowhead\":\"arrow\",\"startBinding\":{\"elementId\":\"r1\"},\"endBinding\":{\"elementId\":\"e1\"},\"isDeleted\":false},{\"id\":\"f1\",\"type\":\"freedraw\",\"x\":40,\"y\":120,\"width\":120,\"height\":20,\"points\":[[0,0],[30,12],[60,2],[90,16],[120,4]],\"strokeColor\":\"#e03131\",\"strokeWidth\":2,\"roughness\":1,\"opacity\":100,\"isDeleted\":false},{\"id\":\"x1\",\"type\":\"text\",\"x\":260,\"y\":110,\"width\":160,\"height\":25,\"text\":\"Prototype\",\"fontSize\":20,\"fontFamily\":1,\"textAlign\":\"left\",\"strokeColor\":\"#1e1e1e\",\"isDeleted\":false},{\"id\":\"gone\",\"type\":\"rectangle\",\"x\":0,\"y\":0,\"width\":10,\"height\":10,\"isDeleted\":true}],\"appState\":{\"viewBackgroundColor\":\"#ffffff\"}}",
                    "style": "file"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SketchboardDrawioToSvgResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "SketchboardDrawioToSvgInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "diagram": {
            "title": "draw.io or Excalidraw file content",
            "description": "Paste the XML of a .drawio file (or the JSON of an .excalidraw file), or upload the file below.",
            "type": "string",
            "maxLength": 8000000,
            "default": ""
          },
          "diagramFile": {
            "title": "File (optional)",
            "description": "Used instead of the pasted text when given. Upload as {filename, contentType?, contentBase64}. Max 11719 KiB. Accepts .drawio,.xml,.excalidraw,.json,application/xml,text/xml,application/json.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "page": {
            "title": "Page number (files with several pages)",
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 1
          },
          "style": {
            "title": "Drawing style",
            "type": "string",
            "enum": [
              "clean",
              "sketchy",
              "file"
            ],
            "default": "clean"
          }
        },
        "required": []
      },
      "SketchboardDrawioToSvgResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}