+ * This is the JSON response format for the layout endpoint.
+ *
+ * @param width total diagram width
+ * @param height total diagram height
+ * @param nodes positioned nodes with coordinates
+ * @param edges positioned edges with waypoints
+ */
+public record DiagramLayout(
+ double width,
+ double height,
+ List
+ * Implementations produce either SVG documents for direct display or
+ * JSON-serializable layout data for client-side rendering.
+ */
+public interface DiagramRenderer {
+
+ /**
+ * Render the route graph as an SVG XML document.
+ *
+ * @param graph the route graph definition
+ * @return SVG XML string
+ */
+ String renderSvg(RouteGraph graph);
+
+ /**
+ * Compute the diagram layout with positioned nodes and edges.
+ *
+ * @param graph the route graph definition
+ * @return layout data suitable for JSON serialization
+ */
+ DiagramLayout layoutJson(RouteGraph graph);
+}
diff --git a/cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java b/cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java
new file mode 100644
index 00000000..cdd29f24
--- /dev/null
+++ b/cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java
@@ -0,0 +1,19 @@
+package com.cameleer3.server.core.diagram;
+
+import java.util.List;
+
+/**
+ * An edge with computed waypoints for rendering.
+ *
+ * @param sourceId source node identifier
+ * @param targetId target node identifier
+ * @param label optional edge label
+ * @param points list of [x, y] waypoints from source to target
+ */
+public record PositionedEdge(
+ String sourceId,
+ String targetId,
+ String label,
+ List
+ * For compound nodes (CHOICE, SPLIT, TRY_CATCH, etc.), {@code children}
+ * contains the nested child nodes rendered inside the parent bounds.
+ *
+ * @param id node identifier (matches RouteNode.id)
+ * @param label display label
+ * @param type NodeType name (e.g., "ENDPOINT", "PROCESSOR")
+ * @param x horizontal position
+ * @param y vertical position
+ * @param width node width
+ * @param height node height
+ * @param children nested child nodes for compound/swimlane groups
+ */
+public record PositionedNode(
+ String id,
+ String label,
+ String type,
+ double x,
+ double y,
+ double width,
+ double height,
+ List