Edit

Dynamic Search Ads Code Example

This example uses the Campaign Management API to setup a Dynamic Search Ads (DSA) campaign.

Note

You can no longer add, update, or retrieve campaigns that only support dynamic search ads. The campaign type of your existing campaigns has been updated from "DynamicSearchAds" to "Search". The ad groups are now considered "dynamic" ad groups, but there are no structural changes i.e., they contain the same auto targets and dynamic search ads as before.

Tip

Use the language selector in the documentation header to choose C#, Java, Php, or Python.

To get access and refresh tokens for your Microsoft Advertising user and make your first service call using the Bing Ads API, see the Quick Start guide. You'll want to review the Get Started guide and walkthroughs for your preferred language e.g., C#, Java, Php, and Python.

Supporting files for C#, Java, Php, and Python examples are available at GitHub. You can clone each repository or repurpose snippets as needed.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds.V13.AdInsight;
using Microsoft.BingAds;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to setup Dynamic Search Ads (DSA) in a Search campaign with the Campaign Management service.
    /// </summary>
    public class DynamicSearchAds : ExampleBase
    {
        public const string DOMAIN_NAME = "contoso.com";
        public const string LANGUAGE = "EN";
        
        public override string Description
        {
            get { return "Dynamic Search Ads (DSA) Campaigns | Campaign Management V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                AdInsightExampleHelper AdInsightExampleHelper = new AdInsightExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                AdInsightExampleHelper.AdInsightService = new ServiceClient<IAdInsightService>(
                    authorizationData: authorizationData,
                    environment: environment);

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

                // To get started with dynamic search ads, first you'll need to add a new Search campaign 
                // Include a DynamicSearchAdsSetting that specifies the target website domain and language.

                var campaigns = new[]{
                    new Campaign
                    {
                        BudgetType = Microsoft.BingAds.V13.CampaignManagement.BudgetLimitType.DailyBudgetStandard,
                        DailyBudget = 50,
                        CampaignType = CampaignType.Search,
                        Languages = new string[] { "All" },
                        Name = "Everyone's Shoes " + DateTime.UtcNow,
                        TimeZone = "PacificTimeUSCanadaTijuana",
                        Settings = new [] {
                            new DynamicSearchAdsSetting
                            {
                                DomainName = "contoso.com",
                                Language = "English"
                            }
                        },
                    },
                };

                OutputStatusMessage("-----\nAddCampaigns:");
                AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaigns: campaigns);
                long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray();
                Microsoft.BingAds.V13.CampaignManagement.BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputStatusMessage("CampaignIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);

                // Create a new ad group with type set to "SearchDynamic"

                var adGroups = new[] {
                    new AdGroup
                    {
                        AdGroupType = "SearchDynamic",
                        Name = "Everyone's Red Shoe Sale",
                        StartDate = null,
                        EndDate = new Date {
                            Month = 12,
                            Day = 31,
                            Year = DateTime.UtcNow.Year + 1
                        },
                        CpcBid = new Bid { Amount = 0.09 },
                    }
                };

                OutputStatusMessage("-----\nAddAdGroups:");
                AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync(
                    campaignId: (long)campaignIds[0],
                    adGroups: adGroups,
                    returnInheritedBidStrategyTypes: false);
                long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray();
                Microsoft.BingAds.V13.CampaignManagement.BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();
                OutputStatusMessage("AdGroupIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors);

                // You can add one or more Webpage criteria to each ad group that helps determine 
                // whether or not to serve dynamic search ads.

                var adGroupCriterions = new List<AdGroupCriterion>();

                var adGroupWebpagePositivePageContent = new BiddableAdGroupCriterion
                {
                    AdGroupId = (long)adGroupIds[0],
                    CriterionBid = new FixedBid
                    {
                        Amount = 0.50
                    },
                    Criterion = new Webpage
                    {
                        Parameter = new WebpageParameter
                        {
                            Conditions = new[]
                            {
                                new WebpageCondition
                                {
                                    Argument = "flowers",
                                    Operand = WebpageConditionOperand.PageContent,
                                }
                            },
                            CriterionName = "Ad Group Webpage Positive Page Content Criterion"
                        },
                    },
                };
                adGroupCriterions.Add(adGroupWebpagePositivePageContent);

                // To discover the categories that you can use for Webpage criteria (positive or negative), 
                // use the GetDomainCategories operation with the Ad Insight service.

                OutputStatusMessage("-----\nGetDomainCategories:");
                var getDomainCategoriesResponse = await AdInsightExampleHelper.GetDomainCategoriesAsync(
                    categoryName: null,
                    domainName: DOMAIN_NAME, 
                    language: LANGUAGE);
                var categories = getDomainCategoriesResponse.Categories;
                OutputStatusMessage("Categories:");
                AdInsightExampleHelper.OutputArrayOfDomainCategory(categories);

                // If any categories are available let's use one as a condition.

                if (categories.Count > 0)
                {
                    var adGroupWebpagePositiveCategory = new BiddableAdGroupCriterion
                    {
                        AdGroupId = (long)adGroupIds[0],
                        CriterionBid = new FixedBid
                        {
                            Amount = 0.50
                        },
                        Criterion = new Webpage
                        {
                            Parameter = new WebpageParameter
                            {
                                Conditions = new[]
                                {
                                    new WebpageCondition
                                    {
                                        Argument = categories[0].CategoryName,
                                        Operand = WebpageConditionOperand.Category,
                                    }
                                },
                                CriterionName = "Ad Group Webpage Positive Category Criterion"
                            },
                        }
                    };
                    adGroupCriterions.Add(adGroupWebpagePositiveCategory);
                }

                // If you want to exclude certain portions of your website, you can add negative Webpage 
                // criterion at the campaign and ad group level. 

                var adGroupWebpageNegativeUrl = new NegativeAdGroupCriterion
                {
                    AdGroupId = (long)adGroupIds[0],
                    Criterion = new Webpage
                    {
                        Parameter = new WebpageParameter
                        {
                            // You can choose whether you want the criterion argument to match partial URLs, 
                            // page content, page title, or categories that Bing thinks applies to your website.
                            Conditions = new[]
                            {
                                new WebpageCondition
                                {
                                    Argument = DOMAIN_NAME,
                                    Operand = WebpageConditionOperand.Url,
                                }
                            },
                            // If you do not specify any name, then it will be set to a concatenated list of conditions. 
                            CriterionName = null
                        }
                    },
                };
                adGroupCriterions.Add(adGroupWebpageNegativeUrl);

                OutputStatusMessage("-----\nAddAdGroupCriterions:");
                CampaignManagementExampleHelper.OutputArrayOfAdGroupCriterion(adGroupCriterions);
                AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = await CampaignManagementExampleHelper.AddAdGroupCriterionsAsync(
                    adGroupCriterions: adGroupCriterions, 
                    criterionType: AdGroupCriterionType.Webpage);
                long?[] adGroupCriterionIds = addAdGroupCriterionsResponse.AdGroupCriterionIds.ToArray();
                OutputStatusMessage("AdGroupCriterionIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adGroupCriterionIds);
                BatchErrorCollection[] adGroupCriterionErrors =
                    addAdGroupCriterionsResponse.NestedPartialErrors.ToArray();
                OutputStatusMessage("NestedPartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(adGroupCriterionErrors);

                // The negative Webpage criterion at the campaign level applies to all ad groups 
                // within the campaign; however, if you define ad group level negative Webpage criterion, 
                // the campaign criterion is ignored for that ad group.

                var campaignCriterions = new List<CampaignCriterion>();
                var campaignWebpageNegative = new NegativeCampaignCriterion
                {
                    CampaignId = (long)campaignIds[0],
                    Criterion = new Webpage
                    {
                        Parameter = new WebpageParameter
                        {
                            Conditions = new[]
                            {
                                new WebpageCondition
                                {
                                    Argument = DOMAIN_NAME + "\\seattle",
                                    Operand = WebpageConditionOperand.Url,
                                }
                            },
                            CriterionName = "Campaign Negative Webpage Url Criterion"
                        }
                    }
                };
                campaignCriterions.Add(campaignWebpageNegative);

                OutputStatusMessage("-----\nAddCampaignCriterions:");
                CampaignManagementExampleHelper.OutputArrayOfCampaignCriterion(campaignCriterions);
                AddCampaignCriterionsResponse addCampaignCriterionsResponse = await CampaignManagementExampleHelper.AddCampaignCriterionsAsync(
                        campaignCriterions: campaignCriterions, 
                        criterionType: CampaignCriterionType.Webpage);
                long?[] campaignCriterionIds = addCampaignCriterionsResponse.CampaignCriterionIds.ToArray();
                OutputStatusMessage("CampaignCriterionIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(campaignCriterionIds);
                BatchErrorCollection[] campaignCriterionErrors =
                    addCampaignCriterionsResponse.NestedPartialErrors.ToArray();
                OutputStatusMessage("NestedPartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchErrorCollection(campaignCriterionErrors);

                // Finally you must add at least one DynamicSearchAd into the ad group. The ad title and display URL 
                // are generated automatically based on the website domain and language that you want to target.

                var ads = new Ad[] {
                    new DynamicSearchAd
                    {
                        Text = "Find New Customers & Increase Sales! Start Advertising on Contoso Today.",
                        Path1 = "seattle",
                        Path2 = "shoe sale",
                        // You cannot set FinalUrls for dynamic search ads. 
                        // The Final URL will be a dynamically selected landing page.
                        // The final URL is distinct from the path that customers will see and click on in your ad.
                        FinalUrls = null,                        
                    },
                };
                
                OutputStatusMessage("-----\nAddAds:");
                AddAdsResponse addAdsResponse = await CampaignManagementExampleHelper.AddAdsAsync(
                    adGroupId: (long)adGroupIds[0],
                    ads: ads);
                long?[] adIds = addAdsResponse.AdIds.ToArray();
                Microsoft.BingAds.V13.CampaignManagement.BatchError[] adErrors = addAdsResponse.PartialErrors.ToArray();
                OutputStatusMessage("AdIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(adIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(adErrors);
                
                // Delete the campaign and everything it contains e.g., ad groups and ads.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaignIds: new[] { (long)campaignIds[0] });
                OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));
            }
            // Catch authentication exceptions
            catch (OAuthTokenRequestException ex)
            {
                OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
            }
            // Catch Campaign Management service exceptions
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
                OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
        }        
    }
}
package com.microsoft.bingads.examples.v13;

import com.microsoft.bingads.*;
import com.microsoft.bingads.v13.adinsight.ArrayOfDomainCategory;
import com.microsoft.bingads.v13.adinsight.GetDomainCategoriesResponse;
import com.microsoft.bingads.v13.campaignmanagement.*;
import com.microsoft.bingads.v13.campaignmanagement.ArrayOfBatchError;
import com.microsoft.bingads.v13.campaignmanagement.ArrayOflong;
import com.microsoft.bingads.v13.campaignmanagement.BudgetLimitType;
import com.microsoft.bingads.v13.adinsight.*;

import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;

public class DynamicSearchAds extends ExampleBase {
    
    public final static String DOMAIN_NAME = "contoso.com";
    public final static String LANGUAGE = "EN";
    
    public static void main(String[] args) {

        try
        {      
            authorizationData = getAuthorizationData(); 
        
            AdInsightExampleHelper.AdInsightService = new ServiceClient<IAdInsightService>(
                            authorizationData, 
                            API_ENVIRONMENT,
                            IAdInsightService.class);    

            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                            authorizationData, 
                            API_ENVIRONMENT,
                            ICampaignManagementService.class);
        
            // To get started with dynamic search ads, first you'll need to add a new Search campaign 
            // Include a DynamicSearchAdsSetting that specifies the target website domain and language.

            ArrayOfCampaign campaigns = new ArrayOfCampaign();
            Campaign campaign = new Campaign();
            campaign.setBudgetType(BudgetLimitType.DAILY_BUDGET_STANDARD);
            List<CampaignType> campaignTypes = new ArrayList<CampaignType>();
            campaignTypes.add(CampaignType.SEARCH);
            campaign.setCampaignType(campaignTypes);
            campaign.setDailyBudget(50.00);
            com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring languages = 
                    new com.microsoft.bingads.v13.campaignmanagement.ArrayOfstring();
            languages.getStrings().add("All");
            campaign.setLanguages(languages);
            campaign.setName("Everyone's Shoes " + System.currentTimeMillis());
            DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
            dynamicSearchAdsSetting.setDomainName("contoso.com");
            dynamicSearchAdsSetting.setLanguage("English");
            dynamicSearchAdsSetting.setSource(DynamicSearchAdsSource.ALL);
            ArrayOfSetting arrayOfSetting = new ArrayOfSetting();
            arrayOfSetting.getSettings().add(dynamicSearchAdsSetting);
            campaign.setSettings(arrayOfSetting);
            campaign.setTimeZone("PacificTimeUSCanadaTijuana");
            campaigns.getCampaigns().add(campaign);

            outputStatusMessage("-----\nAddCampaigns:");
            AddCampaignsResponse addCampaignsResponse = CampaignManagementExampleHelper.addCampaigns(
                    authorizationData.getAccountId(), 
                    campaigns);            
            ArrayOfNullableOflong campaignIds = addCampaignsResponse.getCampaignIds();
            ArrayOfBatchError campaignErrors = addCampaignsResponse.getPartialErrors();
            outputStatusMessage("CampaignIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(campaignIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(campaignErrors);

            // Create a new ad group with type set to "SearchDynamic"
            
            ArrayOfAdGroup adGroups = new ArrayOfAdGroup();
            AdGroup adGroup = new AdGroup();
            adGroup.setAdGroupType("SearchDynamic");
            adGroup.setName("Everyone's Red Shoe Sale");
            adGroup.setStartDate(null);
            Calendar calendar = Calendar.getInstance();
            adGroup.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
            adGroup.getEndDate().setDay(31);
            adGroup.getEndDate().setMonth(12);
            adGroup.getEndDate().setYear(calendar.get(Calendar.YEAR));
            Bid CpcBid = new Bid();
            CpcBid.setAmount(0.09);
            adGroup.setCpcBid(CpcBid);
            adGroups.getAdGroups().add(adGroup);
            
            outputStatusMessage("-----\nAddAdGroups:");
            AddAdGroupsResponse addAdGroupsResponse = CampaignManagementExampleHelper.addAdGroups(
                    campaignIds.getLongs().get(0), 
                    adGroups, 
                    false);
            ArrayOfNullableOflong adGroupIds = addAdGroupsResponse.getAdGroupIds();
            ArrayOfBatchError adGroupErrors = addAdGroupsResponse.getPartialErrors();
            outputStatusMessage("CampaignIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(adGroupIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(adGroupErrors); 

            // You can add one or more Webpage criteria to each ad group that helps determine 
            // whether or not to serve dynamic search ads.
            
            ArrayOfAdGroupCriterion adGroupCriterions = new ArrayOfAdGroupCriterion();	        
            BiddableAdGroupCriterion adGroupWebpagePositivePageContent = getExampleAdGroupWebpagePositivePageContent(adGroupIds.getLongs().get(0));	        
            adGroupCriterions.getAdGroupCriterions().add(adGroupWebpagePositivePageContent);

            // To discover the categories that you can use for Webpage criterion (positive or negative), 
            // use the GetDomainCategories operation with the Ad Insight service.
            
            outputStatusMessage("-----\nGetDomainCategories:");
            GetDomainCategoriesResponse getDomainCategoriesResponse = AdInsightExampleHelper.getDomainCategories(
                    null, 
                    DOMAIN_NAME, 
                    LANGUAGE);
            ArrayOfDomainCategory categories = getDomainCategoriesResponse.getCategories();
            outputStatusMessage("Categories:");
            AdInsightExampleHelper.outputArrayOfDomainCategory(categories);

            // If any categories are available let's use one as a condition.
            if(categories.getDomainCategories().size() > 0)
            {
                BiddableAdGroupCriterion adGroupWebpagePositiveCategory = getExampleAdGroupWebpagePositiveCategory(adGroupIds.getLongs().get(0), categories);
                adGroupCriterions.getAdGroupCriterions().add(adGroupWebpagePositiveCategory);
            }
            
            // If you want to exclude certain portions of your web site, you can add negative Webpage 
            // criterion at the campaign and ad group level.
            NegativeAdGroupCriterion adGroupWebpageNegativeUrl = getExampleAdGroupWebpageNegativeUrl(adGroupIds.getLongs().get(0));
            adGroupCriterions.getAdGroupCriterions().add(adGroupWebpageNegativeUrl);
            
            ArrayList<AdGroupCriterionType> adGroupCriterionTypes = new ArrayList<AdGroupCriterionType>();
            adGroupCriterionTypes.add(AdGroupCriterionType.WEBPAGE);
            
            outputStatusMessage("-----\nAddAdGroupCriterions:");
            AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = CampaignManagementExampleHelper.addAdGroupCriterions(
                    adGroupCriterions, 
                    adGroupCriterionTypes);
            outputStatusMessage("AdGroupCriterionIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(addAdGroupCriterionsResponse.getAdGroupCriterionIds());
            ArrayOfBatchErrorCollection adGroupCriterionErrors = addAdGroupCriterionsResponse.getNestedPartialErrors();
            outputStatusMessage("NestedPartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchErrorCollection(adGroupCriterionErrors);
            
            // The negative Webpage criterion at the campaign level applies to all ad groups 
            // within the campaign; however, if you define ad group level negative Webpage criterion, 
            // the campaign criterion is ignored for that ad group.
            
            ArrayOfCampaignCriterion campaignCriterions = new ArrayOfCampaignCriterion();
            NegativeCampaignCriterion negativeCampaignCriterion = getExampleCampaignWebpageNegativeUrl(campaignIds.getLongs().get(0));
            campaignCriterions.getCampaignCriterions().add(negativeCampaignCriterion);
            
            ArrayList<CampaignCriterionType> campaignCriterionTypes = new ArrayList<CampaignCriterionType>();
            campaignCriterionTypes.add(CampaignCriterionType.WEBPAGE);
            
            outputStatusMessage("-----\nAddCampaignCriterions:");
            AddCampaignCriterionsResponse addCampaignCriterionsResponse = CampaignManagementExampleHelper.addCampaignCriterions(
                    campaignCriterions, 
                    campaignCriterionTypes);
            outputStatusMessage("CampaignCriterionIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(addCampaignCriterionsResponse.getCampaignCriterionIds());
            ArrayOfBatchErrorCollection campaignCriterionErrors = addCampaignCriterionsResponse.getNestedPartialErrors();
            outputStatusMessage("NestedPartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchErrorCollection(campaignCriterionErrors);
            
            // Finally you must add at least one DynamicSearchAd into the ad group. The ad title and display URL 
            // are generated automatically based on the website domain and language that you want to target.
            
            ArrayOfAd ads = new ArrayOfAd();
            DynamicSearchAd dynamicSearchAd  = new DynamicSearchAd();
            dynamicSearchAd.setText("Find New Customers & Increase Sales!");
            dynamicSearchAd.setTextPart2("Start Advertising on Contoso Today.");
            dynamicSearchAd.setPath1("seattle");
            dynamicSearchAd.setPath2("shoe sale");
            // You cannot set FinalUrls. The Final URL will be a dynamically selected landing page.
            // The final URL is distinct from the path that customers will see and click on in your ad.
            dynamicSearchAd.setFinalUrls(null);            
            ads.getAds().add(dynamicSearchAd);
            
            outputStatusMessage("-----\nAddAds:");
            AddAdsResponse addAdsResponse = CampaignManagementExampleHelper.addAds(
                    adGroupIds.getLongs().get(0), 
                    ads);
            ArrayOfNullableOflong adIds = addAdsResponse.getAdIds();
            ArrayOfBatchError adErrors = addAdsResponse.getPartialErrors();
            outputStatusMessage("AdIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(adIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(adErrors);
            
            // Delete the campaign and everything it contains e.g., ad groups and ads.

            outputStatusMessage("-----\nDeleteCampaigns:");
            ArrayOflong deleteCampaignIds = new ArrayOflong();
            deleteCampaignIds.getLongs().add(campaignIds.getLongs().get(0));
            CampaignManagementExampleHelper.deleteCampaigns(
                    authorizationData.getAccountId(), 
                    deleteCampaignIds);
            outputStatusMessage(String.format("Deleted CampaignId %d", deleteCampaignIds.getLongs().get(0))); 
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }    

    protected static BiddableAdGroupCriterion getExampleAdGroupWebpagePositivePageContent(long adGroupId)
    {
        BiddableAdGroupCriterion adGroupWebpagePositivePageContent = new BiddableAdGroupCriterion();
        adGroupWebpagePositivePageContent.setAdGroupId(adGroupId);
        FixedBid criterionBid = new FixedBid();
        criterionBid.setAmount(0.50);
        adGroupWebpagePositivePageContent.setCriterionBid(criterionBid);
        WebpageCondition condition = new WebpageCondition();
        condition.setOperand(WebpageConditionOperand.PAGE_CONTENT);
        condition.setArgument("flowers");
        ArrayOfWebpageCondition conditions = new ArrayOfWebpageCondition();
        conditions.getWebpageConditions().add(condition);
        WebpageParameter webpageParameter = new WebpageParameter();
        webpageParameter.setConditions(conditions);
        webpageParameter.setCriterionName("Ad Group Webpage Positive Page Content Criterion");
        Webpage criterion = new Webpage();
        criterion.setParameter(webpageParameter);
        adGroupWebpagePositivePageContent.setCriterion(criterion);

        return adGroupWebpagePositivePageContent;
    }

    protected static BiddableAdGroupCriterion getExampleAdGroupWebpagePositiveCategory(long adGroupId, ArrayOfDomainCategory categories)
    {
        BiddableAdGroupCriterion adGroupWebpagePositiveCategory = new BiddableAdGroupCriterion();

        adGroupWebpagePositiveCategory.setAdGroupId(adGroupId);
        FixedBid criterionBid = new FixedBid();
        criterionBid.setAmount(0.50);
        adGroupWebpagePositiveCategory.setCriterionBid(criterionBid);
        WebpageCondition webpageCondition = new WebpageCondition();
        webpageCondition.setArgument(categories.getDomainCategories().get(0).getCategoryName());
        webpageCondition.setOperand(WebpageConditionOperand.CATEGORY);
        ArrayOfWebpageCondition conditions = new ArrayOfWebpageCondition();
        conditions.getWebpageConditions().add(webpageCondition);
        WebpageParameter webpageParameter = new WebpageParameter();
        webpageParameter.setConditions(conditions);
        webpageParameter.setCriterionName("Ad Group Webpage Positive Category Criterion");
        Webpage criterion = new Webpage();
        criterion.setParameter(webpageParameter);
        adGroupWebpagePositiveCategory.setCriterion(criterion);

        return adGroupWebpagePositiveCategory;
    }

    protected static NegativeAdGroupCriterion getExampleAdGroupWebpageNegativeUrl(long adGroupId)
    {
        NegativeAdGroupCriterion adGroupWebpageNegativeUrl = new NegativeAdGroupCriterion();
        adGroupWebpageNegativeUrl.setAdGroupId(adGroupId);
        // You can choose whether you want the criterion argument to match partial URLs, 
        // page content, page title, or categories that Bing thinks applies to your website.
        WebpageCondition webpageCondition = new WebpageCondition();
        webpageCondition.setArgument(DOMAIN_NAME);
        webpageCondition.setOperand(WebpageConditionOperand.URL);
        ArrayOfWebpageCondition conditions = new ArrayOfWebpageCondition();
        conditions.getWebpageConditions().add(webpageCondition);
        WebpageParameter webpageParameter = new WebpageParameter();
        webpageParameter.setConditions(conditions);
        // If you do not specify any name, then it will be set to a concatenated list of conditions. 
        webpageParameter.setCriterionName(null);
        Webpage criterion = new Webpage();
        criterion.setParameter(webpageParameter);
        adGroupWebpageNegativeUrl.setCriterion(criterion);

        return adGroupWebpageNegativeUrl;
    }

    protected static NegativeCampaignCriterion getExampleCampaignWebpageNegativeUrl(long campaignId)
    {
        NegativeCampaignCriterion campaignWebpageNegativeUrl  = new NegativeCampaignCriterion();
        campaignWebpageNegativeUrl.setCampaignId(campaignId);
        WebpageCondition webpageCondition = new WebpageCondition();
        webpageCondition.setArgument(DOMAIN_NAME + "\\seattle");
        webpageCondition.setOperand(WebpageConditionOperand.URL);
        WebpageParameter webpageParameter = new WebpageParameter();
        ArrayOfWebpageCondition conditions = new ArrayOfWebpageCondition();
        conditions.getWebpageConditions().add(webpageCondition);
        webpageParameter.setConditions(conditions);
        webpageParameter.setCriterionName("Campaign Negative Webpage Url Criterion");
        Webpage webpage = new Webpage();
        webpage.setParameter(webpageParameter);
        campaignWebpageNegativeUrl.setCriterion(webpage);

        return campaignWebpageNegativeUrl;
    }
}
<?php

use Microsoft\MsAds\Rest\ApiException;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\AddAdGroupCriterionsRequest;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\AddCampaignCriterionsRequest;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\AdGroup;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\AdGroupCriterionType;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\BiddableAdGroupCriterion;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\BudgetLimitType;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\Campaign;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\CampaignCriterionType;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\CampaignType;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\Date;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\DynamicSearchAd;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\DynamicSearchAdsSetting;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\FixedBid;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\NegativeAdGroupCriterion;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\NegativeCampaignCriterion;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\Webpage;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\WebpageCondition;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\WebpageConditionOperand;
use Microsoft\MsAds\Rest\Model\CampaignManagementService\WebpageParameter;
use Microsoft\MsAds\Rest\Test\RestApiTestBase;

class DynamicSearchAdsTest extends RestApiTestBase
{
    /**
     * Add a new campaign with its type set to DynamicSearchAds.
     * @throws ApiException
     */
    public function testAddCampaigns()
    {
        $campaign = new Campaign();
        $campaign->setName("Women's Shoes ".self::generateRandomAlphaNumeric());
        $campaign->setBudgetType(BudgetLimitType::DAILY_BUDGET_STANDARD);
        // Dynamic search ad campaign creation is no longer allowed. Please create a search campaign with DSA settings instead.
        $campaign->setCampaignType(CampaignType::SEARCH);
        $campaign->setDailyBudget(50.00);
        $campaign->setLanguages(['All']);
        $campaign->setTimeZone('PacificTimeUSCanadaTijuana');
        $dynamicSearchSetting = new DynamicSearchAdsSetting();
        $dynamicSearchSetting->setDomainName("www.contoso.com");
        $dynamicSearchSetting->setLanguage("English");
        $campaign->setSettings([$dynamicSearchSetting]);

        return self::addCampaignsRequest([$campaign]);
    }

    /**
     * Create a new ad group within the dynamic search ads campaign.
     * @depends testAddCampaigns
     * @throws ApiException
     */
    public function testAddAdGroups($campaignIds)
    {
        print("-----\r\nAdding Ad Groups:\r\n");

        $adGroup = new AdGroup();
        $adGroup->setName("Women's Red Shoe Sale".self::generateRandomAlphaNumeric());
        $adGroup->setCpcBid((new FixedBid())->setAmount(0.09));
        $adGroup->setStartDate(null);
        $endDate = new Date();
        $endDate->setDay(31);
        $endDate->setMonth(12);
        $endDate->setYear(date("Y"));
        $adGroup->setEndDate($endDate);
        $adGroup->setAdGroupType("SearchDynamic");

        return self::addAdGroupsRequest($campaignIds[0], [$adGroup]);
    }

    /**
     * Add one or more Webpage criteria to each ad group.
     * @depends testAddAdGroups
     * @throws ApiException
     */
    public function testAddAdGroupCriterions($adGroupIds)
    {
        print("-----\r\nAdding Ad Group Criterions:\r\n");

        $criterion = new Webpage();
//        $criterion->setType("Webpage");
        $criterion->setParameter((new WebpageParameter())
            ->setConditions([
                (new WebpageCondition())
                    ->setOperand(WebpageConditionOperand::PAGE_CONTENT)
                    ->setArgument("flowers")
            ])
            ->setCriterionName("Ad Group Webpage Positive Page Content Criterion".self::generateRandomAlphaNumeric()));

        $adGroupCriterion = new BiddableAdGroupCriterion();
        $adGroupCriterion->setAdGroupId($adGroupIds[0]);
        $adGroupCriterion->setCriterion($criterion);
        $adGroupCriterion->setCriterionBid((new FixedBid())->setAmount(0.50));

        $request = new AddAdGroupCriterionsRequest([
            'AdGroupCriterions' => [$adGroupCriterion],
            'CriterionType' => AdGroupCriterionType::WEBPAGE
        ]);

        $response = self::$campaignManagementServiceApi->addAdGroupCriterions($request);
        $criterionIds = $response->getAdGroupCriterionIds();
        print("CampaignCriterionIds:\r\n");
        print_r($criterionIds);
        print("NestedPartialErrors:\r\n");
        print_r($response->getNestedPartialErrors());
        self::assertEmpty($response->getNestedPartialErrors());
        self::assertNotEmpty($criterionIds);

        return $adGroupIds;
    }

    /**
     * @depends testAddAdGroupCriterions
     * @throws ApiException
     */
    public function testAddAdGroupCriterionsWithDomainCategory($adGroupIds)
    {
        $this->markTestIncomplete("Not implemented yet.");
        // To discover the categories that you can use for Webpage criteria (positive or negative),
        // use the GetDomainCategories operation with the Ad Insight service.
        print("-----\r\nFetching Domain Categories:\r\n");

        $request = new GetDomainCategoriesRequest([
            'DomainName' => 'contoso.com',
            'Language' => 'EN'
        ]);

        $response = self::$adInsightServiceApi->getDomainCategories($request);
        $categories = $response->getCategories();
        print("Categories:\r\n");
        print_r($categories);

        if (!empty($categories)) {
            $category = $categories[0]->getCategoryName();

            $positiveCriterion = new BiddableAdGroupCriterion();
            $positiveCriterion->setAdGroupId($adGroupIds[0]);
            $positiveCriterion->setCriterion((new Webpage())
                ->setParameter((new WebpageParameter())
                    ->setConditions([
                        (new WebpageCondition())
                            ->setOperand(WebpageConditionOperand::CATEGORY)
                            ->setArgument($category)
                    ])
                    ->setCriterionName("Positive Category Criterion")));
            $positiveCriterion->setCriterionBid((new FixedBid())->setAmount(0.50));
        }
        $request = new AddAdGroupCriterionsRequest([
            'AdGroupCriterions' => [$positiveCriterion],
            'CriterionType' => AdGroupCriterionType::WEBPAGE
        ]);
        $response = self::$campaignManagementServiceApi->addAdGroupCriterions($request);
        $criterionIds = $response->getAdGroupCriterionIds();
        print("AdGroupCriterionIds:\r\n");
        print_r($criterionIds);
        print("NestedPartialErrors:\r\n");
        print_r($response->getNestedPartialErrors());
        self::assertEmpty($response->getNestedPartialErrors());
        self::assertNotEmpty($criterionIds);
    }

    /**
     * @depends testAddAdGroupCriterions
     * @throws ApiException
     */
    public function testAddNegativeAdGroupCriterion($adGroupIds)
    {
        // If you want to exclude certain portions of your website, you can add negative Webpage
        // criterion at the campaign and ad group level.
        print("-----\r\nAdding Negative Ad Group Criterion:\r\n");
        $negativeCriterion = new NegativeAdGroupCriterion();
        $negativeCriterion->setAdGroupId($adGroupIds[0]);
        $negativeCriterion->setCriterion((new Webpage())
            ->setParameter((new WebpageParameter())
                ->setConditions([
                    (new WebpageCondition())
                        ->setOperand(WebpageConditionOperand::URL)
                        ->setArgument('contoso.com')
                ])));

        $request = new AddAdGroupCriterionsRequest([
            'AdGroupCriterions' => [$negativeCriterion],
            'CriterionType' => AdGroupCriterionType::WEBPAGE
        ]);

        $response = self::$campaignManagementServiceApi->addAdGroupCriterions($request);
        print("AdGroupCriterionIds:\r\n");
        print_r($response->getAdGroupCriterionIds());
        print("NestedPartialErrors:\r\n");
        print_r($response->getNestedPartialErrors());
        self::assertEmpty($response->getNestedPartialErrors());
        self::assertNotEmpty($response->getAdGroupCriterionIds());
    }

    /**
     * Add a negative Webpage criterion at the campaign level.
     * @depends testAddCampaigns
     * @depends testAddNegativeAdGroupCriterion
     * @throws ApiException
     */
    public function testAddCampaignCriterions($campaignIds)
    {
        // The negative Webpage criterion at the campaign level applies to all ad groups
        // within the campaign; however, if you define ad group level negative Webpage criterion,
        // the campaign criterion is ignored for that ad group.
        print("-----\r\nAdding Campaign Criterions:\r\n");

        $negativeCriterion = new NegativeCampaignCriterion();
        $negativeCriterion->setCampaignId($campaignIds[0]);
        $negativeCriterion->setCriterion((new Webpage())
            ->setParameter((new WebpageParameter())
                ->setConditions([
                    (new WebpageCondition())
                        ->setOperand(WebpageConditionOperand::URL)
                        ->setArgument('contoso.com\\seattle')
                ])
                ->setCriterionName("Negative Campaign Criterion")));

        $request = new AddCampaignCriterionsRequest([
            'CampaignCriterions' => [$negativeCriterion],
            'CriterionType' => CampaignCriterionType::WEBPAGE
        ]);

        $response = self::$campaignManagementServiceApi->addCampaignCriterions($request);
        print("CampaignCriterionIds:\r\n");
        print_r($response->getCampaignCriterionIds());
        print("PartialErrors:\r\n");
        print_r($response->getNestedPartialErrors());
        self::assertEmpty($response->getNestedPartialErrors());
        self::assertNotEmpty($response->getCampaignCriterionIds());
    }

    /**
     * Add at least one DynamicSearchAd into the ad group.
     * @depends testAddAdGroups
     * @depends testAddCampaignCriterions
     * @throws ApiException
     */
    public function testAddAds($adGroupIds)
    {
        // Finally you must add at least one DynamicSearchAd into the ad group. The ad title and display URL
        // are generated automatically based on the website domain and language that you want to target.
        print("-----\r\nAdding Ads:\r\n");

        $ad = new DynamicSearchAd();
        $ad->setText("Find New Customers & Increase Sales! Start Advertising on Contoso Today.");
        $ad->setPath1("seattle");
        $ad->setPath2("shoe sale");
        // You cannot set FinalUrls for dynamic search ads.
        // The Final URL will be a dynamically selected landing page.
        // The final URL is distinct from the path that customers will see and click on in your ad.
        return self::addAdsRequest($adGroupIds[0], [$ad]);
    }

    /**
     * Delete the campaign and everything it contains e.g., ad groups and ads.
     * @depends testAddCampaigns
     * @depends testAddAds
     * @throws ApiException
     */
    public function testDeleteCampaigns($campaignIds)
    {
        self::deleteCampaignsRequest($campaignIds);
    }
}
import uuid
from datetime import datetime
from auth_helper import *
from openapi_client.models.campaign import *


def main(authorization_data):
    try:
        # Add a new campaign with DSA settings
        # Dynamic search ad campaign creation is no longer allowed. 
        # Please create a search campaign with DSA settings instead.
        print("Creating campaign with Dynamic Search Ads settings...")
        
        dynamic_search_setting = DynamicSearchAdsSetting(
            domain_name="www.contoso.com",
            language="English"
        )
        
        campaign = Campaign(
            name="Women's Shoes " + str(uuid.uuid4()),
            budget_type=BudgetLimitType.DAILYBUDGETSTANDARD,
            campaign_type=CampaignType.SEARCH,
            daily_budget=50.00,
            languages=['All'],
            time_zone='PacificTimeUSCanadaTijuana',
            settings=[dynamic_search_setting]
        )
        
        add_campaigns_request = AddCampaignsRequest(
            account_id=authorization_data.account_id,
            campaigns=[campaign]
        )
        
        add_campaigns_response = campaign_service.add_campaigns(
            add_campaigns_request=add_campaigns_request
        )
        
        campaign_ids = add_campaigns_response.CampaignIds
        print(f"Created Campaign ID: {campaign_ids[0]}")
        
        if add_campaigns_response.PartialErrors:
            print(f"Partial Errors: {add_campaigns_response.PartialErrors}")
        
        # Create a new ad group within the dynamic search ads campaign
        print("\nCreating ad group...")
        
        current_year = datetime.now().year
        
        ad_group = AdGroup(
            name="Women's Red Shoe Sale" + str(uuid.uuid4()),
            cpc_bid=Bid(amount=0.09),
            start_date=None,
            end_date=Date(day=31, month=12, year=current_year),
            ad_group_type="SearchDynamic"
        )
        
        add_ad_groups_request = AddAdGroupsRequest(
            campaign_id=campaign_ids[0],
            ad_groups=[ad_group]
        )
        
        add_ad_groups_response = campaign_service.add_ad_groups(
            add_ad_groups_request=add_ad_groups_request
        )
        
        ad_group_ids = add_ad_groups_response.AdGroupIds
        print(f"Created Ad Group ID: {ad_group_ids[0]}")
        
        if add_ad_groups_response.PartialErrors:
            print(f"Partial Errors: {add_ad_groups_response.PartialErrors}")
        
        # Add one or more Webpage criteria to each ad group
        print("\nAdding positive ad group webpage criterion...")
        
        webpage_criterion = Webpage(
            parameter=WebpageParameter(
                conditions=[
                    WebpageCondition(
                        operand=WebpageConditionOperand.PAGECONTENT,
                        argument="flowers"
                    )
                ],
                criterion_name="Ad Group Webpage Positive Page Content Criterion" + str(uuid.uuid4())
            )
        )
        
        biddable_ad_group_criterion = BiddableAdGroupCriterion(
            ad_group_id=ad_group_ids[0],
            criterion=webpage_criterion,
            criterion_bid=FixedBid(amount=0.50)
        )
        
        add_ad_group_criterions_request = AddAdGroupCriterionsRequest(
            ad_group_criterions=[biddable_ad_group_criterion],
            criterion_type=AdGroupCriterionType.WEBPAGE
        )
        
        add_ad_group_criterions_response = campaign_service.add_ad_group_criterions(
            add_ad_group_criterions_request=add_ad_group_criterions_request
        )
        
        ad_group_criterion_ids = add_ad_group_criterions_response.AdGroupCriterionIds
        print(f"Created Ad Group Criterion IDs: {ad_group_criterion_ids}")
        
        if add_ad_group_criterions_response.NestedPartialErrors:
            print(f"Nested Partial Errors: {add_ad_group_criterions_response.NestedPartialErrors}")
        
        # Add negative Webpage criterion at ad group level
        print("\nAdding negative ad group webpage criterion...")
        
        negative_webpage = Webpage(
            parameter=WebpageParameter(
                conditions=[
                    WebpageCondition(
                        operand=WebpageConditionOperand.URL,
                        argument="contoso.com"
                    )
                ]
            )
        )
        
        negative_ad_group_criterion = NegativeAdGroupCriterion(
            ad_group_id=ad_group_ids[0],
            criterion=negative_webpage
        )
        
        add_negative_ad_group_request = AddAdGroupCriterionsRequest(
            ad_group_criterions=[negative_ad_group_criterion],
            criterion_type=AdGroupCriterionType.WEBPAGE
        )
        
        add_negative_ad_group_response = campaign_service.add_ad_group_criterions(
            add_ad_group_criterions_request=add_negative_ad_group_request
        )
        
        print(f"Created Negative Ad Group Criterion IDs: {add_negative_ad_group_response.AdGroupCriterionIds}")
        
        if add_negative_ad_group_response.NestedPartialErrors:
            print(f"Nested Partial Errors: {add_negative_ad_group_response.NestedPartialErrors}")
        
        # Add negative Webpage criterion at campaign level
        # The negative Webpage criterion at the campaign level applies to all ad groups
        # within the campaign; however, if you define ad group level negative Webpage criterion,
        # the campaign criterion is ignored for that ad group.
        print("\nAdding negative campaign webpage criterion...")
        
        negative_campaign_webpage = Webpage(
            parameter=WebpageParameter(
                conditions=[
                    WebpageCondition(
                        operand=WebpageConditionOperand.URL,
                        argument="contoso.com\\seattle"
                    )
                ],
                criterion_name="Negative Campaign Criterion"
            )
        )
        
        negative_campaign_criterion = NegativeCampaignCriterion(
            campaign_id=campaign_ids[0],
            criterion=negative_campaign_webpage
        )
        
        add_campaign_criterions_request = AddCampaignCriterionsRequest(
            campaign_criterions=[negative_campaign_criterion],
            criterion_type=CampaignCriterionType.WEBPAGE
        )
        
        add_campaign_criterions_response = campaign_service.add_campaign_criterions(
            add_campaign_criterions_request=add_campaign_criterions_request
        )
        
        print(f"Created Campaign Criterion IDs: {add_campaign_criterions_response.CampaignCriterionIds}")
        
        if add_campaign_criterions_response.NestedPartialErrors:
            print(f"Nested Partial Errors: {add_campaign_criterions_response.NestedPartialErrors}")
        
        # Add at least one DynamicSearchAd into the ad group
        # The ad title and display URL are generated automatically based on the 
        # website domain and language that you want to target.
        print("\nAdding dynamic search ad...")
        
        dynamic_search_ad = DynamicSearchAd(
            text="Find New Customers & Increase Sales! Start Advertising on Contoso Today.",
            path1="seattle",
            path2="shoe sale"
            # You cannot set FinalUrls for dynamic search ads.
            # The Final URL will be a dynamically selected landing page.
            # The final URL is distinct from the path that customers will see and click on in your ad.
        )
        
        add_ads_request = AddAdsRequest(
            ad_group_id=ad_group_ids[0],
            ads=[dynamic_search_ad]
        )
        
        add_ads_response = campaign_service.add_ads(
            add_ads_request=add_ads_request
        )
        
        ad_ids = add_ads_response.AdIds
        print(f"Created Ad IDs: {ad_ids}")
        
        if add_ads_response.PartialErrors:
            print(f"Partial Errors: {add_ads_response.PartialErrors}")
        
        # Clean up - delete the campaign and everything it contains
        print("\nDeleting campaign...")
        
        delete_campaigns_request = DeleteCampaignsRequest(
            account_id=authorization_data.account_id,
            campaign_ids=campaign_ids
        )
        
        campaign_service.delete_campaigns(
            delete_campaigns_request=delete_campaigns_request
        )
        
        print(f"Deleted Campaign ID {campaign_ids[0]}")
        
    except Exception as ex:
        print(f"Error occurred: {str(ex)}")
        import traceback
        traceback.print_exc()


if __name__ == '__main__':
    print("Loading the web service client...")
    
    authorization_data = AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )
    
    authenticate(authorization_data)
    
    campaign_service = ServiceClient(
        service='CampaignManagementService',
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )
    
    main(authorization_data)

See Also

Get Started with the Bing Ads API