← Back to Guides

Logic Apps Expressions and Functions

IntermediateAzure Logic Apps2026-03-14

Understanding Expressions

Azure Logic Apps uses the Workflow Definition Language (WDL) for expressions. You can use expressions in action inputs by wrapping them in @{...} for inline use or using @ as a prefix for standalone expressions.

Microsoft Reference: Workflow Definition Language schema

Expression Syntax

Syntax Usage Example
@{expression} Inline within a string "Hello @{triggerBody()?['name']}"
@expression Standalone value @triggerBody()?['orderId']
@{expression1} text @{expression2} Multiple inline "Order @{body('GetOrder')?['id']} for @{body('GetOrder')?['customer']}"

Accessing Data

Function Purpose Example
triggerBody() Get trigger request body @triggerBody()?['orderId']
triggerOutputs() Get trigger outputs (including headers) @triggerOutputs()?['headers']?['X-Request-Id']
body('actionName') Get action output body @body('HTTP_Call')?['data']
outputs('actionName') Get full action outputs @outputs('HTTP_Call')?['statusCode']
actions('actionName') Get action status and outputs @actions('HTTP_Call')?['status']
items('For_each') Current item in a For Each loop @items('For_each')?['name']
iterationIndexes('For_each') Current iteration index @iterationIndexes('For_each')
result('Scope') Results of all actions in a Scope @result('Try_Scope')
variables('varName') Get a variable value @variables('orderCount')
parameters('paramName') Get a workflow parameter @parameters('apiUrl')
workflow() Workflow metadata @workflow()?['run']?['name']

Microsoft Reference: Expression functions reference

String Functions

Function Example Result
concat() concat('Hello', ' ', 'World') Hello World
substring() substring('Hello World', 0, 5) Hello
replace() replace('Hello World', 'World', 'Azure') Hello Azure
toLower() toLower('HELLO') hello
toUpper() toUpper('hello') HELLO
trim() trim(' hello ') hello
length() length('hello') 5
startsWith() startsWith('Hello World', 'Hello') true
endsWith() endsWith('Hello World', 'World') true
indexOf() indexOf('Hello World', 'World') 6
lastIndexOf() lastIndexOf('test/path/file', '/') 9
split() split('a,b,c', ',') ["a","b","c"]
join() join(createArray('a','b','c'), ',') a,b,c
guid() guid() Random GUID string
nthIndexOf() nthIndexOf('a.b.c.d', '.', 2) 3
slice() slice('Hello World', 6) World
chunk() chunk('abcdef', 2) ["ab","cd","ef"]

String Manipulation Examples

// Extract filename from path
@last(split(triggerBody()?['filePath'], '/'))

// Build a reference number
@concat('ORD-', formatDateTime(utcNow(), 'yyyyMMdd'), '-', guid())

// Mask sensitive data (show last 4 characters)
@concat('****', substring(variables('cardNumber'), sub(length(variables('cardNumber')), 4), 4))

// URL encode a value
@encodeUriComponent(triggerBody()?['searchTerm'])

Date and Time Functions

Working with dates is common in Logic Apps:

utcNow()                                        // Current UTC time
utcNow('yyyy-MM-ddTHH:mm:ssZ')                  // Formatted UTC
addDays(utcNow(), 7)                             // 7 days from now
addHours(utcNow(), -2)                           // 2 hours ago
addMinutes(utcNow(), 30)                         // 30 minutes from now
addSeconds(utcNow(), 0)                          // Current time (useful for casting)
formatDateTime(utcNow(), 'yyyy-MM-dd')           // Date as string
formatDateTime(utcNow(), 'dd/MM/yyyy HH:mm')     // UK format
ticks(utcNow())                                  // Ticks for comparison
convertFromUtc(utcNow(), 'GMT Standard Time')    // Convert timezone
convertToUtc('2026-03-14T10:00:00', 'GMT Standard Time')  // Convert to UTC
startOfDay(utcNow())                             // Start of current day
startOfMonth(utcNow())                           // Start of current month
startOfHour(utcNow())                            // Start of current hour
dayOfWeek(utcNow())                              // 0 (Sunday) to 6 (Saturday)
dayOfMonth(utcNow())                             // 1 to 31
dayOfYear(utcNow())                              // 1 to 366

Date Comparison Patterns

// Check if a date is in the past
@less(ticks(triggerBody()?['expiryDate']), ticks(utcNow()))

// Calculate age in days
@div(sub(ticks(utcNow()), ticks(triggerBody()?['createdDate'])), 864000000000)

// Check if within business hours (9 AM to 5 PM UK time)
@and(
  greaterOrEquals(int(formatDateTime(convertFromUtc(utcNow(), 'GMT Standard Time'), 'HH')), 9),
  less(int(formatDateTime(convertFromUtc(utcNow(), 'GMT Standard Time'), 'HH')), 17)
)

Microsoft Reference: Date and time functions

Collection Functions

When working with arrays and objects:

Function Description Example
first() First element first(body('Get_rows')?['value'])
last() Last element last(split(variables('path'), '/'))
contains() Check existence contains(triggerBody()?['roles'], 'admin')
empty() Check if null/empty empty(triggerBody()?['items'])
length() Count elements length(body('Get_rows')?['value'])
union() Merge arrays union(variables('list1'), variables('list2'))
intersection() Common elements intersection(variables('a'), variables('b'))
skip() Skip N elements skip(variables('items'), 10)
take() Take N elements take(variables('items'), 5)
createArray() Create an array createArray('a', 'b', 'c')
range() Number range range(1, 10)
sort() Sort array sort(variables('items'))
reverse() Reverse array reverse(variables('items'))

