ObjectStackObjectStack

Workflow Metadata

Define event-triggered automation rules — field updates, email alerts, HTTP calls, and scheduled actions

Workflow Metadata

A Workflow Rule is a declarative automation triggered by data events. When a record is created, updated, or deleted, workflow rules evaluate conditions and execute actions like field updates, email alerts, HTTP calls, and task creation.

Basic Structure

const dealClosedWorkflow = {
  name: 'deal_closed_won',
  objectName: 'opportunity',
  triggerType: 'on_update',
  criteria: "status = 'closed_won' AND ISCHANGED(status)",
  active: true,
  executionOrder: 10,

  actions: [
    {
      type: 'field_update',
      field: 'closed_date',
      value: 'TODAY()',
    },
    {
      type: 'email_alert',
      template: 'deal_won_notification',
      recipients: ['{record.owner.email}', 'sales-team@company.com'],
    },
    {
      type: 'task_creation',
      taskObject: 'task',
      subject: 'Onboard new customer: {record.name}',
      assignedTo: '{record.owner}',
      dueDate: 'TODAY() + 3',
    },
  ],
};

Workflow Properties

PropertyTypeRequiredDescription
namestringMachine name (snake_case)
objectNamestringTarget object name
triggerTypeTriggerTypeWhen to evaluate (see below)
criteriastringoptionalFormula condition — workflow fires only when TRUE
actionsAction[]optionalImmediate actions to execute
timeTriggersTimeTrigger[]optionalScheduled/delayed actions
activebooleanIs workflow active
executionOrdernumberoptionalExecution priority (lower = first)
reevaluateOnChangebooleanoptionalRe-evaluate if field updates change criteria

Trigger Types

TypeDescription
on_createFires when a record is created
on_updateFires when a record is updated
on_create_or_updateFires on both create and update
on_deleteFires when a record is deleted
scheduleFires on a time-based schedule

Action Types

Field Update

Update a field value on the triggering record:

{
  type: 'field_update',
  field: 'status',
  value: 'approved',
}
PropertyTypeDescription
fieldstringField to update
valuestringNew value (supports formulas and field references)

Email Alert

Send an email notification:

{
  type: 'email_alert',
  template: 'order_confirmation',
  recipients: ['{record.customer_email}', 'support@company.com'],
}
PropertyTypeDescription
templatestringEmail template name
recipientsstring[]Email addresses (supports field references)

HTTP Call

Call an external API:

{
  type: 'http_call',
  url: 'https://api.example.com/webhooks',
  method: 'POST',
  headers: { 'Authorization': 'Bearer {$credential.api_key}' },
  body: {
    event: 'record_updated',
    record_id: '{record.id}',
    data: '{record}',
  },
}
PropertyTypeDescription
urlstringTarget URL
methodstringHTTP method (GET, POST, PUT, DELETE)
headersobjectRequest headers
bodyobjectRequest body

Task Creation

Create a follow-up task:

{
  type: 'task_creation',
  taskObject: 'task',
  subject: 'Review account: {record.name}',
  assignedTo: '{record.owner}',
  dueDate: 'TODAY() + 7',
}
PropertyTypeDescription
taskObjectstringTask object name
subjectstringTask subject (supports field references)
assignedTostringAssigned user (field reference)
dueDatestringDue date expression

Connector Action

Execute a pre-configured connector action:

{
  type: 'connector_action',
  connectorId: 'slack',
  actionId: 'send_message',
  input: {
    channel: '#sales',
    text: 'Deal closed: {record.name} - {record.amount}',
  },
}

Push Notification

Send a mobile/web push notification:

{
  type: 'push_notification',
  title: 'New Assignment',
  body: 'You have been assigned to {record.name}',
  recipients: ['{record.assignee}'],
}

Custom Script

Execute custom business logic:

{
  type: 'custom_script',
  language: 'javascript',
  code: `
    const discount = record.amount > 10000 ? 0.15 : 0.05;
    await updateRecord('opportunity', record.id, {
      discount_rate: discount,
    });
  `,
  timeout: 30000,
}

Time Triggers

Schedule actions to run at a specified time relative to a trigger event or date field:

timeTriggers: [
  {
    timeLength: 3,
    timeUnit: 'days',
    offsetDirection: 'before',
    offsetFrom: 'date_field',
    dateField: 'due_date',
    actions: [
      {
        type: 'email_alert',
        template: 'reminder_due_soon',
        recipients: ['{record.owner.email}'],
      },
    ],
  },
  {
    timeLength: 1,
    timeUnit: 'hours',
    offsetDirection: 'after',
    offsetFrom: 'trigger_date',
    actions: [
      {
        type: 'field_update',
        field: 'follow_up_sent',
        value: 'true',
      },
    ],
  },
]

Time Trigger Properties

PropertyTypeDescription
timeLengthnumberDuration value
timeUnitenum'minutes', 'hours', 'days'
offsetDirectionenum'before' or 'after' the reference time
offsetFromenum'trigger_date' (when workflow fires) or 'date_field'
dateFieldstringDate field name (required when offsetFrom is 'date_field')
actionsAction[]Actions to execute at the scheduled time

Execution Order

When multiple workflows match the same event, executionOrder determines the sequence:

// Runs first (lower number = higher priority)
{ name: 'validate_amount', executionOrder: 10, ... }

// Runs second
{ name: 'update_status', executionOrder: 20, ... }

// Runs third
{ name: 'send_notification', executionOrder: 30, ... }

Complete Example

const leadConversion = {
  name: 'lead_qualified',
  objectName: 'lead',
  triggerType: 'on_update',
  criteria: "status = 'qualified' AND ISCHANGED(status)",
  active: true,
  executionOrder: 10,

  actions: [
    {
      type: 'field_update',
      field: 'qualified_date',
      value: 'TODAY()',
    },
    {
      type: 'email_alert',
      template: 'lead_qualified_alert',
      recipients: ['{record.owner.email}'],
    },
    {
      type: 'http_call',
      url: 'https://api.company.com/crm/convert',
      method: 'POST',
      body: { lead_id: '{record.id}' },
    },
    {
      type: 'task_creation',
      taskObject: 'task',
      subject: 'Schedule demo for {record.company}',
      assignedTo: '{record.owner}',
      dueDate: 'TODAY() + 2',
    },
  ],

  timeTriggers: [
    {
      timeLength: 7,
      timeUnit: 'days',
      offsetDirection: 'after',
      offsetFrom: 'trigger_date',
      actions: [
        {
          type: 'email_alert',
          template: 'follow_up_reminder',
          recipients: ['{record.owner.email}'],
        },
      ],
    },
  ],
};

Flow vs. Workflow

AspectWorkflow RuleFlow
TriggerData events (create/update/delete)Manual, API, schedule, or data events
LogicLinear actionsVisual branching with decision trees
User InteractionNoSupports screen nodes
ComplexitySimple rulesComplex orchestration
Use CaseField updates, notificationsApproval processes, multi-step logic

Rule of thumb: Use Workflow Rules for simple "when X happens, do Y" automation. Use Flows for complex multi-step logic with branching.

On this page