Skip to main content
Workflow expressions let you pass data between steps in C1 automations - like threading a user’s email from a trigger into a lookup step, then into a notification. This is the most powerful CEL context because data flows through multiple steps, and each step can access outputs from all previous steps.

Core concept: The ctx object

All workflow expressions access data through the ctx object, which contains: Steps can only access data from previously completed steps. The ctx object grows as the workflow progresses - each step adds its output.

Template syntax

Workflow expressions use double curly braces for interpolation:
The expression is evaluated and replaced with its result.

String templates

Result: Hello John Smith!

JSON templates

When the entire template is valid JSON after interpolation, it’s parsed as a structured object:
Result: A structured object with name and email fields accessible in later steps.
Template expressions are evaluated at runtime when the step executes. If a referenced field doesn’t exist, the step will fail.

Available variables

From trigger

The trigger context varies by workflow trigger type. Common patterns:

From previous steps

Access output from any completed step by its step name:
Step names in ctx.<step_name> must match exactly. If you rename a step, update all references to it in later steps.

Step data flow patterns

Pass user from trigger to lookup

Step 1 (trigger): User change event fires Step 2 (lookup): Find user details
Step 3 (action): Use looked-up data

Chain multiple lookups

Conditional step execution

Use CEL in step conditions to skip steps based on previous data:

Common workflow expressions

User change detection

Building notification messages

Extracting data for API calls

Safe field access with has()


What can go wrong

Referencing undefined step

Error: Step fails with “undefined reference” Cause: Referencing a step that hasn’t run yet or doesn’t exist.
Solution: Only reference steps that complete before the current step. Check step names match exactly.

Wrong trigger type

Error: Field not found in trigger Cause: Using user-change fields when trigger is account-change (or vice versa).

Template syntax errors

Error: {{ERROR}} appears in output Cause: Malformed template expression.

Null reference in chain

Error: Step fails partway through Cause: Intermediate value is null.

Best practices

Name steps clearly

Use descriptive step names that indicate what they do:
This makes expressions self-documenting:

Check for nulls in chains

When accessing nested data across steps:

Use step conditions to skip gracefully

Instead of failing on missing data, use step conditions:

Test with representative data

Before deploying:
  1. Identify the trigger type and what data it provides
  2. Trace the data flow through each step
  3. Check for potential null values at each step
  4. Verify step execution order