Sooner or later, every Power Automate flow I build gets a chunk of JSON back from somewhere: an HTTP call, the SharePoint REST API, Microsoft Graph or a Power Apps form. Most of the time, I only need a few fields from it, as a clean array I can pass to the next step.
In this tutorial, I’ll show you two ways to do that: the classic Parse JSON plus Apply to each loop, and a faster single action with Select. I’ll also cover the expressions for converting between JSON text and arrays, and the mistakes that make the array come back empty.
Quick answer: Add Parse JSON to turn the JSON into fields, then add the Select action. Set From to the array inside your JSON, such as body('Parse_JSON')?['Customers'], and map only the keys you need with item()?['Name']. Select returns a new array with just those fields, no loop needed.
The goal
Here’s the sample JSON I’ll use. It has a Customers array with five customers:
{
"Customers": [
{ "Name": "Richard", "CustomerCode": "58244", "CustomerLocation": "France", "ContactNumber": 7894561230 },
{ "Name": "Noah", "CustomerCode": "14789", "CustomerLocation": "Mexico", "ContactNumber": 8456789620 },
{ "Name": "Jordan", "CustomerCode": "21456", "CustomerLocation": "Germany", "ContactNumber": 7584963210 },
{ "Name": "Rufus", "CustomerCode": "25896", "CustomerLocation": "Canada", "ContactNumber": 8457962130 },
{ "Name": "Rachel", "CustomerCode": "19835", "CustomerLocation": "USA", "ContactNumber": 8302165479 }
]
}
I don’t need the contact numbers. I want an array with only Name, CustomerCode and CustomerLocation for each customer:
[
{ "Name": "Richard", "CustomerCode": "58244", "CustomerLocation": "France" },
{ "Name": "Noah", "CustomerCode": "14789", "CustomerLocation": "Mexico" },
{ "Name": "Jordan", "CustomerCode": "21456", "CustomerLocation": "Germany" },
{ "Name": "Rufus", "CustomerCode": "25896", "CustomerLocation": "Canada" },
{ "Name": "Rachel", "CustomerCode": "19835", "CustomerLocation": "USA" }
]
If your JSON is a single object rather than an array, see how to parse a JSON object to an array first.
Method 1: Parse JSON and Apply to each
Use this method when you need to do something with each item while you build the array, such as checking a condition or calculating a value.
Step 1: Create the flow and the array variable
In Power Automate, select Create > Instant cloud flow, choose Manually trigger a flow and select Create. In a real flow, the trigger could be an HTTP request, a SharePoint item or a schedule. The steps after it are the same.
Select + > Add an action, add Initialize variable, and set Name to CustomerDetails, Type to Array, and leave Value empty.

Initialize variable has to be at the top level of the flow, not inside a loop, condition or scope. That’s why it comes first.
For more on array variables, see Power Automate array variable examples.
Step 2: Add the JSON
Add a Compose action and paste the sample JSON into Inputs. In a real flow, you’d use the body of your HTTP action or trigger here instead.

Step 3: Parse the JSON
Add Parse JSON. For Content, select the lightning bolt icon and choose Outputs from Compose. Then select Use sample payload to generate schema, paste the same JSON, and select Done.

The schema tells Power Automate the shape of your data, so the fields (Name, CustomerCode and so on) show up as dynamic content in the next steps.
Step 4: Loop and append
Add Apply to each and select Customers from Parse JSON as its input. Inside the loop, add Append to array variable, pick CustomerDetails, and build the object in Value. Type the keys, and insert each value as an expression with the fx icon:

If you type the whole value yourself, put quotes around each @{...}, otherwise text values produce invalid JSON:
{
"Name": "@{items('Apply_to_each')?['Name']}",
"CustomerCode": "@{items('Apply_to_each')?['CustomerCode']}",
"CustomerLocation": "@{items('Apply_to_each')?['CustomerLocation']}"
}
Use the name of your own loop in items(). It’s Apply_to_each by default, but it could be For_each or anything you renamed it to, with spaces replaced by underscores.
I explain items(), the current item and the index in more detail in how to get the current item in Apply to each.
Step 5: Check the output
After the loop, add a Compose with the CustomerDetails variable as its input. Save the flow and select Test > Manually > Test. The last Compose shows the clean array, with five items and three fields each:

Method 2: The Select action (faster, no loop)
You don’t need a loop just to pick fields. The Select data operation reshapes every item of an array in one step, and it’s much faster on large arrays.
After Parse JSON, add Select. Set From to Customers from Parse JSON. In Map, add one row per key: Name, CustomerCode and CustomerLocation, each with the matching field. Behind the scenes, the values are:
item()?['Name']
item()?['CustomerCode']
item()?['CustomerLocation']
You can also switch the Map to text mode and enter the whole object at once, as in my screenshot. Text mode is mainly useful when you want a flat array of single values, for example only the names: map item()?['Name'] on its own.

