---
title: Node kinds reference
path: reference/node-kinds
status: published
---

# Node kinds reference

Per-kind configuration shape, default ports, and IR mapping.

For the conceptual overview, see [Concepts: Node kinds](../concepts/node-kinds).

## Entry points

### `entry_api`

```jsonc
"config": { "method": "POST", "path": "/" }
```

- Ports: `outputs: [{ id: "out_request", label: "request", type: "object" }]`. No inputs.
- IR: top-level `IRTrigger { kind: "api", name, target_flow }`.

### `entry_webhook`

```jsonc
"config": { "method": "POST", "path": "/", "auth": null }
```

- Ports: `outputs: [{ id: "out_event", label: "event", type: "object" }]`.
- IR: top-level `IRTrigger { kind: "webhook", ... }`.

### `entry_schedule`

```jsonc
"config": { "cron": "0 * * * *", "timezone": "UTC" }
```

- Ports: `outputs: [{ id: "out_tick", label: "tick", type: "object" }]`.
- IR: top-level `IRTrigger { kind: "schedule", ... }`.

## LLM blocks

### `llm_rigid`

```jsonc
"config": { "template": "Hello {{user_name}}, ..." }
```

- Ports: `inputs: [{ id: "in" }]`, `outputs: [{ id: "out" }]`.
- IR: `{ kind: "rigid", statements: [{ kind: "expression", expression: template }], result_binding }`.

### `llm_guarded`

```jsonc
"config": {
  "goal": "Generate a response grounded in the docs.",
  "model": "primary",                     // legacy alias for llm_role; both accepted
  "llm_role": "primary",                  // canonical
  "guard": "kb_results.length > 0",
  "validate": "result.citations.length > 0",
  "output_schema": { "response": "string", "citations": "array" },
  "input_bindings": {},
  "context_bindings": {},
  "guidance": "...",
  "constraints": "...",
  "on_validation_failure": null
}
```

- IR: `{ kind: "guarded", goal, output_type, llm_role, guard, validate, input_bindings, context_bindings, guidance, constraints, on_validation_failure, result_binding }`.

### `llm_flexible`

```jsonc
"config": {
  "goal": "Classify the customer's intent.",
  "model": "fast",
  "llm_role": "fast",
  "output_schema": { "intent": "enum[question, complaint, request, feedback]" },
  "input_bindings": {},
  "context_bindings": {},
  "guidance": "...",
  "identity_ref": false,
  "constraints": "...",
  "examples": [],
  "on_failure": null,
  "budget": null
}
```

- IR: `{ kind: "flexible", goal, output_type, llm_role, input_bindings, ... }`.

## Logic

### `logic_decision`

```jsonc
"config": {
  "style": "if",                          // or "switch"
  "subject": "confidence"                 // optional canvas-side hint
}
```

- Ports: `inputs: [{ id: "in" }]`, `outputs: [{ id: "out" }]`. **One** output port — branches are the outgoing conditional edges.
- IR: `{ kind: "match", style, branches: [{condition, target_node}, ...] }`.

### `logic_loop`

```jsonc
"config": {
  "style": "for",                         // or "while"
  "iterator": "item",                     // for: variable name
  "collection": "items",                  // for: expression
  "max_iterations": 1000,                 // while: REQUIRED (compile-time bound)
  "while": "condition_expr"               // while: condition
}
```

- IR: `{ kind: "foreach", iterator_var, collection, body, yield_expression }` or `{ kind: "while", condition, max_iterations, body }`.

### `logic_parallel`

```jsonc
"config": {
  "max_concurrent": 4,
  "fail_fast": true,
  "join": null                            // deprecated; replaced by fail_fast
}
```

- IR: `{ kind: "parallel", branches: [], max_concurrent, fail_fast }`.

## Tool calls

### `tool_plugin`

```jsonc
"config": {
  "plugin": "scaidrive",
  "method": "search",
  "args": { "path": "/knowledge/", "query": "{{message}}" },
  "plugin_args": {},                      // legacy alias for args
  "result_binding": "docs"
}
```

- IR: `{ kind: "plugin_call", plugin, method, plugin_args, result_binding, source_location }`.

### `tool_http`

