Bing API Receiving an unexpected Report Download URL RRS feed

  • Question

  • I am having an issue that is coming up every couple days when downloading reports from the Bing API. I am getting a URL that is  like this:

    and it is resulting in a 405 error - HTTP/1.1 405 The resource doesn't support specified Http Verb.

    when my report zip files are downloaded successfully they have a different URL type looking similar to the following:

    What is the differences in the two different URLS that bing is providing me and why does the 1st one always error out?

    Tuesday, March 12, 2019 5:21 PM

All replies

  • Do you have a recent repro with tracking ID, report request ID, and timestamp for the first URL? 

    Thank you,


    Thursday, March 14, 2019 2:20 PM
  • Also can you please share more details about your programming language and environment, and the process you use to download the file?

    Thank you,


    Thursday, March 14, 2019 10:09 PM
  • Hi Eric,

    Programing Language = Java/ Talend ETL Tool

    Process: we make a Soap call by following the process on(1) and make the following soap Call (5) and then from the XML returned we iterate through each section of the XML to get Status and Download URL. Next we use each download URL to download each report to a zip file to process in a later step. The issue occurs when we get a different URL than we are expecting that gives us the error below.(6)  I have provided a Tracking ID for both URL(4) examples, but can not find a Request_ID or timestamp in the body of that response, but that is as expected based on the documentation(1)  

    Summary: I am using an ETL Tool called Talend, and I am following the the details on the following page (1). Most days we only get download URL's with the following base URL(2). Our Job was running successful for the first few months, but now every couple days we are now getting a download URL with the following base URL(3), and this gives us a  in a 405 error - HTTP/1.1 405 The resource doesn't support specified Http Verb. error.  We have multiple accounts that we pull for and this problem URL has occurred on all of them at some point in time. From my knowlege we can not change that URL that is provided from Bing so I do not know why they are providing 2 diffrent types of URLS, and why the second one does not download a report. It has "Blob" in the base URL but to my knowledge we are not doing anything with Bing blobs. Let me know if you need more info.




    4. Failure URL tracking ID <h:TrackingId xmlns:h=““>e9ad74de-89b2-41f0-8910-0cd462a4a0ac</h:TrackingId>

             - Passing URL Tracking ID - <h:TrackingId            xmlns:h=““>746bb7bb-d545-4d10-8cad-961611a45a06</h:TrackingId>

    5. "<s:Envelope xmlns:i=\"\" xmlns:s=\"\">
      <s:Header xmlns=\"\">
        <Action mustUnderstand=\"1\">PollGenerateReport</Action>
        <AuthenticationToken i:nil=\"false\">"+context.bing_access_token+"</AuthenticationToken>
        <CustomerAccountId i:nil=\"false\">"+context.curr_acct_id+"</CustomerAccountId>
        <CustomerId i:nil=\"false\">"+context.bing_client_id+"</CustomerId>
        <DeveloperToken i:nil=\"false\">"+context.bing_developer_token+"</DeveloperToken>
        <PollGenerateReportRequest xmlns=\"\">
          <ReportRequestId i:nil=\"false\">"+context.report_id+"</ReportRequestId>

    6.405 error - HTTP/1.1 405 The resource doesn't support specified Http Verb. error.

    Monday, March 18, 2019 7:03 PM
  • Just a quick follow up question, if you decode the 'blob' URL i.e., use '&' instead of '&amp;' does that help?



    Monday, March 18, 2019 7:24 PM
  • IDK exactly, because currently we just use the URL as provided by Bing, and do not do any transformation on the URL because we assume they should give us a valid URL. It would take a little bit or Dev work for us to manipulate that URL then try and download the report. I think the URL is only valid for a short period of time otherwise I would try and do that with some of our past failure logs.

    Do you suggest us trying to manipulate that URL? In the documentation they do not talk about providing different URLS so I am unsure why they give us this completely different format sometimes.  Possibly they do that when the report size is too large, or the report is not complete? It is weird because when our Job Fails we often try and reprocess later and it usually results in us getting an XML with all the correct URL formats, which makes me think possibly that report is not ready for consumption, but you would think they would put something different in status if that was the case.

    Monday, March 18, 2019 8:31 PM
  • I confirmed this is a valid and expected URL. In an XML document e.g., SOAP response the ampersand is encoded in that way. In this case it is in the context of a URL. 

    Here is a related stack overflow thread, although I am not familiar with how to handle it via Talend.

    I hope this helps,


    Tuesday, March 19, 2019 2:34 PM
  • Hey Eric,

    Sorry it has been a while on this thread. I was able to get the decoding piece of this down. (I think) I am now receiving some data stream from the download URLs that are passed to us. Thank you for your help with that!

    I am running into a new set of issues however, because it seems that the data from the blob storage URL is being returned as a strange data type. Some research suggests it might be an binary octet stream. Is my only option to convert that to a regular data type to process my Bing ads data? Or is there some header that I can include in my rest call to that blob download URL to have the data return in a different format? I feel like I am missing something obvious here. We are running against V12 of the Bing ads API and it used to just return .csv files from the download URL. Should we be using a different API endpoint or something?

    This is the URL we are using:

    Is there something I can alter in that to get back an "easier-to-work-with" data type?


    Tuesday, May 7, 2019 1:34 AM
  • There aren't any other request options via the Reporting service. Again I'm not familiar with your steps via Talend but if you provide exact repro steps I'm happy to follow along and try to repro it here. Then I might be in a better position to offer a workaround for your environment. 

    Best regards,


    Tuesday, May 7, 2019 3:08 AM
  • Hey Eric,

    Here is the flow of what we are doing. Don't want to provide the actual access or refresh tokens here so I am afraid that part of the example won't be fully reproducible without your own set of tokens. First first thing we do is make an authorization request to Bing's OAuth endpoint:

    Endpoint -

    HTTP Method - POST

    HTTP Headers - Content-Type : application/x-www-form-urlencoded

    HTTP Body - "client_id=" + <bing_client_id> + "&scope=bingads.manage&grant_type=refresh_token&" + <bing_refresh_token>

    Where the <> text represents our specific variables for our account. From that request we receive the access token back and store that. Next we make a call to the CustomerManagementService endpoint to retrieve all of our Bing ads accounts.

    Endpoint -

    HTTP Method - POST

    HTTP Headers - AuthenticationToken: <Bing_access_token>

    DeveloperToken: <Bing_Developer_Token>

    Content-Type: text/xml;charset=utf-8

    SOAPAction: GetAccountsInfo

    HTTP Body - 

    <s:Envelope xmlns:i=\"\" xmlns:s=\"\">
     <s:Header xmlns=\"\">
       <Action mustUnderstand=\"1\">GetAccountsInfo</Action>
       <AuthenticationToken i:nil=\"false\">"+<bing_access_token>+"</AuthenticationToken>
       <DeveloperToken i:nil=\"false\">"+<bing_developer_token>+"</DeveloperToken>
       <GetAccountsInfoRequest xmlns=\"\">
         <CustomerId i:nil=\"false\">"+<customer_id>+"</CustomerId>

    This request returns an xml file of all of the relevant Bing acocunts. We then loop through that file to extract the account IDs associated with active accounts. Once we have that list, we then use it to make requests against the ReportingService endpoint.

    Endpoint -

    HTTP Method - POST

    HTTP Headers - CustomerAccountId : <Account_ID>

    CustomerId : <Bing_client_id>

    DeveloperToken : <Bing_Developer_Token>

    Content-type : text/xml;charset=utf-8

    SOAPAction : SubmitGenerateReport

    HTTP Body: Note that here we are requesting a keyword performance report with the format CSV

    <s:Envelope xmlns:i=\"\" xmlns:s=\"\">
      <s:Header xmlns=\"\">
        <Action mustUnderstand=\"1\">SubmitGenerateReport</Action>
        <AuthenticationToken i:nil=\"false\">"+<bing_access_token>+"</AuthenticationToken>
        <CustomerAccountId i:nil=\"false\">"+<curr_acct_id>+"</CustomerAccountId>
        <CustomerId i:nil=\"false\">"+<customer_id>+"</CustomerId>
        <DeveloperToken i:nil=\"false\">"+<bing_developer_token>+"</DeveloperToken>
        <SubmitGenerateReportRequest xmlns=\"\">
          <ReportRequest i:nil=\"false\" i:type=\"KeywordPerformanceReportRequest\">
            <ExcludeColumnHeaders i:nil=\"false\">0</ExcludeColumnHeaders>
            <ExcludeReportFooter i:nil=\"false\">1</ExcludeReportFooter>
            <ExcludeReportHeader i:nil=\"false\">1</ExcludeReportHeader>
            <Format i:nil=\"false\">Csv</Format>
            <Language i:nil=\"false\">English</Language>
            <ReportName i:nil=\"false\">KeywordPerformanceReport</ReportName>
            <ReturnOnlyCompleteData i:nil=\"false\">0</ReturnOnlyCompleteData>
            <Columns i:nil=\"false\">
            <Scope i:nil=\"false\">
              <AccountIds i:nil=\"false\" xmlns:a1=\"\">
            <Sort i:nil=\"false\">
            <Time i:nil=\"false\">
              <PredefinedTime i:nil=\"false\">LastSevenDays</PredefinedTime>
              <ReportTimeZone i:nil=\"false\">MountainTimeUSCanada</ReportTimeZone>

    From this request, we gather the reporting request id for the specific client report and then begin the process of polling the Reporting Service to see if the report is ready for download. Note that we are expecting to receive a link to a .csv file per the reporting definition in the last call. To accomplish that polling we make the following requests spaced at approximately a 5 second interval until the report status returned is returned as successful.

    Endpoint -

    HTTP Method - POST

    HTTP Headers - AuthenticationToken : <Bing_Access_Token>

    CustomerAccountID : <Account_id>

    CustomerId : <Bing_Client_Id>

    DeveloperToken : <Bing_Developer_Token>

    Content-type : text/xml;charset=utf-8

    SOAPAction : PollGenerateReport

    HTTP Body: 

    <s:Envelope xmlns:i=\"\" xmlns:s=\"\">
      <s:Header xmlns=\"\">
        <Action mustUnderstand=\"1\">PollGenerateReport</Action>
        <AuthenticationToken i:nil=\"false\">"+<bing_access_token>+"</AuthenticationToken>
        <CustomerAccountId i:nil=\"false\">"+<curr_acct_id>+"</CustomerAccountId>
        <CustomerId i:nil=\"false\">"+<bing_client_id>+"</CustomerId>
        <DeveloperToken i:nil=\"false\">"+<bing_developer_token>+"</DeveloperToken>
        <PollGenerateReportRequest xmlns=\"\">
          <ReportRequestId i:nil=\"false\">"+<report_id>+"</ReportRequestId>

    From each request we receive an XML file containing specific field as defined by Bing. When the report status is successful and there is data available for the time range defined in the reporting request, the file returned contains a field called report download URL. This URL is then used to download the requested report for the specific account_id that was used in the report generate request. Historically, this download URL link was an endpoint which downloaded a zipped folder containing a .csv of the request data. We would then take that folder, unzip it, parse the .csv and load the data to our reporting server. That database loading process is not relevant to the thread as it is specific to us.

    However, the download URL in that is returned by the polling request has recently altered it's behavior, returning the encoded Azure blob storage location instead of the url to download the zip file. I feel like this is an unexpected API action since it is not documented in the Bing API documentation.

    Some notes on the API behavior that you may find useful. The blob storage location is not returned consistently by the pollGenerateReport service. Most calls it will return the blob storage location, but it does occasionally return the zip file location. It is not account specific. The blob URLs seem to be returned randomly with some accounts receiving a blob URL for one request but not a subsequent request. Hopefully that is useful to you all internally.

    But regardless of whether it is unexpected, we need to deal with it. So, to deal with this, we now conditionally distribute the download URLs through two separate flows. If the download URL is returned in the old format, we grab the zip file. If the download URL is the blob format, we then use the following code to properly alter the download URL value returned to a link that works per you earlier advice:<download>, "UTF-8")

    Where <download> is the value returned from the reportingPollRequest and the output of the decoded URL is saved in another variable. We then use the decoded URL in another request to access the data. That is as follows:

    Endpoint - <Decoded_URL>

    HTTP Method - GET

    HTTP Headers - AuthenticationToken : <Bing_Access_Token>

    CustomerAccountId : <Account_id>

    CustomerId : <Bing_client_id>

    DeveloperToken : <Bing_Developer_Token>

    Content-type : application/octet-stream

    I am honestly not sure that any of those headers are required to access the data. What we receive back from that call is some large amount of data in a format that I think is an octet-stream based on Azure documentation. I haven't been able to confirm that. An additional note is that the URL decoding works about 25% of the time. It appears that the other 75% of the time, the signature field in the download URL does not decode properly. I have not fully been able to figure out why that occurs yet. It is probably some Java specific nonsense.

    I hope this helps. I think it is about as reproducible of a flow as I can give you, but if there is anything else that I can provide to help you help us, please let me know!

    Could there be something with the speed at which we are polling the "PollGenerateReport" service that is causing us to get a download URL that is different from what we would expect? Also, is there some Bing ads API documentation that I am missing that shows how to deal with this different flow?


    Tuesday, May 7, 2019 5:51 PM
  • Same problem with KeywordPerformanceReport in Csv format.  Stable code that has been working for a very long time suddenly started giving these ...blob... URLs. If you navigate to that URL, it shows a ResourceNotFound error code. 

    What is not clear is which resource can't be found since the polling seems to be working properly (and works for other report types). I have tried stripping down the report fields list to minimal set, but the error continues.

    Just adding a 'me too' to this error. Details available if needed...

    Tuesday, May 7, 2019 6:42 PM
  • In general for all clients please note "&amp;" is the encoded string that you would see if inspecting the SOAP XML response directly. If your client does not decode it automatically to "&" then you would need to add that step e.g., URLDecode.decode. I confirmed with the Bing Ads Java SDK e.g., this Reporting example, the URL is automatically decoded and the file is downloaded without issue. 

    Regarding the specific example above, instead of setting http header and content type, please try to download files from the Azure blob as follows.

    URL address = new URL("");
    InputStream inStream = address.openStream();
    Path target = new File("C:\\MyPath\\").toPath();
    Files.copy(inStream, target);    

    I hope this helps!


    Wednesday, May 8, 2019 1:21 PM
  • Confirmed -- replacing the &amp; with & in the url and downloading from that url works as desired.  

    What threw us off was that the url was different from previous and other queries. It looked like some kind of error rather than just an alternative delivery url.

    Wednesday, May 8, 2019 8:20 PM
  • That's great feedback, and thanks for confirming!
    Wednesday, May 8, 2019 8:36 PM