Select returns the same array as Method 1, without a variable, a loop or an append. In my flows, it’s the first thing I try.
The Select output also plugs straight into Create HTML table, which is how I create an HTML table from an array for emails.
Select or Apply to each?
| You need to | Use |
|---|---|
| Pick some fields from each item | Select |
| Keep only some items | Filter array, then Select |
| Send an email or create an item for each one | Apply to each |
| Calculate or transform a value per item | Select with an expression, or Apply to each for complex logic |
| Handle a large array quickly | Select |
Select can change the shape of each item but not how many items there are. Filter array is the opposite: it removes items but keeps their shape. Together, they cover most cases.
Filter the array first
To keep only the customers in the USA, add Filter array before Select. Set From to Customers and the condition to item()?['CustomerLocation'] is equal to USA. Then use the Filter array output as the From of Select.
Text comparisons in Filter array are case-sensitive, so “usa” won’t match “USA”. Wrap both sides in toLower() if the case can vary. There are more examples in these Filter array examples.
To check two or more fields at once, see how to filter an array by multiple conditions.
Convert between JSON text and arrays
Searches for “array to JSON” and “JSON to array” usually come down to one of these expressions:
| Expression | What it does | Example result |
|---|---|---|
json('["a","b"]') | Turns JSON text into a real array or object | ["a","b"] |
string(variables('CustomerDetails')) | Turns an array into JSON text, for example for an HTTP body or a text column | [{"Name":"Richard",...}] |
createArray('a', 'b') | Builds an array from two or more values of the same type | ["a","b"] |
array('hello') | Wraps a single value in an array | ["hello"] |
union(createArray(1,2,3), createArray(1,2,10)) | Combines arrays and removes duplicates | [1,2,3,10] |
length(body('Select')) | Counts the items | 5 |
If a value arrives as text, for example from a Power Apps parameter, use json() on it before Parse JSON or Select. Otherwise, the flow treats the whole thing as one long string.
To build an array from a comma-separated text instead, use the split() function, and to combine two arrays, see how to merge arrays in Power Automate.
Why the array comes back empty or broken
- The schema doesn’t match the real data. If a field is sometimes missing or null, Parse JSON fails. Remove optional fields from the schema’s
requiredlist, and allow nulls with"type": ["string", "null"]. - The From field gets an object instead of an array. The JSON is wrapped in
{ "Customers": [...] }, so passbody('Parse_JSON')?['Customers'], not the whole body. - The schema came from a partial sample. Fields missing from the sample don’t appear as dynamic content. Generate the schema again from a complete example.
- Copied expressions don’t work. Curly quotes from web pages and documents break expressions. Use straight quotes:
items('Apply_to_each')?['Name']. - Values are in the wrong order or missing. Apply to each runs one item at a time by default. If you turned on concurrency, appending to a variable becomes unpredictable, so turn it off or use Select.
Key expressions
| Expression | What it returns |
|---|---|
body('Parse_JSON')?['Customers'] | The Customers array from Parse JSON |
items('Apply_to_each')?['Name'] | The Name of the current item in a loop |
item()?['Name'] | The Name of the current item in Select or Filter array |
outputs('Compose') | The output of a Compose action |
variables('CustomerDetails') | The array variable |
first(body('Select')) | The first item of the array |
These Power Automate array tutorials go well with this one:
Frequently Asked Questions
How do I convert JSON to an array in Power Automate?
If the JSON is text, use json() to turn it into an array or object. Then use Parse JSON and Select to pull out the array and the fields you need.
How do I convert an array to a JSON string in Power Automate?
Use string(), for example string(body(‘Select’)). That’s useful when an HTTP body or a SharePoint text column needs the JSON as text.
Can I create an array from JSON without Apply to each?
Yes. The Select action maps every item in one step, which is faster and simpler. Microsoft explains it with the other data operations in Power Automate.
How do I read a nested value in a JSON array?
Chain the property names with ?[], for example item()?[‘Address’]?[‘City’], and make sure the Parse JSON schema includes the nested object.

I have worked with Microsoft technologies for more than 18 years, including SharePoint, Microsoft 365 and the Power Platform (Power Apps, Power Automate and Power BI), at companies like HP, TCS and KPIT. I started EnjoySharePoint in 2011 to share the solutions I build in real projects with readers in the United States, Canada, the United Kingdom, Australia, New Zealand and beyond. Microsoft has recognized this work with the Microsoft MVP award 13 times since 2014.