Built-in Functions
Pure, stateless built-in functions available in every Lodol workflow expression.
Built-in Functions
Built-in functions are pure, stateless helpers that are evaluated directly inside the workflow expression engine. They require no external credentials and are available in every workflow.
Built-ins are referenced in the workflow AST using their kind discriminant. The tables below list each function, its AST node fields, return type, and a usage example.
Text
LowerCase
Convert a string to lowercase.
| Field | Type | Description |
|---|---|---|
kind | "LowerCaseBuiltIn" | Node discriminant |
value | expression | String to convert |
Returns: string
{
"kind": "LowerCaseBuiltIn",
"value": { "kind": "Literal", "value": "Hello World" }
}Result: "hello world"
UpperCase
Convert a string to uppercase.
| Field | Type | Description |
|---|---|---|
kind | "UpperCaseBuiltIn" | Node discriminant |
value | expression | String to convert |
Returns: string
{
"kind": "UpperCaseBuiltIn",
"value": { "kind": "Literal", "value": "hello world" }
}Result: "HELLO WORLD"
Capitalize
Uppercase the first character and lowercase the rest.
| Field | Type | Description |
|---|---|---|
kind | "CapitalizeBuiltIn" | Node discriminant |
value | expression | String to capitalize |
Returns: string
{
"kind": "CapitalizeBuiltIn",
"value": { "kind": "Literal", "value": "hello world" }
}Result: "Hello world"
TitleCase
Title-case every word in a string (whitespace preserved).
| Field | Type | Description |
|---|---|---|
kind | "TitleCaseBuiltIn" | Node discriminant |
value | expression | String to title-case |
Returns: string
{
"kind": "TitleCaseBuiltIn",
"value": { "kind": "Literal", "value": "hello world" }
}Result: "Hello World"
TextLength
Count the number of characters in a string.
| Field | Type | Description |
|---|---|---|
kind | "TextLengthBuiltIn" | Node discriminant |
value | expression | String to measure |
Returns: number
{
"kind": "TextLengthBuiltIn",
"value": { "kind": "Literal", "value": "hello" }
}Result: 5
StartsWith
Check whether a string begins with a given prefix.
| Field | Type | Description |
|---|---|---|
kind | "StartsWithBuiltIn" | Node discriminant |
string | expression | The string to test |
prefix | expression | The prefix to look for |
Returns: boolean
{
"kind": "StartsWithBuiltIn",
"string": { "kind": "Literal", "value": "https://example.com" },
"prefix": { "kind": "Literal", "value": "https" }
}Result: true
EndsWith
Check whether a string ends with a given suffix.
| Field | Type | Description |
|---|---|---|
kind | "EndsWithBuiltIn" | Node discriminant |
string | expression | The string to test |
suffix | expression | The suffix to look for |
Returns: boolean
{
"kind": "EndsWithBuiltIn",
"string": { "kind": "Literal", "value": "report.pdf" },
"suffix": { "kind": "Literal", "value": ".pdf" }
}Result: true
TextContains
Check whether a string contains a given substring.
| Field | Type | Description |
|---|---|---|
kind | "TextContainsBuiltIn" | Node discriminant |
string | expression | The string to search within |
substring | expression | The substring to find |
Returns: boolean
{
"kind": "TextContainsBuiltIn",
"string": { "kind": "Literal", "value": "Welcome to Lodol" },
"substring": { "kind": "Literal", "value": "Lodol" }
}Result: true
Replace
Replace all occurrences of a substring within a string.
| Field | Type | Description |
|---|---|---|
kind | "ReplaceBuiltIn" | Node discriminant |
string | expression | The source string |
search | expression | Substring to find |
replace | expression | Replacement string |
Returns: string
{
"kind": "ReplaceBuiltIn",
"string": { "kind": "Literal", "value": "foo bar foo" },
"search": { "kind": "Literal", "value": "foo" },
"replace": { "kind": "Literal", "value": "baz" }
}Result: "baz bar baz"
Split
Split a string into an array by a delimiter.
| Field | Type | Description |
|---|---|---|
kind | "SplitBuiltIn" | Node discriminant |
string | expression | The string to split |
delimiter | expression | Delimiter string |
Returns: string[]
{
"kind": "SplitBuiltIn",
"string": { "kind": "Literal", "value": "a,b,c" },
"delimiter": { "kind": "Literal", "value": "," }
}Result: ["a", "b", "c"]
Truncate
Truncate a string to a maximum length, appending an ellipsis if the string was shortened.
| Field | Type | Required | Description |
|---|---|---|---|
kind | "TruncateBuiltIn" | Yes | Node discriminant |
string | expression | Yes | The string to truncate |
length | expression | Yes | Maximum number of characters (non-negative integer) |
ellipsis | expression | No | String appended when truncated (defaults to "…") |
Returns: string
{
"kind": "TruncateBuiltIn",
"string": { "kind": "Literal", "value": "Hello, world!" },
"length": { "kind": "Literal", "value": 5 },
"ellipsis": { "kind": "Literal", "value": "..." }
}Result: "Hello..."
IsURL
Return true if the string is a valid http or https URL with no whitespace.
| Field | Type | Description |
|---|---|---|
kind | "IsURLBuiltIn" | Node discriminant |
value | expression | String to validate |
Returns: boolean
{
"kind": "IsURLBuiltIn",
"value": { "kind": "Literal", "value": "https://skipflow.com" }
}Result: true
IsEmail
Return true if the string is a valid email address.
| Field | Type | Description |
|---|---|---|
kind | "IsEmailBuiltIn" | Node discriminant |
value | expression | String to validate |
Returns: boolean
{
"kind": "IsEmailBuiltIn",
"value": { "kind": "Literal", "value": "user@example.com" }
}Result: true
Lists
Length
Return the number of items in an array.
| Field | Type | Description |
|---|---|---|
kind | "LengthBuiltIn" | Node discriminant |
value | expression | Array to measure |
Returns: number
{
"kind": "LengthBuiltIn",
"value": { "kind": "Literal", "value": [1, 2, 3] }
}Result: 3
ListContains
Return true if any element in the list is deeply equal to value.
| Field | Type | Description |
|---|---|---|
kind | "ListContainsBuiltIn" | Node discriminant |
list | expression | Array to search |
value | expression | Value to look for |
Returns: boolean
{
"kind": "ListContainsBuiltIn",
"list": { "kind": "Literal", "value": ["a", "b", "c"] },
"value": { "kind": "Literal", "value": "b" }
}Result: true
IndexOf
Return the zero-based index of the first element deeply equal to value, or -1 if not found.
| Field | Type | Description |
|---|---|---|
kind | "IndexOfBuiltIn" | Node discriminant |
list | expression | Array to search |
value | expression | Value to find |
Returns: number
{
"kind": "IndexOfBuiltIn",
"list": { "kind": "Literal", "value": ["a", "b", "c"] },
"value": { "kind": "Literal", "value": "c" }
}Result: 2
Slice
Return a sub-array from start (inclusive) to end (exclusive). Both indices must be non-negative integers and within bounds.
| Field | Type | Description |
|---|---|---|
kind | "SliceBuiltIn" | Node discriminant |
list | expression | Source array |
start | expression | Start index (inclusive, non-negative integer) |
end | expression | End index (exclusive, non-negative integer) |
Returns: array
{
"kind": "SliceBuiltIn",
"list": { "kind": "Literal", "value": [10, 20, 30, 40, 50] },
"start": { "kind": "Literal", "value": 1 },
"end": { "kind": "Literal", "value": 4 }
}Result: [20, 30, 40]
Sort
Return a sorted copy of the array. Supports mixed types using Lodol's comparison order: null < boolean < number < string < array < object.
| Field | Type | Description |
|---|---|---|
kind | "SortBuiltIn" | Node discriminant |
value | expression | Array to sort |
Returns: array
{
"kind": "SortBuiltIn",
"value": { "kind": "Literal", "value": [3, 1, 2] }
}Result: [1, 2, 3]
Reverse
Return a reversed copy of the array.
| Field | Type | Description |
|---|---|---|
kind | "ReverseBuiltIn" | Node discriminant |
value | expression | Array to reverse |
Returns: array
{
"kind": "ReverseBuiltIn",
"value": { "kind": "Literal", "value": [1, 2, 3] }
}Result: [3, 2, 1]
Append
Return a new array with value appended to the end. The original array is not mutated.
| Field | Type | Description |
|---|---|---|
kind | "AppendBuiltIn" | Node discriminant |
list | expression | Source array |
value | expression | Value to append |
Returns: array
{
"kind": "AppendBuiltIn",
"list": { "kind": "Literal", "value": [1, 2] },
"value": { "kind": "Literal", "value": 3 }
}Result: [1, 2, 3]
Insert
Return a new array with value inserted at index. The index must be between 0 and length (inclusive).
| Field | Type | Description |
|---|---|---|
kind | "InsertBuiltIn" | Node discriminant |
list | expression | Source array |
index | expression | Position to insert at (integer) |
value | expression | Value to insert |
Returns: array
{
"kind": "InsertBuiltIn",
"list": { "kind": "Literal", "value": [1, 3] },
"index": { "kind": "Literal", "value": 1 },
"value": { "kind": "Literal", "value": 2 }
}Result: [1, 2, 3]
RemoveAt
Return a new array with the element at index removed. The index must be within bounds.
| Field | Type | Description |
|---|---|---|
kind | "RemoveAtBuiltIn" | Node discriminant |
list | expression | Source array |
index | expression | Index of the element to remove (integer) |
Returns: array
{
"kind": "RemoveAtBuiltIn",
"list": { "kind": "Literal", "value": ["a", "b", "c"] },
"index": { "kind": "Literal", "value": 1 }
}Result: ["a", "c"]
RemoveDuplicates
Return a new array with duplicate values removed (stable order, deep equality).
| Field | Type | Description |
|---|---|---|
kind | "RemoveDuplicatesBuiltIn" | Node discriminant |
value | expression | Array to deduplicate |
Returns: array
{
"kind": "RemoveDuplicatesBuiltIn",
"value": { "kind": "Literal", "value": [1, 2, 1, 3, 2] }
}Result: [1, 2, 3]
RandomSample
Return up to count randomly selected unique elements from the list (deep-copied).
| Field | Type | Description |
|---|---|---|
kind | "RandomSampleBuiltIn" | Node discriminant |
list | expression | Source array |
count | expression | Number of elements to sample (non-negative integer) |
Returns: array
{
"kind": "RandomSampleBuiltIn",
"list": { "kind": "Literal", "value": ["a", "b", "c", "d"] },
"count": { "kind": "Literal", "value": 2 }
}Result: e.g. ["c", "a"] (random)
Math
Round
Round a number to the nearest integer (ties round up).
| Field | Type | Description |
|---|---|---|
kind | "RoundBuiltIn" | Node discriminant |
value | expression | Finite number to round |
Returns: number
{
"kind": "RoundBuiltIn",
"value": { "kind": "Literal", "value": 2.5 }
}Result: 3
Floor
Return the greatest integer less than or equal to the value.
| Field | Type | Description |
|---|---|---|
kind | "FloorBuiltIn" | Node discriminant |
value | expression | Finite number |
Returns: number
{
"kind": "FloorBuiltIn",
"value": { "kind": "Literal", "value": 2.9 }
}Result: 2
Ceiling
Return the smallest integer greater than or equal to the value.
| Field | Type | Description |
|---|---|---|
kind | "CeilingBuiltIn" | Node discriminant |
value | expression | Finite number |
Returns: number
{
"kind": "CeilingBuiltIn",
"value": { "kind": "Literal", "value": 2.1 }
}Result: 3
AbsoluteValue
Return the absolute value of a finite number.
| Field | Type | Description |
|---|---|---|
kind | "AbsoluteValueBuiltIn" | Node discriminant |
value | expression | Finite number |
Returns: number
{
"kind": "AbsoluteValueBuiltIn",
"value": { "kind": "Literal", "value": -42 }
}Result: 42
Min
Return the minimum value in a non-empty array of finite numbers.
| Field | Type | Description |
|---|---|---|
kind | "MinBuiltIn" | Node discriminant |
value | expression | Non-empty array of numbers |
Returns: number
{
"kind": "MinBuiltIn",
"value": { "kind": "Literal", "value": [3, 1, 4, 1, 5] }
}Result: 1
Max
Return the maximum value in a non-empty array of finite numbers.
| Field | Type | Description |
|---|---|---|
kind | "MaxBuiltIn" | Node discriminant |
value | expression | Non-empty array of numbers |
Returns: number
{
"kind": "MaxBuiltIn",
"value": { "kind": "Literal", "value": [3, 1, 4, 1, 5] }
}Result: 5
Total
Return the sum of all numbers in an array. Returns 0 for an empty array.
| Field | Type | Description |
|---|---|---|
kind | "TotalBuiltIn" | Node discriminant |
value | expression | Array of finite numbers |
Returns: number
{
"kind": "TotalBuiltIn",
"value": { "kind": "Literal", "value": [10, 20, 30] }
}Result: 60
Mean
Return the arithmetic mean of a non-empty array of finite numbers.
| Field | Type | Description |
|---|---|---|
kind | "MeanBuiltIn" | Node discriminant |
value | expression | Non-empty array of numbers |
Returns: number
{
"kind": "MeanBuiltIn",
"value": { "kind": "Literal", "value": [10, 20, 30] }
}Result: 20
Mode
Return the most frequently occurring number in a non-empty array. Ties are broken by first appearance; if counts are equal the smaller first-seen index wins.
| Field | Type | Description |
|---|---|---|
kind | "ModeBuiltIn" | Node discriminant |
value | expression | Non-empty array of numbers |
Returns: number
{
"kind": "ModeBuiltIn",
"value": { "kind": "Literal", "value": [1, 2, 2, 3] }
}Result: 2
RandomInteger
Return a random integer in the inclusive range [min, max].
| Field | Type | Description |
|---|---|---|
kind | "RandomIntegerBuiltIn" | Node discriminant |
min | expression | Lower bound (integer) |
max | expression | Upper bound (integer, must be ≥ min) |
Returns: number
{
"kind": "RandomIntegerBuiltIn",
"min": { "kind": "Literal", "value": 1 },
"max": { "kind": "Literal", "value": 10 }
}Result: e.g. 7 (random)
RandomReal
Return a random real number in [min, max). When min == max, returns min.
| Field | Type | Description |
|---|---|---|
kind | "RandomRealBuiltIn" | Node discriminant |
min | expression | Lower bound (finite number) |
max | expression | Upper bound (finite number, must be ≥ min) |
Returns: number
{
"kind": "RandomRealBuiltIn",
"min": { "kind": "Literal", "value": 0 },
"max": { "kind": "Literal", "value": 1 }
}Result: e.g. 0.6372 (random)
Date & Time
Now
Return the current UTC datetime as an ISO-8601 string with millisecond precision (e.g. "2025-06-01T12:00:00.000Z").
| Field | Type | Description |
|---|---|---|
kind | "NowBuiltIn" | Node discriminant |
Returns: string (ISO-8601)
{ "kind": "NowBuiltIn" }Result: "2025-06-01T12:00:00.000Z" (current UTC time)
Today
Return today's local date as a YYYY-MM-DD string.
| Field | Type | Description |
|---|---|---|
kind | "TodayBuiltIn" | Node discriminant |
Returns: string
{ "kind": "TodayBuiltIn" }Result: "2025-06-01"
Tomorrow
Return tomorrow's local date as a YYYY-MM-DD string.
| Field | Type | Description |
|---|---|---|
kind | "TomorrowBuiltIn" | Node discriminant |
Returns: string
{ "kind": "TomorrowBuiltIn" }Result: "2025-06-02"
Yesterday
Return yesterday's local date as a YYYY-MM-DD string.
| Field | Type | Description |
|---|---|---|
kind | "YesterdayBuiltIn" | Node discriminant |
Returns: string
{ "kind": "YesterdayBuiltIn" }Result: "2025-05-31"
UnixTimestamp
Return the current UTC Unix timestamp in whole seconds.
| Field | Type | Description |
|---|---|---|
kind | "UnixTimestampBuiltIn" | Node discriminant |
Returns: number
{ "kind": "UnixTimestampBuiltIn" }Result: 1748779200
WeekdayName
Return the name of the weekday ("Sunday" through "Saturday") for a given ISO-8601 date string, evaluated in UTC.
| Field | Type | Description |
|---|---|---|
kind | "WeekdayNameBuiltIn" | Node discriminant |
date | expression | ISO-8601 date or datetime string |
Returns: string
{
"kind": "WeekdayNameBuiltIn",
"date": { "kind": "Literal", "value": "2025-06-02" }
}Result: "Monday"
TimeUntil
Return the number of whole seconds until the given ISO-8601 datetime (negative if in the past).
| Field | Type | Description |
|---|---|---|
kind | "TimeUntilBuiltIn" | Node discriminant |
date | expression | ISO-8601 date or datetime string |
Returns: number
{
"kind": "TimeUntilBuiltIn",
"date": { "kind": "Literal", "value": "2025-12-31T23:59:59Z" }
}Result: seconds remaining until that date
Wait
Pause workflow execution for the given number of seconds. Maximum duration is 86400 seconds (24 hours).
| Field | Type | Description |
|---|---|---|
kind | "WaitBuiltIn" | Node discriminant |
seconds | expression | Positive integer number of seconds (max 86400) |
Returns: null
{
"kind": "WaitBuiltIn",
"seconds": { "kind": "Literal", "value": 30 }
}IsHoliday
Return true if the given date is a public holiday in the specified region (defaults to "US"). Accepts ISO-8601 date strings or datetime strings.
| Field | Type | Required | Description |
|---|---|---|---|
kind | "IsHolidayBuiltIn" | Yes | Node discriminant |
date | expression | Yes | ISO-8601 date or datetime string |
region | expression | No | ISO 3166-1 alpha-2 country code (e.g. "US", "GB") |
Returns: boolean
{
"kind": "IsHolidayBuiltIn",
"date": { "kind": "Literal", "value": "2025-12-25" },
"region": { "kind": "Literal", "value": "US" }
}Result: true
Validation
IsPhoneNumber
Return true if the string is a valid phone number for the given region (defaults to "US"). The region must be an ISO 3166-1 alpha-2 country code.
| Field | Type | Required | Description |
|---|---|---|---|
kind | "IsPhoneNumberBuiltIn" | Yes | Node discriminant |
value | expression | Yes | Phone number string to validate |
region | expression | No | ISO 3166-1 alpha-2 country code (default "US") |
Returns: boolean
{
"kind": "IsPhoneNumberBuiltIn",
"value": { "kind": "Literal", "value": "+14155552671" },
"region": { "kind": "Literal", "value": "US" }
}Result: true
Output
Display
Return a deep copy of the given value. Used to surface a value as a visible output in the workflow execution log.
| Field | Type | Description |
|---|---|---|
kind | "DisplayBuiltIn" | Node discriminant |
value | expression | Any value to display |
Returns: the same value (deep-copied)
{
"kind": "DisplayBuiltIn",
"value": { "kind": "Literal", "value": "Hello, world!" }
}Result: "Hello, world!"