Hi felipy
I would suggest try revisiting the initial setup as you might be missing some steps
Here’s a step-by-step guide to building a server-to-server (daemon / machine-to-machine) integration for pulling Microsoft Advertising reports via the Reporting API v13 (REST) — including sandbox setup, authentication, and report retrieval.
Step 1: Register Your Application https://free.blessedness.top/en-us/advertising/guides/authentication-oauth-register?view=bingads-13
You must register your app in Microsoft Entra ID (Azure AD) to obtain credentials.
1.Go to Azure Portal
2.Navigate to Microsoft Entra ID → App registrations
3.Click: New registration
Name: e.g., MyAdReportingDaemon
Redirect URI: Required for initial authorization (can be http://localhost)
4.After registration, note:
Application (client) ID
Directory (tenant) ID
Step 2: Configure API Permissions
- In your app registration, go to API permissions
- Click Add a permission → APIs my organization uses
- Search for Microsoft Advertising API
- Add delegated permissions:
msads.manage offline_access
- Click Grant admin consent (if available)
Step 3: Create a Client Secret
- Go to Certificates & secrets
- Click New client secret
- Save the generated secret securely — you’ll need it to exchange tokens
Step 4: Request Sandbox Access
If testing in sandbox:
- Contact Microsoft Advertising Support
- Request sandbox enablement for your DeveloperToken
- Ask for sandbox-specific CustomerId (CID) and AccountId (AID)
Step 5: Perform Authorization Code Flow
This is required to obtain a refresh token for your daemon.
1.Redirect user to:
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?
client_id={client_id}
&response_type=code
&redirect_uri={redirect_uri}
&scope=https://ads.microsoft.com/msads.manage offline_access
2.After user signs in, capture the code from the redirect
3.Exchange code for tokens:
POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={client_id}
client_secret={client_secret}
grant_type=authorization_code
code={authorization_code}
redirect_uri={redirect_uri}
- Save:
access_token (valid for 1 hour)
refresh_token (long-lived)
Step 6: Refresh Access Token on Schedule
Use the refresh token to get new access tokens without user interaction:
POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
client_id={client_id}
client_secret={client_secret}
grant_type=refresh_token
refresh_token={refresh_token}
scope=https://ads.microsoft.com/msads.manage offline_access
Step 7: Submit Report Request
Use the Reporting API v13 endpoint:
POST
https://reporting.api.bingads.microsoft.com/Reporting/v13/GenerateReport/Submit
Headers:
Authorization: Bearer {access_token}
DeveloperToken: {your_developer_token}
CustomerId: {CID}
CustomerAccountId: {AID}
Content-Type: application/json
Body:
{
"ReportRequest": {
"Type": "AdPerformanceReportRequest",
"ReportName": "Ad Perf (7d)",
"Format": "Csv",
"FormatVersion": "2.0",
"ReturnOnlyCompleteData": false,
"Aggregation": "Daily",
"Columns": [
"TimePeriod", "CampaignId", "CampaignName", "AdId", "Title", "Impressions", "Clicks", "Spend"
],
"Scope": {
"AccountIds": [12345678]
},
"Time": {
"CustomDateRangeStart": { "Year": 2025, "Month": 10, "Day": 6 },
"CustomDateRangeEnd": { "Year": 2025, "Month": 10, "Day": 12 },
"ReportTimeZone": "SaoPaulo"
}
}
}
Step 8: Poll for Report Completion
Use the GetReportStatus endpoint with the returned ReportRequestId. Once ready, download the report using DownloadReport.
Final Notes
- Client credentials flow is NOT supported — you must use delegated user tokens.
- Sandbox and production credentials are NOT interchangeable
- Always decode your token at jwt.ms to verify
aud and scp claims
Issue and troubleshooting: What Error 105 means?
{
"Code": 105,
"Message": "Authentication failed. The provided credentials are invalid or the account is inactive",
"ErrorCode": "InvalidCredentials"
}
This error occurs when:
The access token is invalid or missing required claims
The DeveloperToken is not enabled for the environment (sandbox vs production)
The CustomerId (CID) or AccountId (AID) is incorrect or inactive
You're using the wrong authentication flow (e.g., client_credentials instead of authorization_code)
✅ Fix Checklist
1.Use the Correct OAuth Flow
Only the authorization_code flow is supported for Reporting API v13
You must use a user-delegated token with scopes:
https://ads.microsoft.com/msads.manage
offline_access
2.Verify Access Token Claims
Decode your token at jwt.ms
Confirm:
aud = https://ads.microsoft.com
scp includes msads.manage
Token is not expired
3.Use the Right DeveloperToken
Must be approved for sandbox if you're using sandbox endpoints
Production tokens will not work in sandbox
Contact Microsoft Advertising Support to confirm
4.Use Sandbox-Specific CID and AID
Production CustomerId and AccountId will not work in sandbox
Retrieve sandbox IDs using:
GetCustomersInfo
GetAccountsInfo
Ensure the account is active
5.Correct Headers in API Call
Authorization: Bearer {access_token}
DeveloperToken: {sandbox_or_production_token}
CustomerId: {sandbox_or_production_CID}
CustomerAccountId: {sandbox_or_production_AID}
Content-Type: application/json
6.Check Account Status
Use GetAccountsInfo to confirm the account is active
Inactive or disabled accounts will trigger Error 105
🧪 Common Pitfalls
Using client_credentials flow (not supported)
Mixing production and sandbox credentials
Missing msads.manage scope
Using expired or malformed access tokens
I hope this helps, if you’ve confirmed all of the above and still get Error 105, submit a ticket request to support for further assistance
Kind regards,
John | Microsoft Advertising Support Specialist | 1-800-518-5689