“‘Parse JSON’ gives me a lot of useless dynamic contents, is there another way to parse the response from an HTTP request in Power Automate?”
When using HTTP requests in Power Automate, it’s recommended to use the ‘Parse JSON’ action to process the response. You take the HTTP response, use it as a sample payload in the ‘Parse JSON’, and the action will parse it for you. But if you do that, it’ll give you much more dynamic contents than you’d expect. It’ll parse everything in the HTTP response and add a ton of dynamic content, sometimes even doubling it. So, is there an easier way to get the data you need without using ‘Parse JSON’?
Access the data using expressions
When you look at the response from the HTTP request, you can see it’s a valid JSON. Let’s take an example, a response from an HTTP call that will return list of users in a SharePoint group.
_api/Web/SiteGroups/GetByID([ItemID])/users
The body of the example response will look as above. There’s the main element “d” (1), subelement “results” (2) with an array of users, and the actual user data (3). You can recognize that “results” is an array by the square brackets [ ] enclosing the user information (3). Since you’re interested in the user data, you want to loop through all the “results” and get the desired value for each user.
Expression to access the array
The first step is to get only the “results’ array from the object, and then use it in an ‘Apply to each’ action to process all items (users). Start from the default ‘body’ output from the HTTP action, it’ll look like: outputs(‘HTTP request action name’)?[‘body’], e.g. as below.
outputs('Send_an_HTTP_request_to_SharePoint')?['body']
This dynamic content contains all the data as shown on the image above. But as was already mentioned, you need to go deeper, you want to go in the “d” and “results” elements.
outputs('Send_an_HTTP_request_to_SharePoint')?['body']['d']['results']
That’s the expression to use as the input of the ‘Apply to each’ action that will loop through all the results.
Expression to access the value
Now it’s time to select the value you want to get from that array. When processing an array inside ‘Apply to each’, you can access the currently processed item with item() expression. To continue with the example from above, each item() will contain only the part 3.
You’ll define what value from the item() you want by adding its key to the item() expression in the format below:
item()?['Key']
e.g. to get user Email address
item()?['Email']
And that’s the expression you can use to access the desired value from an HTTP request response, in this example the user email.
Summary
I’d say that’s the key takeaway from this article is to think about any input of ‘Parse JSON’ as an object. If it needs parsing, it’s an object and you can do all the object operations with it.
‘Parse JSON’ will just parse it for you and make the use more convenient, but it’s not the only way. You can skip that action and do the parsing by yourself, take only the values you really need and leave the rest. And it doesn’t apply only to HTTP requests, you can extract data from any JSON.
Also, the HTTP request in this article was taken just as an example. You can follow the same process with minor variations for any HTTP request and its outcome. It’s just another object after all.
Really useful article, I find the Parse JSON Step to be less than ideal for complex schemas because you lose the structure of the JSON, for example ID could appear 10 times in a big response, the parse step doesn’t show the path like “Product > Sales > ID” for example, you just get ID with no lineage. I prefer this method of deconstructing the JSON like this.
Hello Matt,
I agree, I don’t like the Parse JSON exactly for the same reason, it creates a terrible mess among the dynamic contents. I don’t even remember the last time I used it since it’s so easy to get the right value right away…
Awesome, thanks!
I mean thanks to the author of the post Tom.
Hi Tom – I got the cheat sheet but there’s nothing in it on GET an item. I have some fairly complex processes and the multiple date and person fields don’t come through in a simple Get Item/Get Items action. I got the cheat sheet hoping it would contain information on how to get an item and that maybe that way I could circumvent the limitation on complex fields that Get Item has.
Apart from single parameters, would an HTTP action help me with that?
Thanks, Christine
Hello Christine,
you can use an HTTP request in the format ‘_api/web/lists/getByTitle(‘listName’)/items’ to get the items with all the columns, but I don’t think it’s a “user friendly” approach, especially for people picker columns as it’ll return only user Id on the specific site, not the AD connected object like the ‘Get item/Get items’ action.
In general I think that the ‘Get items/Get item’ actions are much better than the HTTP alternatives, even if you have to use multiple ‘Get items’ over different views to get all the columns and merge them together into a single array (a topic Paul wrote a nice article about: https://www.tachytelic.net/2022/07/power-automate-merge-array/)
Awesome. That saved my time
This is amazing! One question if you have ideas…I have a template that references itself (lookup column). Is there any way you know to make that reference the new list?
I am doing this and it is returning a null value. I believe this is because the value i seek is inside another array in the top level array. if thishappens, it all seems to fall apart. After a month of digging, using this call “_api/lists/getbytitle(‘DTR Tasks’)/RoleAssignments?$expand=Member/Users,RolDefinitionBindings” i get all results i am looking for. however, the information seems to be in an array down further so i tried this “outputs(‘Send_an_HTTP_request_to_SharePoint’)?[‘body’]?[‘d’]?[‘results’]?[‘Users’]?[‘results’]” to no avail.
this would allow everyone (if it works) to get all users and permissions on all objects in sharepoint.
That is really nice, but can I use this approach to get the user id? when I use _api/web/SiteUsers/GetByEmail(‘useremail’) I don’t get the [‘results’] only [‘d’]
Hello Everart,
if you get only [‘d’] then skip the [‘results’] part and take only the [‘d’] using the same approach.
Thanks for this, it was very helpful. I got fed up trying to parse JSON from _api/web/SiteGroups/GetById(x)/Users repeatedly failing.
At the For Each step I’m using the following:
body(‘Send_an_HTTP_request_to_SharePoint’)?[‘d’][‘results’]
The current Flow builder (3 July 24) has the body object as an available input from a previous step, not “output”. It caught me out for a few minutes but everything else worked great as is!
Simplified even further…. You don’t need to use Compose if you’re appending the entries into an array, just use fn “items(‘Apply_to_each’)?[‘Email’]” for the value.
This also works if extracting users to add individually to field columns. However that fn needs to be bracketed with ‘{ “Claims”: ‘ and ‘}’ in the append array value field. Users do need to be active for this to work though!
Thanks again – this blog post cracked an aspect of Flow that had been annoying me for a while, and couldn’t find a clear explanation elsewhere.