Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.

Reply
TP-101
Helper I
Helper I

M Query Post REST API, return format not JSON with Expression.Error

I'm attempting a POST to a REST API which should return data in JSON.  The POST appears to succeed however, receiving an Expression.Error trying to convert the response to binary.  Can this query be modified to return the data as JSON and not convert to binary?  I'm assuming it's something with line 31.  Thank you in advance.

 

Expression.ErrorExpression.Error

 

The entire M query

Screenshot 2023-10-26 at 7.27.24 AM.png

 

18 REPLIES 18
lbendlin
Super User
Super User

Can you post a sample result of Web.Contents ?

Is this what you are looking for?  The variables form a complete https URL to the endpoint.  Screenshot 1.  Then, we're posting some JSON data to the endpoint.  Screenshot 2.

Screenshot 2023-10-30 at 3.58.46 PM.png

Screenshot 2023-10-31 at 12.52.45 PM.png

 

Then it should return JSON data.  By the look of the Expression.Error, it appears to be data I'm POST'ing that it's trying to first convert to binary.  I'm wondering if the "Content=Text.FromBinary" is the culpret.  I dont believe there is a "Text.FromJSON" equivalent.

no, I am looking for a sample response text with the \u000a  etc.

I think the problem is not with the response.  The \u000a seems to be coming from the data section which is formatted JSON we are trying to POST to the REST API.  The API should return something totally different.

 

TP-101
Helper I
Helper I

Thank you @lbendlin .  I changed line 31 to include a content-type however, still seeing the Expression.Error.  I'm not sure what is tring to convert to binary since the response should be json.  Any idea?

 

GetJsonQuery = Json.Document(Web.Contents("https://" & #"Tenant" & #"GetMetric", [Headers=[Authorization=AccessTokenHeader, #"Content-Type"="application/json"], Content=Text.FromBinary(Json.FromValue(data))]))

Try adding an accept directive.

Added the accept and still observing the same Expression.Error.

 GetJsonQuery = Json.Document(Web.Contents("https://" & #"Tenant" & #"GetMetric", [Headers=[Authorization=AccessTokenHeader, #"accept"="application/json"], Content=Text.FromBinary(Json.FromValue(data))]))

Try this.  

 GetJsonQuery = Json.Document(Web.Contents("https://" & Tenant & GetMetric, [Headers=[Authorization=AccessTokenHeader, Accept="application/json"], Content=Text.FromBinary(Json.FromValue(data))]))

 

You will also need to read up on RelativePath and Query.

Changing it to that shows a Bad Request (400) error instead.

please show the current code.

let
data = "{
        ""object_type"": ""device"",
        ""metric_category"": ""ssl_server"",
        ""metric_specs"": [
                {
                ""name"": ""connected""
                }
            ],
        ""object_ids"": ""[8589939089]"",
        ""cycle"": ""auto"",
    }",


 // Concatenates the Consumer Key & Consumer Secret and converts to base64
  authKey = "Basic " & Binary.ToText(Text.ToBinary(#"API ID" & ":" & #"API Secret"),0),
  url = "https://" & #"Tenant" & #"Token URL",
 // Uses the oauth2/token method to obtain a bearer token
 GetJson = Web.Contents(url,
     [
         Headers = [#"Authorization"=authKey,
                    #"Content-Type"="application/x-www-form-urlencoded"],
         Content = Text.ToBinary("grant_type=client_credentials") 
     ]
 ),
 FormatAsJson = Json.Document(GetJson),
 // Gets token from the Json response
 AccessToken = FormatAsJson[access_token],
 AccessTokenHeader = "Bearer " & AccessToken,
 // Uses the POST method using the bearer token from the previous POST oauth2/token method
 // GetJsonQuery = Json.Document(Web.Contents("https://" & #"Tenant" & #"GetMetric", [Headers=[Authorization=AccessTokenHeader, #"accept"="application/json"], Content=Text.FromBinary(Json.FromValue(data))]))
 GetJsonQuery = Json.Document(Web.Contents("https://" & Tenant & GetMetric, [Headers=[Authorization="AccessTokenHeader", Accept="application/json"]]))
in
    GetJsonQuery

GetJsonQuery = Json.Document(Web.Contents("https://" & Tenant & GetMetric, [Headers=[Authorization=AccessTokenHeader, Accept="application/json"]]))

That one is showing a 405 error.  I think that might be due to it trying to GET vs. POST without the Content piece.

Screenshot 2023-10-30 at 3.58.46 PM.png

yes, didn't notice you had removed that.

 

 GetJsonQuery = Json.Document(Web.Contents("https://" & Tenant & GetMetric, [Headers=[Authorization="AccessTokenHeader", Accept="application/json"], Content=Text.FromBinary(Json.FromValue(data))]))

That one put's us back to square 1.  Is there something in that line that is trying to convert the returned JSON to binary?

Screenshot 2023-10-30 at 4.14.49 PM.png

Sorry, typo again. Tiny screen. Try this one

 

 

WebResult = Web.Contents("https://" & Tenant & GetMetric, [Headers=[Authorization=AccessTokenHeader, Accept="application/json"], Content=Text.FromBinary(Json.FromValue(data))]),
GetJsonQuery = Json.Document(Text.Replace(Text.Replace(WebResult,"\u000a",""),"\""",""""))

 

Ya, still getting the Expression.Error as before.

lbendlin
Super User
Super User

The response is JSON, just a bit messed up .  \u000a is a line feed.  \"  is a double quote etc.  You can make that usable with a couple of replaces.

 

Anyway, in your headers you can specify which content type you accept. Try setting that to application/JSON.

Helpful resources

Announcements
July PBI25 Carousel

Power BI Monthly Update - July 2025

Check out the July 2025 Power BI update to learn about new features.

Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 community update carousel

Fabric Community Update - June 2025

Find out what's new and trending in the Fabric community.