Tutorials/Power Automate/Power Automate: Unlock Hidden Step Data with actions(), outputs(), and body()
Power Automateintermediate

Power Automate: Unlock Hidden Step Data with actions(), outputs(), and body()

Learn how to retrieve inputs, outputs, status codes, and response bodies from previous steps using these three essential workflow functions.

NA
Narmer Abader
@narmer · Published June 3, 2026

Dynamic content is convenient, but it only shows a fraction of what each action can provide. Status codes, headers, and even some input fields are hidden from that menu. The actions(), outputs(), and body() functions let you reach into any previous step and pull out any property from its complete JSON response. This article walks through each function using a practical SharePoint example, so you can confidently grab the data you really need.

Scenario: New Employee Onboarding List

We'll use a SharePoint list named NewEmployeeOnboarding with the columns below. This list tracks requests for equipment and account setup.

EmployeeName (text)Department (choice)StartDate (date)EquipmentOrdered (Yes/No)Status (choice)
Alice TranEngineering2026-07-01YesApproved
Bob MartinezMarketing2026-07-15NoPending Approval
Carol SinghHuman Resources2026-06-20YesCompleted
David ChenEngineering2026-08-01NoSubmitted
Emily JohanssonFinance2026-07-22YesApproved

The flow we'll build will query this list and then explore the data that is returned.

Building the Exploration Flow

Create an Instant cloud flow and add a trigger of your choice (e.g., manually trigger a flow). Then add a SharePoint – Get Items action and configure it to point to your site and the NewEmployeeOnboarding list. No filter is needed for now.

After that, insert a Compose action. We will use multiple Compose actions to inspect the output of the Get Items action with different functions.

The actions() Function: The Complete Picture

The actions() function returns the full inputs and outputs of any previous step as a JSON object. This is the rawest view – it includes every parameter you passed in and the entire response.

Write the following expression in the Compose action:

textGet all inputs and outputs of Get Items
actions('Get_items')

When you run the flow, the output will be a large JSON object showing the action's schema, inputs (like site address, list name, query parameters), and outputs (including body, status code, and headers).

Digging into a Specific Input

To extract just one property from this object, use the ? syntax to navigate through the JSON. For example, to get the site address that was used as input, write:

textGet the site address input
actions('Get_items')?['inputs']?['parameters']?['dataset']

The result will be the SharePoint site URL, such as https://yourtenant.sharepoint.com/sites/Onboarding.

The outputs() Function: Status, Headers, and Body

The outputs() function returns a subset of the action's response: the statusCode, headers, and body. It strips away the input details and the top-level action metadata.

Replace the Compose expression with:

textGet outputs of Get Items
outputs('Get_items')

The JSON you see will have three top-level properties:

  • statusCode – typically 200 for a successful request.
  • headers – response headers (content-type, date, etc.).
  • body – the actual data from SharePoint (the items).

If you only need the status code, use:

textGet only the status code
outputs('Get_items')?['statusCode']

This is useful for error handling: you can check whether a step succeeded (200) or returned a different code.

The body() Function: Just the Data

The body() function is shorthand for outputs('name')?['body']. It returns the response body of the action, which typically contains the meaningful data.

textGet the body of Get Items
body('Get_items')

The body for a Get Items action will contain a value array with the list items, along with metadata like odata.nextLink if there are more items. For most work, you want the value array:

textGet the array of items
body('Get_items')?['value']

This expression returns each SharePoint item as an object, which you can then iterate with an Apply to each or use in other actions.

When to Use Which Function

  • actions() – When you need the original input parameters (e.g., the query that was sent) or the complete action definition. Use it rarely because the output is large and usually contains more than you need.
  • outputs() – When you need the full HTTP response, including status code and headers. It's indispensable for error handling or if an API returns information in the headers.
  • body() – When you simply want the data from the action. In many cases, the dynamic content picker already exposes body properties, but if a property is missing (e.g., nested JSON), body() is the reliable fallback.

Common Mistakes and Troubleshooting

1. Incorrect Action Name

The action name must match exactly, including colons, underscores, and spaces. The easiest way to avoid typos is to use the dynamic content picker: start typing actions( and then select the action from the list that appears.

2. Using outputs() When You Already Have the Body

If the property you need is already offered in the dynamic content menu, don't waste an expression. Use outputs() only for status codes and headers that are hidden.

3. Forgetting the ? Property Accessor

To navigate into JSON, always use ?['propertyName']. Using ['propertyName'] directly after the function will still work, but staying consistent with the ? syntax avoids errors when properties might be null.

4. Not Handling Pagination

Get Items may not return all items if the list is large. The body includes an odata.nextLink property when there are more results. Use a pagination pattern (loop over the next link) to retrieve the full dataset.

Performance and Security Considerations

  • Large lists: Retrieving many items in one Get Items call can slow down your flow. Always filter as much as possible with OData queries. actions() and outputs() still include the entire response, which could be heavy if you log them unnecessarily.
  • Delegation: The functions themselves are evaluated at runtime and don't affect delegation. However, the underlying action (e.g., Get Items) should use filtered queries for efficiency.
  • Security: The output of any action can contain sensitive data. Avoid writing these functions in test Compose steps that you forget to remove, and be cautious if you store the results in logs or emails.

A Practical Example: Checking an Action's Status

Suppose you have an action that sometimes fails. You can use outputs() to capture the status code and branch your flow:

textCondition for success
equals(outputs('Send_an_HTTP_request')?['statusCode'], '200')

If the HTTP request returns a 201 created instead of 200, this condition would be false. You can then trigger a fallback or notification.

Final Recommendations

  • Start with body() if you're just after the data. It's the most concise and covers 90% of use cases.
  • Move to outputs() when you need to check if something succeeded or to read headers.
  • Reserve actions() for debugging or when you need to verify what inputs were sent.
  • Always test your expressions with a Compose action first to see the raw JSON before using them in logic.

These three functions give you a backstage pass to every step in your flow. Master them, and you'll never be limited by the dynamic content picker again.

References