Power Automate Expressions
Expressions unlock the full power of Power Automate. This guide teaches you the logic, the editor, and every major function category, with real examples you can start using today.
What are expressions?
In Power Automate, most action inputs accept either a dynamic value (a piece of data from a previous step) or a static value (text you type in). Expressions are a third option that lets you compute a value using a formula, combining functions, dynamic data, and constants.
Think of expressions as the formula bar in Excel, but for your flow. Instead of clicking a cell reference, you reference flow data. Instead of =UPPER(A1), you write toUpper(triggerBody()?['Title']).
Every expression is evaluated at runtime, meaning Power Automate runs the formula and replaces it with the computed result before passing that value to the action.
Expressions are not required for simple flows, but as soon as you need to format a date, combine two fields, check a condition, or reshape data, they become essential.
The expression editor
To write an expression, click inside any action input field. A small lightning bolt icon or the dynamic content panel will appear. Switch to the Expression tab in the dynamic content panel. You will see a text box where you type your formula.
When you click OK, the expression is saved. In the designer, it shows as a blue pill with the function name visible. To edit it, just click the pill again.
You can mix expressions with static text by wrapping them in the dynamic content panel. For example, you can type Hello as static text and then insert a concat() expression after it, or just use concat('Hello ', body()?['Name']) entirely in the expression tab.
Expressions are case-sensitive for function names. formatDateTime works. FormatDateTime will cause an error.
String functions
String functions let you build, clean, slice, and search text values. These are used in almost every real-world flow: formatting names, building email subjects, extracting substrings from codes, and more.
concat: Joining strings together
concat(value1, value2, ...) joins any number of strings into one. You can pass as many arguments as you need.
Expression
concat('Hello ', triggerBody()?['FirstName'], ' ', triggerBody()?['LastName'])Result
Hello Sarah JonestriggerBody()?['FirstName'] reads the FirstName field from the trigger. The ? handles null safely.
toUpper and toLower
Normalise case for comparisons or display. Always lowercase before comparing. Otherwise "London" and "london" are treated as different values.
Expression
toUpper('power automate')Result
POWER AUTOMATEExpression
toLower(triggerBody()?['Department'])Result
engineeringtrim: Removing whitespace
User-entered data often has accidental leading or trailing spaces. trim() removes them.
Input
' Invoice Number 'Expression
trim(' Invoice Number ')Result
Invoice Numberreplace: Substituting text
replace(text, findText, replaceWith) replaces every occurrence of a substring. Useful for sanitising filenames, stripping characters, or formatting codes.
Expression
replace('2026/05/17', '/', '-')Result
2026-05-17substring: Extracting part of a string
substring(text, startIndex, length) extracts a portion. Index starts at 0. The third parameter is the length: how many characters to take.
Expression
substring('INV-2026-00042', 4, 4)Result
2026Starts at position 4, takes 4 characters.
indexOf and lastIndexOf
indexOf(text, searchText) returns the position of the first match (0-based). Returns -1 if not found. Combine with substring to extract dynamic parts.
Expression
indexOf('user@company.com', '@')Result
4startsWith and endsWith
Return true or false. Great inside if() conditions.
Expression
startsWith('INV-2026-001', 'INV')Result
truesplit: Turning a string into an array
split(text, delimiter) breaks a string into an array of substrings. The result can be used in an Apply to Each loop.
Expression
split('apples,oranges,bananas', ',')Result
["apples","oranges","bananas"]length: Counting characters
Expression
length('Power Automate')Result
14Logical functions
Logical functions evaluate conditions and return values based on whether conditions are true or false. They are the backbone of dynamic flow behaviour.
if: The ternary operator
if(condition, valueIfTrue, valueIfFalse) is the most important logical function. It evaluates a condition and returns one of two values. There is no built-in IF action in cloud flows for expressions. This is your tool.
Expression
if(greater(variables('Score'), 80), 'Pass', 'Fail')Result
Pass (when Score is 90)Expression
if(equals(triggerBody()?['Status'], 'Approved'), 'green', 'red')Result
green (when Status is Approved)equals, not, greater, greaterOrEquals, less, lessOrEquals
These comparison functions all return true or false and are typically used inside if() or as condition expressions.
Expression
equals('London', 'London')Result
trueExpression
greater(42, 10)Result
trueExpression
not(equals(variables('Status'), 'Done'))Result
true (when Status is not Done)and / or
Combine multiple conditions. and(condition1, condition2) is true only if both are true. or(condition1, condition2) is true if either is true.
Expression
and(greater(variables('Score'), 50), equals(variables('Submitted'), true))Result
true (when Score > 50 AND Submitted is true)contains: Checking for a value
Works on strings, arrays, and objects. For strings it checks for a substring. For arrays it checks if the value exists in the array.
Expression
contains('Power Automate', 'Auto')Result
trueExpression
contains(variables('ApprovedList'), 'London')Result
true (if London is in the array)You can nest if() functions for multi-branch logic: if(equals(x,'A'), 'Alpha', if(equals(x,'B'), 'Beta', 'Unknown'))
Date and Time functions
Dates in Power Automate are ISO 8601 strings (like 2026-05-17T09:00:00Z). All date functions work with this format.
utcNow: The current timestamp
utcNow() returns the current UTC date and time as an ISO 8601 string. It takes an optional format pattern.
Expression
utcNow()Result
2026-05-17T09:00:00.0000000ZExpression
utcNow('yyyy-MM-dd')Result
2026-05-17formatDateTime: Formatting a date for display
formatDateTime(timestamp, format) converts any ISO 8601 date string to a human-friendly format. The format string uses standard .NET date tokens.
Expression
formatDateTime('2026-05-17T09:30:00Z', 'dd MMM yyyy')Result
17 May 2026Expression
formatDateTime('2026-05-17T09:30:00Z', 'dddd, MMMM d')Result
Sunday, May 17Expression
formatDateTime(triggerBody()?['DueDate'], 'dd/MM/yyyy HH:mm')Result
17/05/2026 09:30Common format tokens: yyyy = 4-digit year, MM = 2-digit month,dd = 2-digit day, HH = 24-hour, hh = 12-hour,mm = minutes, ss = seconds, tt = AM/PM,dddd = full weekday name, MMMM = full month name.
addDays, addHours, addMinutes, addSeconds, addMonths
Add (or subtract using negative numbers) to a timestamp. Essential for calculating due dates, expiry times, and scheduling offsets.
Expression
addDays(utcNow(), 7)Result
2026-05-24T09:00:00.0000000ZToday plus 7 days.
Expression
addDays(utcNow(), -30)Result
2026-04-17T09:00:00.0000000Z30 days ago. Use negative numbers to subtract time.
Expression
addHours(triggerBody()?['StartTime'], 2)Result
Adds 2 hours to the StartTime fieldconvertTimeZone
Converts a UTC timestamp to a local time zone. Important when displaying times to users in specific regions.
Expression
convertTimeZone(utcNow(), 'UTC', 'GMT Standard Time', 'dd MMM yyyy HH:mm')Result
17 May 2026 10:00Use Windows time zone IDs, the same ones as in the Recurrence Builder.
dayOfWeek, dayOfMonth, month, year
Extract parts of a date as integers.
Expression
dayOfWeek('2026-05-17')Result
0 (Sunday: 0=Sun, 1=Mon, 2=Tue...)Expression
dayOfMonth('2026-05-17')Result
17Expression
month('2026-05-17')Result
5Expression
year('2026-05-17')Result
2026Math functions
Math functions operate on numbers. They are straightforward but easy to misuse when dealing with strings that look like numbers. Always convert first.
add, sub, mul, div, mod
Expression
add(10, 5)Result
15Expression
sub(100, 37)Result
63Expression
mul(12, 8)Result
96Expression
div(100, 4)Result
25Expression
mod(17, 5)Result
2 (remainder of 17 ÷ 5)min and max: Smallest and largest value
Expression
min(3, 7, 1, 9, 2)Result
1Expression
max(3, 7, 1, 9, 2)Result
9abs, power, sqrt
Expression
abs(-42)Result
42Expression
power(2, 10)Result
1024Expression
sqrt(144)Result
12div() does integer division when both inputs are integers. If you need a decimal result, cast at least one to a float: div(float(7), float(2)) returns 3.5, not 3.
Collection functions
Collection functions work on arrays and objects. These are extremely powerful when combined with the array actions (see the Array Actions guide), because they let you query and transform arrays directly in expressions.
length: Count items in an array
Expression
length(body('Get_items')?['value'])Result
42 (number of SharePoint items returned)first and last
Get the first or last item from an array.
Expression
first(body('Get_items')?['value'])?['Title']Result
The Title field of the first returned itemtake and skip
take(array, count) returns the first N items. skip(array, count) skips the first N and returns the rest. Combine them to paginate or slice arrays.
Expression
take(variables('NumberList'), 3)Result
[1, 2, 3]Expression
skip(variables('NumberList'), 2)Result
[3, 4, 5] (skips first 2)union and intersection
union() merges arrays removing duplicates. intersection() returns only items present in all arrays.
Expression
union(createArray('A','B'), createArray('B','C'))Result
["A","B","C"]createArray: Building an array inline
Useful when you need to pass a list of values without a prior step.
Expression
createArray('Monday','Wednesday','Friday')Result
["Monday","Wednesday","Friday"]contains: Checking membership
Expression
contains(createArray('Admin','Owner'), variables('UserRole'))Result
true (when UserRole is Admin or Owner)join: Converting an array to a string
Turns an array into a single string with a separator. Great for building comma-separated lists.
Expression
join(variables('TagList'), ', ')Result
urgent, finance, Q2empty: Checking if an array is empty
Expression
empty(body('Get_items')?['value'])Result
true (when no items were returned)Conversion functions
Data from triggers and API responses often comes as strings even when it represents numbers or booleans. Conversion functions cast between types to avoid runtime errors.
int and float: Parsing numbers from strings
Expression
int(triggerBody()?['Quantity'])Result
42 (as a number, not text)Expression
float('3.14')Result
3.14string: Converting values to text
Expression
string(42)Result
'42'Expression
string(true)Result
'true'bool: Parsing boolean values
Expression
bool('true')Result
true (boolean)json: Parsing a JSON string into an object
When an HTTP response body comes back as a string rather than parsed JSON, use json() to convert it so you can access its properties with ?['key'].
Input
"{\"Name\":\"Alice\",\"Score\":95}"Expression
json(body('HTTP'))?['Name']Result
Alicearray: Wrapping a single value in an array
Expression
array('single-value')Result
["single-value"]base64 and decodeBase64
Expression
base64('Hello World')Result
SGVsbG8gV29ybGQ=Expression
decodeBase64('SGVsbG8gV29ybGQ=')Result
Hello WorlduriComponent and uriComponentToBinary
Encode strings for use in URLs. Escapes spaces and special characters.
Expression
uriComponent('hello world & more')Result
hello%20world%20%26%20moreWorkflow context functions
These functions let you access data from the flow's own context: the trigger, previous actions, variables, loop items, and flow metadata. They are the most used category in real flows.
triggerBody() and triggerOutputs()
triggerBody() returns the body of whatever triggered the flow. For a SharePoint trigger this is the list item. For a Forms trigger this is the response. For a manual trigger this is the user-supplied input.
Accessing trigger fields
triggerBody()?['Title'] // SharePoint item Title triggerBody()?['EmailAddress'] // Forms question answer triggerOutputs()?['headers']?['x-ms-trigger-type'] // trigger metadata
body('ActionName') and outputs('ActionName')
Access the output of a specific previous action by its internal name. Use the name as shown in the action title bar (spaces become underscores).
Accessing action outputs
body('Get_item')?['Title']
body('Send_an_HTTP_request_to_SharePoint')?['body']
outputs('Get_item')?['headers']Hover over any output in the dynamic content panel to see the exact expression it will generate. This is the fastest way to learn action output paths.
items('ActionName'): Current loop item
Inside an Apply to Each loop, items('Apply_to_each') refers to the current item in the iteration. Use ?['FieldName'] to access its properties.
items('Apply_to_each')?['Title']
items('Apply_to_each')?['AssignedTo']?['Email']variables('variableName')
Reads the current value of a flow variable. Variables must first be initialised with the Initialize Variable action.
Expression
variables('Counter')Result
5 (current value of Counter variable)parameters('parameterName')
Reads a solution-level parameter. Useful for configuration values that change between environments (dev, test, production).
workflow(): Flow metadata
Returns metadata about the current flow run including its name, ID, run ID, and environment.
Expression
workflow()?['name']Result
My Production FlowExpression
workflow()?['run']?['name']Result
08585903... (the run ID)Common patterns
Null-safe access with coalesce
When a field might be null or missing, wrap it with coalesce() to provide a fallback value. Without this, a null field will crash your expression.
Expression
coalesce(triggerBody()?['Description'], 'No description provided')Result
No description provided (when Description is null)Checking for null explicitly
Expression
if(equals(triggerBody()?['Manager'], null), 'No manager', triggerBody()?['Manager']?['Email'])Result
No manager (when Manager field is empty)Building a filename from fields + date
Expression
concat(triggerBody()?['Title'], '_', formatDateTime(utcNow(), 'yyyyMMdd'), '.pdf')Result
Monthly Report_20260517.pdfCalculating business day offset
Expression
addDays(utcNow(), 5)Result
5 days from now (does not skip weekends. Use Power Automate Desktop for true business day logic)Converting a SharePoint person field to email
triggerBody()?['AssignedTo']?['Email']
body('Get_item')?['Author']?['Email']Reading a choice field value
triggerBody()?['Priority']?['Value'] // Choice field text triggerBody()?['Priority']?['Id'] // Choice field numeric ID
Getting array length for a condition
Expression
if(greater(length(body('Get_items')?['value']), 0), 'Has results', 'Empty')Result
Has results (when the query returned items)Interactive Playground
Type any expression and see the live result instantly. The sample data panel shows the mock triggerBody and variables values you can reference.
Quick examples
Expression
Result
Hello Alice Johnson
Type: string (19 chars)
Build a full name
The trigger has a Title field and an Author with a DisplayName. Combine them to produce: "Project Alpha — submitted by Alice Johnson"
Format the due date
Format the DueDate field as "30 Jun 2026" (dd MMM yyyy).
Pass or fail check
The Score variable is 87. Return "Pass" if it is greater than 80, otherwise return "Fail".
Extract the invoice year
The Reference field is "INV-2026-00042". Extract "2026" using substring (it starts at position 4 and is 4 characters long).
Safe null fallback
The trigger body has no "Manager" field. Use coalesce to return "No manager assigned" when Manager is null.
Count tags
The Tags field is an array. Return how many tags the trigger item has.
Build a filename with today's date
Create a filename like "Project Alpha_20260530.pdf" using the Title field and today's date.
Uppercase the status
Return the Status field in all uppercase letters.
Ready to look things up?
Use the Expression Function Reference to browse all 65 functions with signatures, parameters, examples, and return types, searchable and filterable by category.