POST a small JSON description and get back a deck-ready PNG (or SVG). The endpoint is open and CORS-enabled, so it works from browsers, scripts, CI and anywhere else you can make an HTTP call. The same JSON opens in the builder.
| Field | Type | Description |
|---|---|---|
| title | string | Heading shown top-left of the chart at 22px bold. Every chart has one title row; an empty string hides it. max 140 chars · default "Issue tree" |
| rootrequired | node | The key question, problem or top-line metric on the left (e.g. "Why has profitability declined?" or "Operating profit"), with its drivers nested in `children`. Limits: 4 levels in total including the root, up to 6 children per box and 40 boxes; extras are dropped with a warning, deepest levels and last-listed boxes first. |
| levels | string[] | Optional column labels, left to right, printed in small caps above each level, e.g. ["Key question", "Drivers", "Sub-drivers", "Hypotheses"] (0–4). Omit for none. max 4 items |
| numbered | boolean | Prefix every box below the root with its outline number, 1, 1.1, 1.1.1, as consultants number issue trees. Default false. default false |
| width | integer | Chart width in pixels (640–2400). Omit it (recommended) and the chart sizes itself to its content with comfortable margins, between 880 and 1280px wide. PNG output renders at 2x. 640–2400 |
| palette | string[] | Hex colours applied in order to items that have no colour of their own. Pass the user's brand colours here when they name them. Default: indigo, sky, emerald, amber, red, gray. max 12 items · default ["#4f46e5","#0ea5e9","#10b981","#f59e0b","#ef4444","#6b7280"] |
| Field | Type | Description |
|---|---|---|
| namerequired | string | The box label, e.g. "Revenue", "Price per unit" or "Are we losing customers?". Wraps onto three lines, then truncates; keep it to a few words. max 80 chars |
| value | string | Optional figure shown as a second line in bold, e.g. "$12.4m", "+3% YoY" or "4,200". Free text, so units and signs are up to you. Omit for none. max 30 chars |
| operator | string | Optional: how this box's children combine into it, drawn as + − × ÷ in a small circle where the connector meets the children's spine (the KPI or value driver tree convention). "+" add, "-" subtract, "x" multiply, "/" divide; e.g. Revenue with "x" over Customers and Revenue per customer. Omit for a plain issue tree. "+", "-", "x", "/" |
| color | string | Optional hex colour for this box and everything under it, e.g. "#10b981". Without one, colour is automatic: the root takes the first palette colour, each first-level branch the next one, and deeper boxes inherit their branch's colour. max 40 chars |
| children | node[] | The drivers, causes or sub-questions under this box, top to bottom (up to 6). Ideally mutually exclusive and collectively exhaustive (MECE). max 6 items |
POST /api/render/issuetree returns image/png; add ?format=svg for SVG.GET /issuetree.png?d=<payload> and /issuetree.svg?d=<payload> render a chart from a link. The payload is the JSON body, raw-deflated and base64url-encoded. Nothing is stored: links are permanent and cached for a year./issuetree#d=<payload> opens the same chart in the builder for editing.GET /api/render/issuetree?demo=1 returns the demo chart.GET /api/schema/issuetree returns the JSON Schema, for code generators and AIs.Input is lenient where the intent is clear: numeric strings become numbers, out-of-range values are clamped, and unknown fields are ignored. Adjustments are listed in the X-Render-Warnings header. Anything unclear returns a 400 that says how to fix it:
{
"error": "Invalid payload",
"issues": [{ "path": "tasks", "message": "must be an array" }],
"example": { … }
}
Use the hosted MCP server instead. It gives Claude, Cursor and other MCP clients a create_issue_tree tool that returns the image plus image, SVG and edit links. See the MCP page →