ObjectStackObjectStack

Flow Metadata

Build visual automation with decision trees, data operations, HTTP requests, and screen interactions

Flow Metadata

A Flow is a visual automation that orchestrates business logic through connected nodes. Flows support decision branching, data operations (CRUD), HTTP integrations, script execution, user screens, and subflow composition.

Basic Structure

const approvalFlow = {
  name: 'order_approval',
  label: 'Order Approval Flow',
  type: 'record_change',
  version: 1,
  status: 'active',
  template: false,
  runAs: 'system',

  variables: [
    { name: 'order_amount', type: 'number', isInput: true, isOutput: false },
    { name: 'approved', type: 'boolean', isInput: false, isOutput: true },
  ],

  nodes: [
    { id: 'start', type: 'start', label: 'Start' },
    {
      id: 'check_amount',
      type: 'decision',
      label: 'Check Amount',
      config: {
        conditions: [
          { label: 'High Value', expression: 'order_amount > 10000' },
          { label: 'Standard', expression: 'order_amount <= 10000' },
        ],
      },
    },
    {
      id: 'auto_approve',
      type: 'update_record',
      label: 'Auto Approve',
      config: { object: 'order', fields: { status: 'approved' } },
    },
    {
      id: 'request_approval',
      type: 'screen',
      label: 'Manager Approval',
      config: { screenType: 'approval' },
    },
    { id: 'end', type: 'end', label: 'End' },
  ],

  edges: [
    { id: 'e1', source: 'start', target: 'check_amount', type: 'default' },
    { id: 'e2', source: 'check_amount', target: 'auto_approve', type: 'default', condition: 'order_amount <= 10000' },
    { id: 'e3', source: 'check_amount', target: 'request_approval', type: 'default', condition: 'order_amount > 10000' },
    { id: 'e4', source: 'auto_approve', target: 'end', type: 'default' },
    { id: 'e5', source: 'request_approval', target: 'end', type: 'default' },
  ],
};

Flow Properties

PropertyTypeRequiredDescription
namestringMachine name (snake_case)
labelstringDisplay label
descriptionstringoptionalFlow description
versionnumberVersion number
statusenum'draft', 'active', 'obsolete', 'invalid'
typeFlowTypeFlow trigger type (see below)
templatebooleanIs this a reusable subflow template
runAsenum'system' or 'user' execution context
variablesFlowVariable[]optionalInput/output variables
nodesFlowNode[]Flow nodes
edgesFlowEdge[]Connections between nodes
errorHandlingobjectoptionalError handling strategy

Flow Types

TypeDescriptionTrigger
autolaunchedRuns automatically without user interactionInvoked by other flows or API
record_changeTriggered by record create/update/deleteData mutation events
scheduleRuns on a schedule (cron)Time-based
screenInteractive flow with user screensUser clicks a button
apiExposed as an API endpointHTTP request

Nodes

Each node performs a specific action in the flow.

Node Types

TypeDescription
startFlow entry point
endFlow termination
decisionConditional branching (if/else)
assignmentSet variable values
loopIterate over a collection
create_recordCreate a new record
update_recordUpdate existing records
delete_recordDelete records
get_recordQuery records
http_requestMake an HTTP API call
scriptExecute custom JavaScript
screenDisplay a user form/screen
waitPause and wait for an event or time
subflowInvoke another flow
connector_actionExecute an external connector action

Node Structure

{
  id: 'unique_node_id',
  type: 'decision',
  label: 'Check Priority',
  config: { /* type-specific configuration */ },
  position: { x: 200, y: 100 },    // Canvas position (optional)
}
PropertyTypeRequiredDescription
idstringUnique node identifier
typeFlowNodeActionNode type
labelstringDisplay label
configobjectoptionalType-specific configuration
connectorConfigobjectoptionalExternal connector settings
position{ x, y }optionalVisual position on canvas

Node Examples

Decision (branching):

{
  id: 'check_status',
  type: 'decision',
  label: 'Check Status',
  config: {
    conditions: [
      { label: 'Approved', expression: "status = 'approved'" },
      { label: 'Rejected', expression: "status = 'rejected'" },
    ],
  },
}

Create Record:

{
  id: 'create_task',
  type: 'create_record',
  label: 'Create Follow-up Task',
  config: {
    object: 'task',
    fields: {
      title: 'Follow up on {record.name}',
      assignee: '{record.owner}',
      due_date: 'TODAY() + 7',
    },
  },
}

HTTP Request:

{
  id: 'notify_slack',
  type: 'http_request',
  label: 'Send Slack Notification',
  config: {
    url: 'https://hooks.slack.com/services/...',
    method: 'POST',
    body: { text: 'New order: {record.name}' },
  },
}

Script:

{
  id: 'calculate',
  type: 'script',
  label: 'Calculate Discount',
  config: {
    code: `
      const discount = input.amount > 1000 ? 0.1 : 0.05;
      return { discount_rate: discount };
    `,
  },
}

Edges

Edges connect nodes and define the execution path:

{
  id: 'edge_1',
  source: 'check_status',
  target: 'send_email',
  type: 'default',
  condition: "status = 'approved'",
  label: 'Approved',
}
PropertyTypeRequiredDescription
idstringUnique edge identifier
sourcestringSource node ID
targetstringTarget node ID
typeenum'default' (success) or 'fault' (error)
conditionstringoptionalBoolean expression for branching
labelstringoptionalLabel displayed on the connector

Variables

Flows use variables to pass data between nodes and to/from callers:

variables: [
  { name: 'input_id', type: 'text', isInput: true, isOutput: false },
  { name: 'result', type: 'object', isInput: false, isOutput: true },
  { name: 'counter', type: 'number', isInput: false, isOutput: false },
]
PropertyTypeDescription
namestringVariable name
typestring'text', 'number', 'boolean', 'object', 'list'
isInputbooleanAvailable as input parameter
isOutputbooleanAvailable as output parameter

Error Handling

Configure how errors are handled during flow execution:

errorHandling: {
  strategy: 'retry',           // 'fail' | 'retry' | 'continue'
  maxRetries: 3,
  retryDelayMs: 5000,
  fallbackNodeId: 'error_handler',
}
PropertyTypeDescription
strategyenum'fail' (stop), 'retry' (retry), 'continue' (skip)
maxRetriesnumberMaximum retry attempts (0-10)
retryDelayMsnumberDelay between retries (ms)
fallbackNodeIdstringNode to execute on failure

On this page