Examples
Ready-to-use DSP scene documents, one per diagram family plus a few showing the element primitives agents reach for most. Every example sets layoutStrategy on the scene and omits layout on elements - the pattern recommended by the Agent Usage Guide. Paste any of these into the playground or send them via the API.
Building an agent integration? See How AI Agents Should Use Zindex for the full recommended workflow. Agents using MCP should install
@zindex-ai/mcpand calldsp_create_scenewith any of these as the scene document.
Architecture diagram
A service architecture. The engine positions nodes, routes edges, and places labels - you describe the graph.
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "service-arch",
"title": "Service Architecture",
"canvas": { "width": 900, "height": 360 }
},
"elements": [
{ "id": "client", "kind": "node", "nodeType": "actor", "shape": "roundedRect", "label": "Client" },
{ "id": "api", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "API Gateway" },
{ "id": "cache", "kind": "node", "nodeType": "storage", "shape": "roundedRect", "label": "Redis Cache" },
{ "id": "db", "kind": "node", "nodeType": "database", "shape": "cylinder", "label": "PostgreSQL" },
{ "id": "worker", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Worker" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "client" }, "to": { "elementId": "api" } },
{ "id": "e2", "kind": "edge", "from": { "elementId": "api" }, "to": { "elementId": "cache" }, "label": "read/write" },
{ "id": "e3", "kind": "edge", "from": { "elementId": "api" }, "to": { "elementId": "db" }, "label": "queries" },
{ "id": "e4", "kind": "edge", "from": { "elementId": "db" }, "to": { "elementId": "worker" }, "label": "events" }
]
}
No layout on any element. The hierarchical planner walks the edge graph, assigns nodes to ranks (columns in LR), minimizes crossings, and places them with orthogonal edge routing.
Workflow / BPMN
A BPMN approval flow. Setting diagramFamily: "workflow" activates BPMN-correct shapes and arrows: workflow.start renders as a circle, workflow.gateway as a diamond with an x marker, workflow.end as a bold-stroke circle, and workflow.sequenceFlow edges get triangle arrowheads. Use workflow.decision for a marker-less decision diamond instead - its label renders inside the diamond (Mermaid / draw.io flowchart convention), where workflow.gateway* types render the label outside beside the marker glyph.
{
"schemaVersion": "0.1",
"diagramFamily": "workflow",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "approval-flow",
"title": "Approval Flow",
"canvas": { "width": 900, "height": 240 }
},
"elements": [
{ "id": "start", "kind": "node", "nodeType": "workflow.start", "shape": "ellipse", "label": "Submitted" },
{ "id": "review", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Review" },
{ "id": "gate", "kind": "node", "nodeType": "workflow.gateway", "shape": "diamond", "label": "OK?" },
{ "id": "approve", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Notify Approver" },
{ "id": "reject", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Notify Rejection" },
{ "id": "done", "kind": "node", "nodeType": "workflow.end", "shape": "ellipse", "label": "Done" },
{ "id": "e1", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "start" }, "to": { "elementId": "review" } },
{ "id": "e2", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "review" }, "to": { "elementId": "gate" } },
{ "id": "e3", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "gate" }, "to": { "elementId": "approve" }, "label": "yes" },
{ "id": "e4", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "gate" }, "to": { "elementId": "reject" }, "label": "no" },
{ "id": "e5", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "approve" }, "to": { "elementId": "done" } },
{ "id": "e6", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "reject" }, "to": { "elementId": "done" } }
]
}
See the Diagram Classes reference for the full BPMN node and edge taxonomy (11 event types, 4 gateways, subprocess [+] marker, message flow open-circle endpoints).
Sequence diagram
A UML sequence diagram with lifelines and time-ordered messages. The sequence family resolver auto-positions lifelines left-to-right in definition order and stacks messages vertically - no explicit layout needed. Headers auto-size to the label, and a foot bar mirror is drawn at the bottom of every lifeline by default (UML convention) so you don’t need to author closing nodes.
{
"schemaVersion": "0.1",
"diagramFamily": "sequence",
"scene": {
"id": "auth-sequence",
"title": "Authentication",
"canvas": { "width": 640, "height": 360 }
},
"elements": [
{ "id": "client", "kind": "node", "nodeType": "sequence.actor", "shape": "rect", "label": "Client" },
{ "id": "server", "kind": "node", "nodeType": "sequence.lifeline", "shape": "rect", "label": "Auth Server" },
{ "id": "db", "kind": "node", "nodeType": "sequence.lifeline", "shape": "rect", "label": "User DB" },
{ "id": "m1", "kind": "edge", "edgeType": "sequence.message", "from": { "elementId": "client" }, "to": { "elementId": "server" }, "label": "POST /login" },
{ "id": "m2", "kind": "edge", "edgeType": "sequence.message", "from": { "elementId": "server" }, "to": { "elementId": "db" }, "label": "find user" },
{ "id": "m3", "kind": "edge", "edgeType": "sequence.reply", "from": { "elementId": "db" }, "to": { "elementId": "server" }, "label": "user record" },
{ "id": "m4", "kind": "edge", "edgeType": "sequence.reply", "from": { "elementId": "server" }, "to": { "elementId": "client" }, "label": "session token" }
]
}
Messages are ordered by array position - the first message edge is topmost. sequence.reply renders as a dashed arrow. For activation bars, add a sequence.activation node centered on the active lifeline. For UML annotations between messages, add a sequence.note node with extensions.anchor set to a single lifeline id (note centres OVER that lifeline) or a string array (note spans across the named lifelines, also centred-over) - notes interleave with messages by document order, matching PlantUML / Mermaid / UML 2.5 §17.4 convention. See Diagram Classes.
ER diagram
An entity-relationship diagram with compartmented entity rendering, PK/FK badges, and crow’s-foot cardinality.
{
"schemaVersion": "0.1",
"diagramFamily": "entityRelationship",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "er-orders",
"title": "Order Schema",
"canvas": { "width": 900, "height": 360 }
},
"elements": [
{
"id": "customer",
"kind": "node",
"nodeType": "er.entity",
"shape": "rect",
"label": "Customer",
"extensions": {
"columns": [
{ "name": "id", "type": "uuid", "pk": true },
{ "name": "email", "type": "text" },
{ "name": "created_at", "type": "timestamp" }
]
}
},
{
"id": "order",
"kind": "node",
"nodeType": "er.entity",
"shape": "rect",
"label": "Order",
"extensions": {
"columns": [
{ "name": "id", "type": "uuid", "pk": true },
{ "name": "customer_id", "type": "uuid", "fk": true },
{ "name": "total", "type": "numeric" }
]
}
},
{
"id": "item",
"kind": "node",
"nodeType": "er.entity",
"shape": "rect",
"label": "OrderItem",
"extensions": {
"columns": [
{ "name": "id", "type": "uuid", "pk": true },
{ "name": "order_id", "type": "uuid", "fk": true },
{ "name": "product_id", "type": "uuid", "fk": true },
{ "name": "qty", "type": "int" }
]
}
},
{ "id": "e1", "kind": "edge", "from": { "elementId": "customer", "cardinality": "one" }, "to": { "elementId": "order", "cardinality": "many" }, "label": "places" },
{ "id": "e2", "kind": "edge", "from": { "elementId": "order" }, "to": { "elementId": "item" }, "label": "contains" }
]
}
extensions.columns turns each er.entity into a compartmented box with a header bar and typed attribute rows. pk: true renders a golden PK badge; fk: true renders a blue FK badge. Valid cardinality values: one, many, zero-or-one, one-or-many, zero-or-many.
The second edge omits cardinality - when not set, the engine infers it from each endpoint’s resolved column metadata (pk → one; fk → many by default, narrowing to zero-or-many for nullable, one for unique, zero-or-one for unique + nullable). Author-set values are always preserved; auto-inference only fills in undefined endpoints.
Org chart
A hierarchical org chart rendered as structured person cards. The orgchart family uses a tidy-tree planner that gives balanced TB layouts for reporting hierarchies.
{
"schemaVersion": "0.1",
"diagramFamily": "orgchart",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "TB" },
"scene": {
"id": "team-org",
"title": "Engineering Team",
"canvas": { "width": 900, "height": 420 }
},
"elements": [
{ "id": "cto", "kind": "node", "nodeType": "org.person", "shape": "roundedRect", "label": "Jordan Lee\nCTO", "style": { "accentColor": "#d4a843" } },
{ "id": "vp-eng", "kind": "node", "nodeType": "org.person", "shape": "roundedRect", "label": "Alex Chen\nVP Engineering", "style": { "accentColor": "#4db89a" } },
{ "id": "vp-design", "kind": "node", "nodeType": "org.person", "shape": "roundedRect", "label": "Sam Rivera\nHead of Design", "style": { "accentColor": "#4db89a" } },
{ "id": "dev1", "kind": "node", "nodeType": "org.person", "shape": "roundedRect", "label": "Pat Kim\nSenior Developer" },
{ "id": "dev2", "kind": "node", "nodeType": "org.person", "shape": "roundedRect", "label": "Taylor Ng\nSRE" },
{ "id": "r1", "kind": "edge", "edgeType": "org.directReport", "from": { "elementId": "cto" }, "to": { "elementId": "vp-eng" } },
{ "id": "r2", "kind": "edge", "edgeType": "org.directReport", "from": { "elementId": "cto" }, "to": { "elementId": "vp-design" } },
{ "id": "r3", "kind": "edge", "edgeType": "org.directReport", "from": { "elementId": "vp-eng" }, "to": { "elementId": "dev1" } },
{ "id": "r4", "kind": "edge", "edgeType": "org.directReport", "from": { "elementId": "vp-eng" }, "to": { "elementId": "dev2" } }
]
}
org.person nodes render with a bold name (first line), muted title (remaining lines), and an accent stripe when style.accentColor is set. Use org.dottedLine for matrix/dotted-line reporting relationships.
Swimlane / pool diagram
A workflow with a pool containing vertical lanes. Frames auto-size from their children - set laneDirection on the pool, list the lanes as the pool’s children, and list the nodes in each lane as that lane’s children. The engine handles sizing.
{
"schemaVersion": "0.1",
"diagramFamily": "workflow",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "approval-lanes",
"title": "Approval with Lanes",
"canvas": { "width": 900, "height": 420 }
},
"elements": [
{ "id": "pool", "kind": "frame", "title": "Approval Process", "containerType": "pool", "laneDirection": "vertical", "children": ["lane-req", "lane-rev"] },
{ "id": "lane-req", "kind": "frame", "title": "Requester", "containerType": "lane", "children": ["start", "submit"] },
{ "id": "lane-rev", "kind": "frame", "title": "Reviewer", "containerType": "lane", "children": ["review", "gate", "notify", "end"] },
{ "id": "start", "kind": "node", "nodeType": "workflow.start", "shape": "ellipse", "label": "Submitted" },
{ "id": "submit", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Submit" },
{ "id": "review", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Review" },
{ "id": "gate", "kind": "node", "nodeType": "workflow.gateway", "shape": "diamond", "label": "OK?" },
{ "id": "notify", "kind": "node", "nodeType": "workflow.task", "shape": "roundedRect", "label": "Notify" },
{ "id": "end", "kind": "node", "nodeType": "workflow.end", "shape": "ellipse", "label": "Done" },
{ "id": "e0", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "start" }, "to": { "elementId": "submit" } },
{ "id": "e1", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "submit" }, "to": { "elementId": "review" } },
{ "id": "e2", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "review" }, "to": { "elementId": "gate" } },
{ "id": "e3", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "gate" }, "to": { "elementId": "notify" }, "label": "yes" },
{ "id": "e4", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "gate" }, "to": { "elementId": "end" }, "label": "no" },
{ "id": "e5", "kind": "edge", "edgeType": "workflow.sequenceFlow", "from": { "elementId": "notify" }, "to": { "elementId": "end" } }
]
}
laneDirection: "vertical" stacks lanes top-to-bottom (horizontal bands). "horizontal" stacks them left-to-right (vertical bands). Both pools and lanes omit layout.
Refining auto-layout with constraints
When auto-layout doesn’t place things exactly right, use constraints - not explicit coordinates. order constraints force spatial relationships (rightOf, leftOf, above, below, sameRank), align aligns elements on an axis, sameSize forces matching dimensions.
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "microservices",
"title": "Microservices",
"canvas": { "width": 1000, "height": 420 }
},
"elements": [
{ "id": "gateway", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Gateway" },
{ "id": "users", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Users Service" },
{ "id": "orders", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Orders Service" },
{ "id": "payments", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Payments Service" },
{ "id": "db", "kind": "node", "nodeType": "database", "shape": "cylinder", "label": "Database" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "gateway" }, "to": { "elementId": "users" } },
{ "id": "e2", "kind": "edge", "from": { "elementId": "gateway" }, "to": { "elementId": "orders" } },
{ "id": "e3", "kind": "edge", "from": { "elementId": "gateway" }, "to": { "elementId": "payments" } },
{ "id": "e4", "kind": "edge", "from": { "elementId": "orders" }, "to": { "elementId": "db" } },
{ "id": "e5", "kind": "edge", "from": { "elementId": "payments" }, "to": { "elementId": "db" } }
],
"constraints": [
{ "id": "c1", "type": "order", "source": "users", "target": "orders", "relation": "above" },
{ "id": "c2", "type": "order", "source": "orders", "target": "payments", "relation": "above" },
{ "id": "c3", "type": "sameSize", "elements": ["users", "orders", "payments"], "dimension": "both" }
]
}
The order constraints pin the three services into a specific top-to-bottom order. sameSize forces them to the same dimensions so the stack looks uniform. Without these, the engine would still produce a valid layout - but with them, it produces the one you wanted.
Icons on nodes
Nodes can display an icon using the icon field. Two built-in packs: Lucide (~51 generic icons, matches the node’s text color) and AWS (~50 service icons, uses brand colors).
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "aws-infra",
"title": "AWS Infrastructure",
"canvas": { "width": 900, "height": 280 }
},
"elements": [
{ "id": "cf", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "CloudFront", "icon": "aws:cloudfront" },
{ "id": "api", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "API Gateway", "icon": "aws:api-gateway" },
{ "id": "lambda", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Handler", "icon": "aws:lambda" },
{ "id": "db", "kind": "node", "nodeType": "database", "shape": "cylinder", "label": "DynamoDB", "icon": "aws:dynamodb" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "cf" }, "to": { "elementId": "api" } },
{ "id": "e2", "kind": "edge", "from": { "elementId": "api" }, "to": { "elementId": "lambda" } },
{ "id": "e3", "kind": "edge", "from": { "elementId": "lambda" }, "to": { "elementId": "db" } }
]
}
Icons are embedded as base64 SVG - no external requests at render time. For Lucide, use keys like lucide:database, lucide:server, lucide:cloud, lucide:shield. URL fallback: "icon": "https://example.com/custom.svg".
Text wrapping on nodes
Long labels wrap inside the node when textStyle.wrap: "word" is set. Combine with layout.autoSize: "content" to auto-expand the node height to fit the wrapped text. Because autoSize is a property of layout, this example uses explicit positioning - it’s the one place to reach for coordinates instead of layoutStrategy.
{
"schemaVersion": "0.1",
"scene": {
"id": "text-cards",
"title": "Service Cards",
"canvas": { "width": 720, "height": 180 }
},
"elements": [
{
"id": "gateway",
"kind": "node",
"nodeType": "service",
"shape": "roundedRect",
"label": "API Gateway handles all incoming HTTP requests, performs rate limiting, and routes to downstream services.",
"layout": { "mode": "absolute", "x": 40, "y": 40, "width": 220, "height": 60, "autoSize": "content" },
"textStyle": { "wrap": "word", "align": "left", "verticalAlign": "top" }
},
{
"id": "auth",
"kind": "node",
"nodeType": "service",
"shape": "roundedRect",
"label": "Auth Service validates JWT tokens, manages sessions, and enforces RBAC policies across all endpoints.",
"layout": { "mode": "absolute", "x": 440, "y": 40, "width": 220, "height": 60, "autoSize": "content" },
"textStyle": { "wrap": "word", "align": "left", "verticalAlign": "top" }
},
{ "id": "e1", "kind": "edge", "from": { "elementId": "gateway" }, "to": { "elementId": "auth" } }
]
}
autoSize: "content" combined with an explicit width is the standard pattern for card-style nodes: you set width, the engine computes height. The initial height is a seed; the engine expands it to fit the wrapped label. If text still overflows after auto-sizing, the render response’s diagnostics array includes TEXT_OVERFLOW with the exact requiredHeight.
Annotations with text and guides
For section titles, callouts, and dividers, use text (standalone labels) and guide (canvas-spanning separator lines). These are the right tools for annotations - don’t create invisible nodes just to hold label text.
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "annotated",
"title": "Annotated Architecture",
"canvas": { "width": 900, "height": 420 }
},
"elements": [
{
"id": "title",
"kind": "text",
"text": "Payment Processing Flow",
"layout": { "mode": "absolute", "x": 20, "y": 10, "width": 500, "height": 30 },
"textStyle": { "align": "left" },
"style": { "fontSize": 18, "textColor": "#1a1a1a" }
},
{
"id": "divider",
"kind": "guide",
"orientation": "horizontal",
"position": 50
},
{ "id": "client", "kind": "node", "nodeType": "actor", "shape": "roundedRect", "label": "Client" },
{ "id": "checkout", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Checkout" },
{ "id": "processor", "kind": "node", "nodeType": "externalSystem", "shape": "cloud", "label": "Stripe" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "client" }, "to": { "elementId": "checkout" }, "label": "submit" },
{ "id": "e2", "kind": "edge", "from": { "elementId": "checkout" }, "to": { "elementId": "processor" }, "label": "charge", "style": { "dash": [4, 4], "stroke": "#cc6600" } }
]
}
kind: "text"is a standalone label.textStyle.wrap: "word"lets you embed multi-line descriptions. For bullet lists, use unicode bullets in the content:"Features:\n• Fast\n• Reliable".kind: "guide"draws a dashed separator line across the full canvas.orientationis"horizontal"or"vertical";positionis the y- or x-coordinate.style.dash: [4, 4]on an edge produces a dashed connector. Any number array works:[6, 3],[2, 2], etc.
Scene palette for branding
Set palette at the scene root to apply a consistent color scheme across all unstyled elements in one place. Beats setting style on every node.
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "branded",
"title": "Branded Architecture",
"canvas": { "width": 900, "height": 280 }
},
"palette": {
"background": "#f4f7fb",
"nodeFill": "#003366",
"nodeStroke": "#001a33",
"foreground": "#ffffff",
"edgeStroke": "#335c85",
"accentPrimary": "#ffcc00"
},
"elements": [
{ "id": "web", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "Web App" },
{ "id": "api", "kind": "node", "nodeType": "service", "shape": "roundedRect", "label": "API" },
{ "id": "db", "kind": "node", "nodeType": "database", "shape": "cylinder", "label": "Postgres" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "web" }, "to": { "elementId": "api" } },
{ "id": "e2", "kind": "edge", "from": { "elementId": "api" }, "to": { "elementId": "db" } }
]
}
Palette keys: background, foreground, nodeFill, nodeStroke, edgeStroke, containerFill, containerStroke, accentPrimary, accentSecondary, mutedForeground. Any element’s explicit style still wins over the palette. Text color auto-adjusts for contrast against the resolved fill if you don’t set textColor.
3D box shapes for infrastructure
Use shape: "box3d" for isometric-style infrastructure icons - servers, appliances, physical deployments. Pairs well with the clean theme for product diagrams or the blueprint theme for engineering docs.
{
"schemaVersion": "0.1",
"diagramFamily": "architecture",
"layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
"scene": {
"id": "rack-topology",
"title": "Datacenter Rack",
"canvas": { "width": 900, "height": 260 }
},
"elements": [
{ "id": "edge-fw", "kind": "node", "nodeType": "service", "shape": "box3d", "label": "Edge Firewall" },
{ "id": "lb", "kind": "node", "nodeType": "service", "shape": "box3d", "label": "Load Balancer" },
{ "id": "app", "kind": "node", "nodeType": "service", "shape": "box3d", "label": "App Servers" },
{ "id": "storage", "kind": "node", "nodeType": "database", "shape": "box3d", "label": "Storage Array" },
{ "id": "e1", "kind": "edge", "from": { "elementId": "edge-fw" }, "to": { "elementId": "lb" } },
{ "id": "e2", "kind": "edge", "from": { "elementId": "lb" }, "to": { "elementId": "app" } },
{ "id": "e3", "kind": "edge", "from": { "elementId": "app" }, "to": { "elementId": "storage" } }
]
}
box3d is one of 12 built-in shapes. The full set: rect, roundedRect, ellipse, diamond, cylinder, pill, hexagon, parallelogram, cloud, box3d, textBox, iconBox. See Element Types for the full catalog.