I'm trying to use the Microsoft Bing Ads' Reporting API to gather ad performance data such as clicks, spend, etc. programmatically. Below, I describe the steps taken.
The issue is that after following the steps I don't get the expected SOAP Response. Instead I get an empty body with HTTP 202 Accepted
Status.
I'm using Postman to test the service and my end goal is to use httr
to do the same in R.
Authentication
I have followed their OAuth 2.0 Authentication Flow in that, I have:
- Registered my Application (using the Developer Account)
- Requested user consent (through the Ad account)
- Generated the Access Token and Refresh Token
Every time I hit the API, I generate a new Access Token using the Refresh Token, since the Access Token is short lived.
Making the Request
The documentation describes a Reporting Service Operation which follows an asynchronous approach. First we need to use SubmitGenerateReport
to make a request to the Reporting Service. This returns a ResponseRequestId
which we can then use to repeatedly poll the service using PollGenerateReport
till we get the requested report in response.
SubmitGenerateReport
SubmitGenerateReport
has to be in SOAP XML Format as stated here. Following is the document I generated for my use case looking at the provided example in the documentation.
<s:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header xmlns="https://bingads.microsoft.com/Reporting/v13">
<Action mustUnderstand="1">SubmitGenerateReport</Action>
<AuthenticationToken i:nil="false">**AUTHENTICATION_TOKEN_VALUE**</AuthenticationToken>
<CustomerAccountId i:nil="false">**CUSTOMER_ACCOUNT_ID_VALUE**</CustomerAccountId>
<CustomerId i:nil="false">**CUSTOMER_ID_VALUE**</CustomerId>
<DeveloperToken i:nil="false">**DEVELOPER_TOKEN_VALUE**</DeveloperToken>
</s:Header>
<s:Body>
<SubmitGenerateReportRequest xmlns="https://bingads.microsoft.com/Reporting/v13">
<ReportRequest i:nil="false" i:type="-- derived type specified here with the appropriate prefix --">
<ExcludeColumnHeaders i:nil="false">false</ExcludeColumnHeaders>
<ExcludeReportFooter i:nil="false">false</ExcludeReportFooter>
<ExcludeReportHeader i:nil="false">false</ExcludeReportHeader>
<Format i:nil="false">Csv</Format>
<FormatVersion i:nil="false">2.0</FormatVersion>
<ReportName i:nil="false">COA Bing Ad Spend</ReportName>
<ReturnOnlyCompleteData i:nil="false">false</ReturnOnlyCompleteData>
<!--These fields are applicable if the derived type attribute is set to AccountPerformanceReportRequest-->
<Aggregation>Summary</Aggregation>
<Columns i:nil="false">
<AccountPerformanceReportColumn>Spend</AccountPerformanceReportColumn>
</Columns>
<Filter i:nil="false">
<AccountStatus i:nil="false"></AccountStatus>
<AdDistribution i:nil="false"></AdDistribution>
<DeviceOS i:nil="false"></DeviceOS>
<DeviceType i:nil="false"></DeviceType>
</Filter>
<Scope i:nil="false">
<AccountIds i:nil="false" xmlns:a1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a1:long>**ACCOUNT_ID_VALUE**</a1:long>
</AccountIds>
</Scope>
<Time i:nil="false">
<CustomDateRangeEnd i:nil="false">
<Day></Day>
<Month></Month>
<Year></Year>
</CustomDateRangeEnd>
<CustomDateRangeStart i:nil="false">
<Day></Day>
<Month></Month>
<Year></Year>
</CustomDateRangeStart>
<PredefinedTime i:nil="false">ThisWeek</PredefinedTime>
<ReportTimeZone i:nil="false"></ReportTimeZone>
</Time>
</s:Body>
</s:Envelope>
Having generated this XML, I am trying to hit their Reporting Service Endopoint (Production) by making use of Postman.
Postman Configuration
I'm following this article on how to make SOAP Requests using Postman.
- I'm making a POST Request to:
https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/V13/ReportingService.svc
with the above SOAP XML as the Body - Have set the Body encoding to
Raw
- Have added a
Content-Type = text/xml
header as recommended in the article (setting this asapplication/xml
, returns505 Internal Server Error
)
As per the Documentation, I'm supposed to get a SOAP Response as:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header xmlns="https://bingads.microsoft.com/Reporting/v13">
<TrackingId d3p1:nil="false" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance">ValueHere</TrackingId>
</s:Header>
<s:Body>
<SubmitGenerateReportResponse xmlns="https://bingads.microsoft.com/Reporting/v13">
<ReportRequestId d4p1:nil="false" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">ValueHere</ReportRequestId>
</SubmitGenerateReportResponse>
</s:Body>
</s:Envelope>
The ResponseRequestId
I would then use to poll the service for the actual report.
However, when I POST this, I get an HTTP 202 Accepted
Response and an empty body. The response according to Postman means:
The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when the processing actually takes place.
I've redone the Authentication steps multiple times and am generally confident that there's no issue there. This leaves me with no direction as to how I can go about debugging this. When I try making the POST after removing, say the Authentication Token or the Customer Account Id, the request is still accepted and returns 202.
I've never worked with SOAP APIs before, so it's possible I'm not following the proper process. Any help or pointers would be highly appreciated.
Thanks!
I could solve this error, after searching by many pages I find that to do a request in postman you must aggregate the next header. header