```jsonc
"config": {
  "method": "GET",
  "url": "https://api.example.com/users/{{id}}",
  "headers": {},
  "body": null
}
```

- Compiles to `plugin_call` with `plugin: "http"` (placeholder name; canonical TBD).

## Data

### `data_variable_set`

```jsonc
"config": { "name": "counter", "expression": "0" }
```

- IR: `{ kind: "assign", target, value, source_location }`.

## Checkpoint

### `checkpoint`

```jsonc
"config": {
  "type": "approval",                     // or "review", "debug_breakpoint", etc.
  "when": "amount > 500",                 // optional gating condition
  "prompt": "Approve?",
  "options": ["approve", "reject"],
  "timeout": "1h",
  "on_timeout": "escalate",
  "breakpoint": false                     // toggle: when true, prepends a debug_breakpoint
}
```

- IR: `{ kind: "checkpoint", checkpoint_type, presentation, options, ... }`.

## Queue / HITL

### `queue_publish`

```jsonc
"config": {
  "scope": "support",                     // optional; inherits flow scope
  "queue": "intake",
  "message_type": "event",
  "payload": {},
  "labels": null,
  "priority": null
}
```

- IR: `{ kind: "plugin_call", plugin: "scaiqueue", method: "publish", plugin_args: {...} }`.

### `queue_consume`

```jsonc
"config": {
  "scope": "support",
  "queue": "intake",
  "consumer_id": "worker-1"
}
```

- IR: `scaiqueue.consume(...)`.

### `hitl_review`

```jsonc
"config": {
  "scope": "support",                     // optional; inherits
  "queue": "review",
  "assignee": null,
  "timeout": "1h",
  "on_timeout": "escalate",
  "options": ["approve", "reject", "edit_and_approve"],
  "decision_bind": "decision",
  "present": {},                          // legacy free-form presentation
  "sections": [ /* form builder sections */ ]
}
```

- IR: `{ kind: "checkpoint", checkpoint_type: "hitl_review",
         hitl_target: { scope, queue, hitl_spec }, ... }`.

### `hitl_decision`

```jsonc
"config": {
  "type": "approval",
  "timeout": "1h",
  "on_timeout": "escalate",
  "options": ["approve", "reject"]
}
```

- IR: `{ kind: "checkpoint", checkpoint_type: "approval", ... }` (no `hitl_target`).

### `queue_escalation`

```jsonc
"config": {
  "scope": "support",
  "escalation_queue": "escalation",
  "reason": "timeout-exceeded"
}
```

- IR: `scaiqueue.escalate(...)`.

## Compute (ScaiBunker)

### `compute_provision`

```jsonc
"config": {
  "image": "python-3.12",
  "lifecycle": "ephemeral",
  "cpu_millicores": 1000,
  "memory_mb": 512,
  "network_profile": "registry"
}
```

- IR: `scaibunker.create(...)`. Returns a bunker handle.

### `compute_exec`

```jsonc
"config": {
  "command": ["python", "/script.py"],
  "timeout_s": 30
}
```

- IR: `scaibunker.exec(...)`.

### `compute_file_upload`

```jsonc
"config": { "path": "/data/in.json", "content": "{{payload}}" }
```

- IR: `scaibunker.write_file(...)`.

### `compute_file_download`

```jsonc
"config": { "path": "/data/out.json" }
```

- IR: `scaibunker.read_file(...)`.

### `compute_destroy`

```jsonc
"config": {}
```

- IR: `scaibunker.destroy()`.

## Sub-flow

### `subflow_call`

```jsonc
"config": {
  "target": "core://acme/customer-lookup",
  "flow_name": null,
  "instance_key": null,
  "version": null,
  "input_bindings": { "id": "{{customer_id}}" },
  "timeout": "30s",
  "is_async": false
}
```

- IR: `{ kind: "core_call", target, flow_name, input_bindings, instance_key, version, timeout, is_async, source_location }`.

## See also

- [Concepts: Flow graph](../concepts/flow-graph-model) — the higher-level shape.
- [Concepts: Rigidity spectrum](../concepts/rigidity-spectrum) — why three LLM block kinds.
- [Flow schema reference](./flow-schema) — JSON Schema details.
