Skip to main content

🔍 Bing Ads Integration

🎯 Overview

Microsoft Advertising (formerly Bing Ads) integration providing programmatic access to search advertising campaigns through SOAP-based web services. Supports OAuth 2.0 authentication, campaign management, ad groups, ads, keywords, and comprehensive performance reporting with automatic token refresh.

Provider: Microsoft Advertising (https://ads.microsoft.com)
API Version: v13 (SOAP Web Services)
Integration Type: OAuth 2.0 + SOAP XML Protocol

📖 Documentation Structure

This integration is organized into the following sections:

  • Authentication - OAuth 2.0 flow with automatic token refresh middleware
  • Accounts - Manager accounts and accessible user accounts
  • Campaigns - Campaign operations, metrics, and status management
  • Ad Groups - Ad group management and targeting
  • Ads - Ad operations by type (expanded text, responsive, etc.)
  • Keywords - Keyword management and quality scores
  • Reports - Async report generation and download

✨ Features

  • SOAP Protocol: XML-based web services for Microsoft Advertising API
  • OAuth 2.0 Authentication: Secure authorization with automatic token refresh
  • Token Refresh Middleware: Automatic access token renewal using refresh tokens
  • Manager Accounts (MCC): Support for Microsoft Advertising MCC hierarchy
  • Campaign Management: Full CRUD operations on campaigns, ad groups, ads
  • Keyword Management: Keyword bidding, quality scores, and performance
  • Multiple Ad Types: Support for ExpandedText, Responsive, Dynamic Search, etc.
  • Async Reporting: Generate and download performance reports
  • Aggregation Timeframes: Daily, weekly, monthly, and custom date ranges
  • Editorial Status: Filter by ad approval status

🏗️ Architecture

sequenceDiagram
participant Client as DashClicks App
participant Controller as Bing Controller
participant Middleware as Token Middleware
participant DB as MongoDB
participant SOAP as SOAP Client
participant Bing as Bing Ads API

Client->>Controller: API Request (JWT)
Controller->>Middleware: Check/refresh token
Middleware->>DB: Fetch token document
DB-->>Middleware: Return token + generated_at
alt Token Expired
Middleware->>Bing: POST /oauth2/v2.0/token
Note over Middleware,Bing: Refresh token grant
Bing-->>Middleware: New access token
Middleware->>DB: Update token document
end
Middleware-->>Controller: Valid access token
Controller->>SOAP: Build SOAP XML request
SOAP->>Bing: SOAP Web Service Call
Bing-->>SOAP: SOAP XML Response
SOAP->>SOAP: Parse XML to JSON
SOAP-->>Controller: JSON data
Controller-->>Client: Formatted response

🗄️ MongoDB Collections

📚 Detailed Schema: See Database Collections Documentation

bing.ads.tokens

Purpose: Store OAuth 2.0 tokens with automatic refresh capability

Model: shared/models/bing-ads-token.js

Key Fields:

  • account_id (ObjectId, required, indexed) - DashClicks account reference
  • uid (ObjectId, required, indexed) - DashClicks user reference
  • oauth (Object) - Full OAuth response from Microsoft
    • access_token (String) - Bearer token for API requests
    • refresh_token (String) - Token for automatic renewal
    • expires_in (Number) - Token lifetime in seconds (3600)
    • token_type (String) - "Bearer"
    • scope (String) - OAuth scopes granted
    • generated_at (Number) - Unix timestamp of token generation
  • createdAt (Date) - Document creation timestamp
  • updatedAt (Date) - Last update timestamp

Indexes:

  • { account_id: 1 } - Account-based queries
  • { uid: 1 } - User-based queries

Schema Type: strict: false - Allows flexible OAuth response storage

📁 Directory Structure

Source Code Location:

external/Integrations/BingAds/
├── Controllers/
│ ├── Auth/
│ │ └── AuthController.js # OAuth authentication
│ ├── Accounts/
│ │ └── AccountsController.js # Account operations
│ ├── Campaigns/
│ │ └── CampaignController.js # Campaign management
│ ├── Adgroups/
│ │ └── AdGroupController.js # Ad group operations
│ ├── Ads/
│ │ └── AdsController.js # Ad management
│ ├── Keywords/
│ │ └── KeyWordsController.js # Keyword operations
│ └── Reports/
│ └── ReportsController.js # Report generation
├── Models/
│ ├── token.js # Token CRUD operations
│ ├── Accounts/
│ │ └── AccountsModel.js # Account SOAP logic
│ ├── Campaigns/
│ │ └── CampaignsModel.js # Campaign SOAP logic
│ ├── AdGroups/
│ │ └── AdGroupsModel.js # AdGroup SOAP logic
│ ├── Ads/
│ │ └── AdsModel.js # Ads SOAP logic
│ ├── Keywords/
│ │ └── KeywordsModel.js # Keyword SOAP logic
│ └── Reports/
│ └── ReportsModel.js # Reports SOAP logic
├── Middleware/
│ └── getToken.js # Auto token refresh middleware
├── Routes/
│ └── index.js # Express route definitions
└── SoapClient.js # SOAP XML parser/client

Shared Models Used:

  • shared/models/bing-ads-token.js - OAuth token storage

🔐 Authentication & Configuration

Authentication Method: OAuth 2.0 Authorization Code Flow

Required Environment Variables:

VariableDescriptionRequired
BING_ADS_CLIENT_IDMicrosoft Azure app client ID
BING_CLIENT_SECRETMicrosoft Azure app secret
BING_ADS_REDIRECT_URLOAuth callback URL
BING_ADS_CALLBACK_REDIRECT_URLFrontend redirect after OAuth
BING_ADS_DEVELOPER_TOKENMicrosoft Ads developer token
JWT_SECRETJWT state token signing secret

OAuth Scopes: openid offline_access https://ads.microsoft.com/ads.manage

Developer Token:

🚀 Quick Start

1. Configure Environment Variables

BING_ADS_CLIENT_ID=your_client_id
BING_CLIENT_SECRET=your_client_secret
BING_ADS_REDIRECT_URL=https://api.dashclicks.com/v1/integrations/bing/ads/auth/callback
BING_ADS_CALLBACK_REDIRECT_URL=https://app.dashclicks.com/integrations
BING_ADS_DEVELOPER_TOKEN=your_production_token
JWT_SECRET=your_jwt_secret

2. Initiate OAuth Flow

GET /v1/integrations/bing/ads/auth/login?forward_url=https://app.dashclicks.com/integrations
Authorization: Bearer {jwt_token}

3. List Manager Accounts

GET /v1/integrations/bing/ads/accounts/managers
Authorization: Bearer {jwt_token}

4. List User Accounts

GET /v1/integrations/bing/ads/accounts/users?customerID=12345678
Authorization: Bearer {jwt_token}

5. List Campaigns

GET /v1/integrations/bing/ads/campaigns?customerAccountID=98765432&customerID=12345678&campaignType=Search
Authorization: Bearer {jwt_token}

6. Get Campaign Metrics

GET /v1/integrations/bing/ads/campaigns/metrics?customerAccountID=98765432&aggregation=Monthly&predefinedTime=Last30Days
Authorization: Bearer {jwt_token}

📊 API Endpoints Summary

MethodEndpointDescription
GET/auth/loginInitiate OAuth 2.0 flow
GET/auth/callbackHandle OAuth callback
DELETE/auth/:idDelete OAuth token
GET/accounts/managersList manager accounts (MCC)
GET/accounts/usersList accessible user accounts
GET/campaignsList campaigns
GET/campaigns/showShow single campaign
GET/campaigns/metricsGet campaign performance metrics
GET/adgroupsList ad groups
GET/adgroups/showShow single ad group
GET/adgroups/metricsGet ad group metrics
GET/adsList ads
GET/ads/showShow single ad
GET/ads/metricsGet ad metrics
GET/keywordsList keywords
GET/keywords/showShow single keyword
GET/keywords/metricsGet keyword metrics
GET/reports/downloadDownload generated report

🔄 Token Auto-Refresh Flow

Middleware: Middleware/getToken.js

Process:

  1. Every request passes through token middleware
  2. Middleware fetches token from MongoDB
  3. Checks if token expired (compares generated_at + 3600 seconds)
  4. If expired:
    • Calls Microsoft token endpoint with refresh token
    • Updates MongoDB with new access token and generated_at
    • Sets new token on req.access_token
  5. If valid, passes token to controller
  6. If no token exists, returns error: "oauth token not found. Please redirect to login"

Token Lifetime: 3600 seconds (1 hour)

🎯 Campaign Types

Bing Ads supports multiple campaign types:

  • Search - Text ads on Bing search results
  • Shopping - Product listing ads
  • DynamicSearchAds - Auto-generated search ads

Filter by Type: Use comma-separated values: campaignType=Search,Shopping

📈 Aggregation Timeframes

Supported Values:

  • Today, Yesterday
  • LastSevenDays, Last14Days, Last30Days
  • ThisWeek, LastWeek, LastFourWeeks
  • ThisMonth, LastMonth
  • LastThreeMonths, LastSixMonths
  • ThisYear, LastYear
  • Weekly, Monthly, Summary

Default: Last30Days

🌍 Timezone Options

Default: EasternTimeUSCanada

Full List: See Microsoft Ads ReportTimeZone Reference

🎨 Ad Types

Supported Ad Types:

  • Text - Basic text ads (legacy)
  • ExpandedText - Expanded text ads (default)
  • ResponsiveSearch - Responsive search ads
  • ResponsiveAd - Display responsive ads
  • Image - Image ads
  • Product - Shopping product ads
  • AppInstall - Mobile app install ads
  • DynamicSearch - Dynamic search ads

Reference: Microsoft Ads AdType Documentation

🚨 Error Handling

Common Error Scenarios:

ErrorCauseSolution
oauth token not foundNo token in databaseRedirect to OAuth login
Token expiredAccess token > 1 hour oldAuto-refreshed by middleware
customerAccountID is requiredMissing required parameterProvide account ID
Please provide customerIDMissing customer IDProvide customer ID
SOAP faultMicrosoft API errorCheck SOAP response for details

📊 Required Parameters

Account-Level Operations

customerAccountID (Required for most operations):

  • The identifier of the account that owns the entities
  • Must be provided as query parameter
  • Example: customerAccountID=98765432

customerID (Optional but recommended):

  • The identifier of the customer that owns the account
  • Used when managing accounts of other customers
  • Example: customerID=12345678

Reference: Microsoft Ads Request Headers

⚠️ Important Notes

  • 🔐 Production App Required: Sandbox accounts only work with desktop apps
  • 🔄 Auto Token Refresh: Middleware automatically renews expired tokens
  • 📦 SOAP Protocol: Uses XML-based SOAP web services (not REST)
  • ⏱️ Token Lifetime: Access tokens expire after 1 hour (3600 seconds)
  • 🔑 Developer Token: Required for all API requests
  • 🎯 Customer Account ID: Required for most operations
  • 📊 Multiple API Calls: Listing operations may make multiple SOAP calls
  • 🌐 Timezone: All timestamps use account/report timezone setting
  • 📈 Aggregation: Reports support flexible time aggregation
  • 🔍 Editorial Status: Ads/keywords can be filtered by approval status

🎨 SOAP Client Architecture

Custom SOAP Client (SoapClient.js):

  • Built with Axios for HTTP requests
  • Uses fast-xml-parser for XML-to-JSON conversion
  • Handles SOAP envelope construction
  • Parses SOAP fault responses
  • Returns JSON for easy consumption

SOAP Request Format:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:AuthenticationToken>...</h:AuthenticationToken>
<h:DeveloperToken>...</h:DeveloperToken>
<h:CustomerAccountId>...</h:CustomerAccountId>
</s:Header>
<s:Body>
<!-- SOAP operation specific body -->
</s:Body>
</s:Envelope>

🏢 Manager Account Hierarchy

MCC (Microsoft Advertising Center) Support:

  • List manager accounts with linked customer accounts
  • Access campaigns across multiple managed accounts
  • Filter operations by specific customer IDs
  • Support for agency/reseller account structures

🔗 Submodules

💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:30 AM