REST API: Preview
Live compile + validate endpoints. Both stateless — no persistence, no deploy.
Used by the canvas's right-sidebar Live Preview pane and the inline validation badges. Routes registered before the /v1/flows/{flow_id} wildcard so they win.
Both endpoints require scaicore:view.
POST /v1/flows/compile#
Compile the posted flow JSON to YAML, IR, or .scai text. No persistence — the flow doesn't have to be saved.
Body:
{
"content": { /* full FlowGraph JSON */ },
"format": "yaml" // or "ir", "scai"
}
Response:
{
"format": "yaml",
"body": "core:\n name: my-flow\n ...", // string body for yaml/scai
"errors": [] // compile errors, if any
}
For format: "ir", the body is base64-encoded MessagePack bytes.
Compile errors come back inside errors[] rather than as a 4xx — the canvas's live preview pane renders them inline so the user sees what's wrong as they type. Empty errors means clean compile.
POST /v1/flows/validate#
Run schema validation + the analyze stage (port wiring, entry detection, cycle detection). Doesn't compile.
Body: same as compile (just the content).
Response:
{
"valid": false,
"diagnostics": [
{ "severity": "error",
"message": "edge 'edge_xyz': source node 'node_abc' has no output port 'out_typo'",
"path": "edges[2]",
"node_id": null,
"edge_id": "edge_xyz" },
{ "severity": "warning",
"message": "node 'node_review' has an unused output port 'out_aux'",
"node_id": "node_review",
"edge_id": null }
]
}
Severity is error or warning. Errors block compile/deploy; warnings don't.
The canvas indexes diagnostics by node_id / edge_id / unattached so:
<NodeView>can paint cards red (error) or amber (warning) on the canvas.<PropertyPanel>can list per-node messages on the selected node.
Skipped in dev-token mode#
Both endpoints require scaicore:view. The canvas skips them entirely when authStore.authMode() !== "scaikey" to avoid spamming 401 toasts in dev-token mode.
Debounce#
The canvas's previewStore debounces calls by 500 ms and uses a monotonic nextRequest counter to drop out-of-order responses (so a slow compile from an earlier flow state doesn't overwrite a fast compile from the current state).