Sea12Docs
Core Concepts

Processes In-Depth

Process CRUD, the visual editor, node placement, edges, locking, forking, import/export.


A process is a visual workflow -- a directed graph of nodes connected by edges. When triggered, the execution engine traverses the graph, running each node and propagating data along edges.


Process Structure

Process
 ├── name: string
 ├── description: string
 ├── max_retries: int         -- retry count on failure (0 = no retries)
 ├── is_running: bool         -- whether input listeners are active
 ├── locked: bool             -- prevents edits
 ├── error_webhook_url: string -- URL to POST error details on failure
 │
 ├── Nodes[]
 │    ├── id: UUID
 │    ├── type: string        -- "inputNode", "outputNode", "scriptNode", etc.
 │    ├── position: { x, y }  -- canvas coordinates
 │    └── config: JSONB       -- type-specific configuration
 │
 ├── Edges[]
 │    ├── source_node_id: UUID
 │    ├── target_node_id: UUID
 │    ├── source_handle: string
 │    └── target_handle: string
 │
 └── Versions[]
      ├── version_number: int
      ├── label: string
      └── snapshot: JSONB     -- full graph at that point

Creating a Process

  1. Navigate to Processes.
  2. Click New Process.
  3. Enter a name and optional description.
  4. You are placed in the visual editor.

From Import

Import a process from JSON:

API: POST /processes/bulk-import/{orgId}

JSON
{
  "name": "Imported Process",
  "description": "...",
  "nodes": [
    {
      "type": "inputNode",
      "position": { "x": 100, "y": 200 },
      "config": { ... }
    }
  ],
  "edges": [
    {
      "sourceNodeId": "node-1-uuid",
      "targetNodeId": "node-2-uuid",
      "sourceHandle": "output",
      "targetHandle": "input"
    }
  ],
  "schemaDependencies": {
    "schema-uuid": { ... }
  }
}

Schema dependencies are resolved during import -- if a referenced schema doesn't exist, it is created from the dependency data.


The Visual Editor

The editor is a canvas powered by ReactFlow. Key interactions:

ActionHow
Add a nodeDrag from the Node Palette (left panel) onto the canvas
Connect nodesDrag from an output port (right side of node) to an input port (left side of another node)
Move a nodeDrag the node body; position auto-saves
Delete a nodeSelect and press Delete, or right-click > Delete
Delete an edgeClick the edge, then press Delete
ZoomScroll wheel or pinch
PanClick and drag on empty canvas
Auto-layoutToolbar button to automatically arrange nodes

Node Palette Categories

CategoryNodes
I/OInput, Output, SQL, Database
AIML Model, Schematization
LogicScript, Conditional, Loop, Wait
OperationsIntegrations, Web Automation, OCR

Nodes

Node Properties

Every node has these common properties:

PropertyTypeDescription
idUUIDUnique identifier (auto-generated)
typestringNode type identifier
position{x, y}Canvas position
configJSONBAll type-specific settings

Node Config

The config object varies by node type. Common fields across many types:

FieldDescription
labelDisplay name (used in template references)
passthroughFilesWhether to forward input files to output

The label is critical -- it is how other nodes reference this node's output in templates:

{{input["My Node Label"]["field_name"]}}

If you rename a node's label, you must update all templates that reference it.

See Node Reference for every type's config.


Edges

Edge Properties

PropertyDescription
source_node_idThe node producing data
target_node_idThe node consuming data
source_handleOutput port name (default: "output")
target_handleInput port name (default: "input")

Handle Names

Most nodes have a single "output" handle and "input" handle. Special cases:

Node TypeOutput Handles
Conditional (conditions mode)"true", "false"
Conditional (switch mode)One handle per case label, plus default
SchematizationOne handle per selected data block name
Loop"start" (to loop body), "output" (final results)
Script (multi-output)One handle per configured output port name

Only nodes connected to the active output handle receive data. Nodes on inactive branches are skipped.


Running a Process

Starting

  1. Click Start in the process toolbar, or
  2. API: POST /processes/start/{processId}

This activates all input listeners (Gmail polling, webhook endpoint, cron scheduler). The process status changes to is_running: true.

Stopping

  1. Click Stop in the toolbar, or
  2. API: POST /processes/stop/{processId}

This shuts down all input listeners. In-flight executions continue to completion, but no new executions start.

Manual Trigger

You can trigger a single execution without starting persistent listeners:

API: POST /processes/test/{processId}

This sends test data directly to the execution engine.


Execution Flow

When a trigger fires:

  1. The input node's data is captured.
  2. A ProcessExecution record is created with status running.
  3. The execution engine loads the full graph (nodes + edges).
  4. The graph is traversed concurrently -- nodes run as soon as all their parent nodes complete.
  5. Data propagates along edges (each node's output is merged into its children's input).
  6. On completion, the execution record is updated with status, output data, duration, and node states.

See Execution Engine for the internal mechanics.


Execution History

Every execution is recorded and queryable:

API: GET /processes/executions/{processId}?page=1&pageSize=20

Execution Record

FieldTypeDescription
idUUIDExecution record ID
execution_idstringEngine-assigned execution ID
statusstringrunning, completed, failed, timeout, cancelled
started_attimestampWhen execution began
completed_attimestampWhen execution ended
duration_secondsintWall-clock duration
input_dataJSONBData from the trigger
output_dataJSONBFinal output data
error_messagestringError details if failed
triggered_by_user_idUUIDUser who triggered (if manual)
trigger_node_idstringWhich input node fired
node_statesJSONBStatus and data for every node
graph_snapshotJSONBSnapshot of the process graph at execution time

Node States

The node_states field is a JSON array with one entry per node:

JSON
[
  {
    "node_id": "uuid",
    "node_name": "Email Input",
    "node_type": "inputNode",
    "status": "completed",
    "started_at": "2026-04-12T10:00:00Z",
    "completed_at": "2026-04-12T10:00:01Z",
    "duration_ms": 1200,
    "input_data": { ... },
    "output_data": { ... },
    "error": null
  }
]

Execution Statistics

API: GET /processes/execution-stats/{processId}

Returns aggregated statistics: total runs, success rate, average duration, failure breakdown.


Error Webhook

Configure an error webhook URL to receive notifications when executions fail.

Field: error_webhook_url on the process.

When an execution fails, the engine POSTs error details to this URL including the process ID, execution ID, status, and failed node information.


Locking

Lock a process to prevent edits while it runs in production.

OperationAPI
LockPOST /processes/lock/{processId}
UnlockPOST /processes/unlock/{processId}

When locked:

  • Nodes and edges cannot be added, modified, or deleted
  • Process settings cannot be changed
  • The process can still be started/stopped
  • Executions still run normally

Forking (Duplicating)

Create a copy of a process:

API: POST /processes/fork/{processId}

JSON
{
  "name": "Steel Order Quoter (Copy)"
}

This duplicates all nodes, edges, and configs. Schema references point to the same schemas (not duplicated).


Export

Export a process as JSON:

API: GET /processes/{processId}/export

The export includes:

  • Process metadata
  • All nodes with configs
  • All edges
  • Schema dependencies (inline schema definitions for portability)

Process Validation (Linting)

API: POST /processes/{processId}/lint

Checks:

  • At least one input node exists
  • At least one output node exists
  • All nodes are connected (no orphans)
  • Required node config fields are populated
  • Schema references are valid
  • Edge source/target nodes exist
  • No circular dependencies (DAG validation)