Object Functions

Function Description Example
json() Parse JSON string json(body('HTTP'))
xml() Convert to XML xml(variables('jsonData'))
xpath() Query XML xpath(xml(body('HTTP')), '//order/id/text()')
setProperty() Set object property setProperty(body('Get_item'), 'status', 'processed')
removeProperty() Remove property removeProperty(body('Get_item'), 'internalId')
addProperty() Add property addProperty(body('Get_item'), 'timestamp', utcNow())

Filtering and Transforming Arrays

// Filter with a condition action after For Each
// Use Select (map) action for transformation
// Use Filter Array action for filtering

// Check if any items match
@greater(length(body('Filter_array')), 0)

// Pagination — take page 2 (10 items per page)
@take(skip(body('Get_rows')?['value'], 10), 10)

Conditional Expressions

Use the if() function for conditional logic:

if(equals(triggerBody()?['status'], 'approved'), 'Process', 'Reject')

Comparison Functions

Function Description Example
equals() Equality equals(variables('status'), 'active')
greater() Greater than greater(variables('count'), 100)
greaterOrEquals() Greater or equal greaterOrEquals(variables('score'), 80)
less() Less than less(variables('retries'), 3)
lessOrEquals() Less or equal lessOrEquals(length(variables('items')), 50)
and() Logical AND and(equals(a, 1), equals(b, 2))
or() Logical OR or(equals(status, 'error'), equals(status, 'failed'))
not() Logical NOT not(empty(triggerBody()?['email']))

Null-Safe Navigation

// The ? operator prevents null reference errors
@triggerBody()?['customer']?['address']?['city']

// Use coalesce for default values
@coalesce(triggerBody()?['priority'], 'normal')

// Multiple fallback values
@coalesce(triggerBody()?['preferredEmail'], triggerBody()?['email'], 'no-email@example.com')

Conversion Functions

Function Description Example
int() Convert to integer int('42')
float() Convert to float float('3.14')
string() Convert to string string(42)
bool() Convert to boolean bool('true')
array() Convert to array array('hello')
json() Parse JSON string json('{"key":"value"}')
xml() Convert to XML xml(variables('jsonString'))
base64() Encode to base64 base64('Hello')
base64ToString() Decode base64 base64ToString(body('Get_blob'))
base64ToBinary() Base64 to binary base64ToBinary(body('Get_file'))
binary() Convert to binary binary('text content')
decodeBase64() Decode base64 (legacy) decodeBase64(variables('encoded'))
encodeUriComponent() URL encode encodeUriComponent('hello world')
decodeUriComponent() URL decode decodeUriComponent('hello%20world')
dataUri() Convert to data URI dataUri('text/plain;charset=utf-8')
uriHost() Extract host from URI uriHost('https://example.com/path')
uriPath() Extract path from URI uriPath('https://example.com/path')
uriQuery() Extract query string uriQuery('https://example.com?key=value')

Math Functions

Function Description Example
add() Addition add(variables('total'), variables('tax'))
sub() Subtraction sub(variables('balance'), variables('payment'))
mul() Multiplication mul(variables('quantity'), variables('price'))
div() Division div(variables('total'), variables('count'))
mod() Modulo mod(variables('index'), 2)
min() Minimum value min(variables('a'), variables('b'))
max() Maximum value max(variables('a'), variables('b'))
rand() Random integer rand(1, 100)

Advanced Patterns

Dynamic Property Access

// Access a property dynamically
@body('HTTP')[variables('propertyName')]

// Build dynamic paths
@body('Get_rows')?['value']?[0]?[variables('columnName')]

Working with HTTP Responses

// Get status code
@outputs('HTTP_Call')?['statusCode']

// Get a specific response header
@outputs('HTTP_Call')?['headers']?['Content-Type']

// Check if request was successful
@equals(outputs('HTTP_Call')?['statusCode'], 200)

// Parse response body
@body('HTTP_Call')

// Get the raw body as string
@string(body('HTTP_Call'))

Working with Action Results

// Get status of a previous action
@actions('Send_email')?['status']

// Get all action results within a scope
@result('Try_Scope')

// Filter failed actions
@filter(result('Try_Scope'), item => item['status'] == 'Failed')

// Get the error message from a failed action
@actions('HTTP_Call')?['error']?['message']

Best Practices

  1. Use coalesce() to handle null values gracefully — avoids workflow failures on missing data
  2. Prefer outputs() over body() for accessing action results when you need headers or status codes
  3. Use triggerOutputs() headers for HTTP trigger metadata like Content-Type or custom headers
  4. Test expressions in the designer using the expression editor's evaluation feature
  5. Use the ? operator for null-safe property access — triggerBody()?['prop'] instead of triggerBody()['prop']
  6. Avoid complex nested expressions — use Compose actions to break down complex transformations
  7. Use result() in Catch scopes to get detailed error information from Try scopes
  8. Prefer formatDateTime() over string manipulation when working with dates
  9. Use createArray() and createObject() to construct data structures inline

Tip: The Logic Apps expression editor provides IntelliSense — start typing a function name to see suggestions and parameter hints.

Official Microsoft Resources