Experiments Code Example

This example demonstrates how to create experiment campaigns from a base campaign.

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;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to create experiment campaigns from a base campaign.
    /// </summary>
    public class Experiments : ExampleBase
    {
        public override string Description
        {
            get { return "Experiments | Campaign Management V13"; }
        }

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

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

                // Choose a base campaign for the experiment.

                OutputStatusMessage("-----\nGetCampaignsByAccountId:");
                GetCampaignsByAccountIdResponse getCampaignsByAccountIdResponse = await CampaignManagementExampleHelper.GetCampaignsByAccountIdAsync(
                    accountId: authorizationData.AccountId,
                    campaignType: CampaignType.Search,
                    returnAdditionalFields: CampaignAdditionalField.AdScheduleUseSearcherTimeZone);
                var campaigns = getCampaignsByAccountIdResponse.Campaigns;
                OutputStatusMessage("Campaigns:");
                CampaignManagementExampleHelper.OutputArrayOfCampaign(campaigns);

                // The base campaign cannot be an experiment of another base campaign
                // i.e., the campaign's ExperimentId must be nil. 
                // Likewise the base campaign cannot use a shared budget
                // i.e., the campaign's BudgetId must be nil. 

                var baseCampaign = campaigns.FirstOrDefault(
                    campaign => campaign.ExperimentId == null && campaign.BudgetId == null);

                if (baseCampaign == null)
                {
                    OutputStatusMessage("You do not have any campaigns that are eligible for experiments.");
                    return;
                }

                // Create the experiment

                var experiments = new [] {
                    new Experiment
                    {
                        BaseCampaignId = baseCampaign.Id,
                        EndDate = new Date
                        {
                            Month = 12,
                            Day = 31,
                            Year = DateTime.UtcNow.Year
                        },
                        ExperimentCampaignId = null,
                        ExperimentStatus = "Active",
                        ExperimentType = null,
                        Id = null,
                        Name = baseCampaign.Name + "-Experiment",
                        StartDate = new Date
                        {
                            Month = DateTime.UtcNow.Month,
                            Day = DateTime.UtcNow.Day,
                            Year = DateTime.UtcNow.Year
                        },
                        TrafficSplitPercent = 50
                    }
                };

                OutputStatusMessage("-----\nAddExperiments:");
                AddExperimentsResponse addExperimentsResponse = await CampaignManagementExampleHelper.AddExperimentsAsync(
                        experiments: experiments);
                long?[] experimentIds = addExperimentsResponse.ExperimentIds.ToArray();
                BatchError[] experimentErrors = addExperimentsResponse.PartialErrors.ToArray();
                OutputStatusMessage("ExperimentIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(experimentIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(experimentErrors);

                OutputStatusMessage("-----\nGetExperimentsByIds:");
                GetExperimentsByIdsResponse getExperimentsByIdsResponse = await CampaignManagementExampleHelper.GetExperimentsByIdsAsync(
                        experimentIds: new[] { (long)experimentIds[0] },
                        pageInfo: null);
                OutputStatusMessage("Experiments:");
                CampaignManagementExampleHelper.OutputArrayOfExperiment(getExperimentsByIdsResponse.Experiments);

                var experiment = getExperimentsByIdsResponse.Experiments?.ToList()[0];

                // If the experiment is in a Graduated state, then the former experiment campaign 
                // is now an independent campaign that must be deleted separately. 
                // Otherwise if you delete the base campaign (not shown here), 
                // the experiment campaign and experiment itself are also deleted.

                OutputStatusMessage("-----\nDeleteCampaigns:");
                await CampaignManagementExampleHelper.DeleteCampaignsAsync(
                    accountId: authorizationData.AccountId,
                    campaignIds: new[] { (long)experiment.ExperimentCampaignId });
                OutputStatusMessage(string.Format("Deleted Experiment Campaign Id {0} with Status '{1}'",
                    experiment.ExperimentCampaignId,
                    experiment.ExperimentStatus));

                OutputStatusMessage("-----\nDeleteExperiments:");
                await CampaignManagementExampleHelper.DeleteExperimentsAsync(
                    experimentIds: new[] { (long)experiment.Id });
                OutputStatusMessage(string.Format("Deleted Experiment Id {0}", experiment.Id));        
            }
            // 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 java.util.ArrayList;
import java.util.Calendar;

import com.microsoft.bingads.*;
import com.microsoft.bingads.v13.campaignmanagement.*;
import java.util.HashSet;
import java.util.List;
import java.util.stream.*;

public class Experiments extends ExampleBase {
    
    public static void main(java.lang.String[] args) {
     
        try
        {
            authorizationData = getAuthorizationData(); 
             
            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                        authorizationData, 
                        API_ENVIRONMENT,
                        ICampaignManagementService.class);
            
            ArrayList<CampaignType> campaignTypes = new ArrayList<CampaignType>();
            campaignTypes.add(CampaignType.SEARCH);   
            
            // Choose a base campaign for the experiment.
                        
            outputStatusMessage("-----\nGetCampaignsByAccountId:");
            GetCampaignsByAccountIdResponse getCampaignsByAccountIdResponse = CampaignManagementExampleHelper.getCampaignsByAccountId(
                authorizationData.getAccountId(),
                campaignTypes,
                null);
            ArrayOfCampaign campaigns = getCampaignsByAccountIdResponse.getCampaigns();
            outputStatusMessage("Campaigns:");
            CampaignManagementExampleHelper.outputArrayOfCampaign(campaigns);  
            
            // The base campaign cannot be an experiment of another base campaign
            // i.e., the campaign's ExperimentId must be nil. 
            // Likewise the base campaign cannot use a shared budget
            // i.e., the campaign's BudgetId must be nil. 

            Campaign baseCampaign = null;
            if (baseCampaign == null) baseCampaign = campaigns.getCampaigns().stream().filter(
                    campaign -> campaign.getExperimentId() == null && campaign.getBudgetId() == null).findFirst().orElse(null);
            
            if (baseCampaign == null)
            {
                outputStatusMessage("You do not have any campaigns that are eligible for experiments.");
                return;
            }

            // Create the experiment
            
            ArrayOfExperiment experiments = new ArrayOfExperiment();
            Experiment experiment = new Experiment();
            experiment.setBaseCampaignId(baseCampaign.getId());
            Calendar calendar = Calendar.getInstance();
            experiment.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
            experiment.getEndDate().setDay(31);
            experiment.getEndDate().setMonth(12);
            experiment.getEndDate().setYear(calendar.get(Calendar.YEAR));
            experiment.setExperimentCampaignId(null);
            experiment.setExperimentStatus("Active");
            experiment.setExperimentType(null);
            experiment.setId(null);
            experiment.setName(baseCampaign.getName() + "-Experiment");
            experiment.setStartDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
            experiment.getStartDate().setDay(calendar.get(Calendar.DAY_OF_MONTH));
            experiment.getStartDate().setMonth(calendar.get(Calendar.MONTH) + 1);
            experiment.getStartDate().setYear(calendar.get(Calendar.YEAR));
            experiment.setTrafficSplitPercent(50);
            experiments.getExperiments().add(experiment);

            outputStatusMessage("-----\nAddExperiments:");
            AddExperimentsResponse addExperimentsResponse = CampaignManagementExampleHelper.addExperiments(
                    experiments);
            ArrayOfNullableOflong nullableExperimentIds = addExperimentsResponse.getExperimentIds();
            ArrayOfBatchError experimentErrors = addExperimentsResponse.getPartialErrors();
            outputStatusMessage("ExperimentIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(nullableExperimentIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(experimentErrors);

            outputStatusMessage("-----\nGetExperimentsByIds:");
            ArrayOflong experimentIds = new ArrayOflong();
            experimentIds.getLongs().add(nullableExperimentIds.getLongs().get(0));
            GetExperimentsByIdsResponse getExperimentsByIdsResponse = CampaignManagementExampleHelper.getExperimentsByIds(experimentIds,
                    null);
            experiments = getExperimentsByIdsResponse.getExperiments();
            outputStatusMessage("Experiments:");
            CampaignManagementExampleHelper.outputArrayOfExperiment(experiments);

            experiment = experiments.getExperiments().get(0);

            // If the experiment is in a Graduated state, then the former experiment campaign 
            // is now an independent campaign that must be deleted separately. 
            // Otherwise if you delete the base campaign (not shown here), 
            // the experiment campaign and experiment itself are also deleted.

            outputStatusMessage("-----\nDeleteCampaigns:");
            ArrayOflong campaignIds = new ArrayOflong();
            campaignIds.getLongs().add(experiment.getExperimentCampaignId());
            CampaignManagementExampleHelper.deleteCampaigns(
                    authorizationData.getAccountId(), 
                    campaignIds);
            outputStatusMessage(String.format("Deleted Experiment Campaign Id %s with Status '%s'",
                experiment.getExperimentCampaignId(),
                experiment.getExperimentStatus()));

            outputStatusMessage("-----\nDeleteExperiments:");
            CampaignManagementExampleHelper.deleteExperiments(
                    experimentIds);
            outputStatusMessage(String.format("Deleted Experiment Id %s", experiment.getId()));   
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }    
 }
<?php

namespace Microsoft\BingAds\Samples\V13;

// For more information about installing and using the Bing Ads PHP SDK, 
// see https://go.microsoft.com/fwlink/?linkid=838593.

require_once __DIR__ . "/../vendor/autoload.php";

include __DIR__ . "/AuthHelper.php";
include __DIR__ . "/AdInsightExampleHelper.php";
include __DIR__ . "/CampaignManagementExampleHelper.php";

use SoapVar;
use SoapFault;
use Exception;

// Specify the Microsoft\BingAds\Auth classes that will be used.
use Microsoft\BingAds\Auth\ServiceClient;
use Microsoft\BingAds\Auth\ServiceClientType;

// Specify the Microsoft\BingAds\Samples classes that will be used.
use Microsoft\BingAds\Samples\V13\AuthHelper;
use Microsoft\BingAds\Samples\V13\CampaignManagementExampleHelper;

// Specify the Microsoft\BingAds\V13\CampaignManagement classes that will be used.
use Microsoft\BingAds\V13\CampaignManagement\CampaignType;
use Microsoft\BingAds\V13\CampaignManagement\Date;
use Microsoft\BingAds\V13\CampaignManagement\Experiment;

try
{
    // Authenticate user credentials and set the account ID for the sample.  
    AuthHelper::Authenticate();

    // Choose a base campaign for the experiment.

    print("-----\r\nGetCampaignsByAccountId:\r\n");
    $getCampaignsByAccountIdResponse = CampaignManagementExampleHelper::GetCampaignsByAccountId(
        $GLOBALS['AuthorizationData']->AccountId,
        AuthHelper::CampaignTypes,
        AuthHelper::CampaignAdditionalFields
    );
    $campaigns = $getCampaignsByAccountIdResponse->Campaigns;
    print("Campaigns:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfCampaign($campaigns);

    // The base campaign cannot be an experiment of another base campaign
    // i.e., the campaign's ExperimentId must be nil. 
    // Likewise the base campaign cannot use a shared budget
    // i.e., the campaign's BudgetId must be nil. 
    
    $baseCampaign = null;
    foreach ($campaigns->Campaign as $campaign) {
        if(((isset($campaign->ExperimentId) && $campaign->ExperimentId == null) || !isset($campaign->ExperimentId))
        && $campaign->BudgetId == null){
            $baseCampaign = $campaign;
            break;
        }
    }

    if($baseCampaign == null){
        print("You do not have any campaigns that are eligible for experiments.");
        return;
    }

    // Create the experiment

    $experiments = array();   
    $experiment = new Experiment();
    $experiment->BaseCampaignId = $baseCampaign->Id;
    date_default_timezone_set('UTC');
    $endDate = new Date();
    $endDate->Day = 31;
    $endDate->Month = 12;
    $endDate->Year = date("Y");
    $experiment->EndDate = $endDate;
    $experiment->ExperimentCampaignId = null;
    $experiment->ExperimentStatus = "Active";
    $experiment->ExperimentType = null;
    $experiment->Id = null;
    $experiment->Name = $baseCampaign->Name . "-Experiment";
    $startDate = new Date();
    $startDate->Day = date("d");
    $startDate->Month = date("m");
    $startDate->Year = date("Y");
    $experiment->StartDate = $startDate;
    $experiment->TrafficSplitPercent = 50;
    $experiments[] = $experiment;
    
    print("-----\r\nAddExperiments:\r\n");
    $addExperimentsResponse = CampaignManagementExampleHelper::AddExperiments(
        $experiments
    );
    $experimentIds = $addExperimentsResponse->ExperimentIds;
    print("ExperimentIds:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfLong($experimentIds);
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($addExperimentsResponse->PartialErrors);

    print("-----\r\nGetExperimentsByIds:\r\n");
    $getExperimentsByIdsResponse = CampaignManagementExampleHelper::GetExperimentsByIds(
        $experimentIds,
        null
    );
    print("Experiments:");
    CampaignManagementExampleHelper::OutputArrayOfExperiment($getExperimentsByIdsResponse->Experiments);

    $experiment = $getExperimentsByIdsResponse->Experiments->Experiment[0];

    // If the experiment is in a Graduated state, then the former experiment campaign 
    // is now an independent campaign that must be deleted separately. 
    // Otherwise if you delete the base campaign (not shown here), 
    // the experiment campaign and experiment itself are also deleted.

    print("-----\r\nDeleteCampaigns:\r\n");
    CampaignManagementExampleHelper::DeleteCampaigns(
        $GLOBALS['AuthorizationData']->AccountId, 
        array($experiment->ExperimentCampaignId)
    );
    printf("Deleted Experiment Campaign Id %s with Status '%s'\r\n",
        $experiment->ExperimentCampaignId,
        $experiment->ExperimentStatus
    );

    print("-----\nDeleteExperiments:\r\n");
    CampaignManagementExampleHelper::DeleteExperiments(
        array($experiment->Id)
    );
    printf("Deleted Experiment Id %s\r\n", $experiment->Id);   
}
catch (SoapFault $e)
{
    printf("-----\r\nFault Code: %s\r\nFault String: %s\r\nFault Detail: \r\n", $e->faultcode, $e->faultstring);
    var_dump($e->detail);
    print "-----\r\nLast SOAP request/response:\r\n";
    print $GLOBALS['Proxy']->GetWsdl() . "\r\n";
    print $GLOBALS['Proxy']->GetService()->__getLastRequest()."\r\n";
    print $GLOBALS['Proxy']->GetService()->__getLastResponse()."\r\n";
}
catch (Exception $e)
{
    // Ignore fault exceptions that we already caught.
    if ($e->getPrevious())
    { ; }
    else
    {
        print $e->getCode()." ".$e->getMessage()."\n\n";
        print $e->getTraceAsString()."\n\n";
    }
}
from auth_helper import *
from campaignmanagement_example_helper import *

# You must provide credentials in auth_helper.py.

def main(authorization_data): 

    try:
        # Choose a base campaign for the experiment.

        output_status_message("-----\nGetCampaignsByAccountId:")
        campaigns=campaign_service.GetCampaignsByAccountId(
            AccountId=authorization_data.account_id, 
            CampaignType=['Search'])
        output_status_message("Campaigns:")
        output_array_of_campaign(campaigns)

        # The base campaign cannot be an experiment of another base campaign
        # i.e., the campaign's ExperimentId must be nil. 
        # Likewise the base campaign cannot use a shared budget
        # i.e., the campaign's BudgetId must be nil. 
 
        base_campaign=None
        for campaign in campaigns['Campaign']:
            if ((hasattr(campaign, 'ExperimentId') and campaign.ExperimentId is None) or not hasattr(campaign, 'ExperimentId')) \
            and campaign.BudgetId is None:
                base_campaign=campaign
                break

        if base_campaign is None:
            output_status_message("You do not have any campaigns that are eligible for experiments.")
            sys.exit(0)
        
        # Create the experiment

        experiments=campaign_service.factory.create('ArrayOfExperiment')
        experiment=set_elements_to_none(campaign_service.factory.create('Experiment'))
        experiment.BaseCampaignId=base_campaign.Id
        end_date=campaign_service.factory.create('Date')
        end_date.Day=31
        end_date.Month=12
        current_time=gmtime()
        end_date.Year=current_time.tm_year + 1
        experiment.EndDate=end_date
        experiment.ExperimentCampaignId=None
        experiment.ExperimentStatus="Active"
        experiment.ExperimentType=None
        experiment.Id=None
        experiment.Name=base_campaign.Name + "-Experiment"
        start_date=campaign_service.factory.create('Date')
        start_date.Day=current_time.tm_mday
        start_date.Month=current_time.tm_mon
        start_date.Year=current_time.tm_year
        experiment.StartDate=start_date
        experiment.TrafficSplitPercent=50
        experiments.Experiment.append(experiment)

        output_status_message("-----\nAddExperiments:")
        add_experiments_response=campaign_service.AddExperiments(
            Experiments=experiments
        )
        experiment_ids={
            'long': add_experiments_response.ExperimentIds['long'] if add_experiments_response.ExperimentIds['long'] else None
        }
        output_status_message("ExperimentIds:")
        output_array_of_long(experiment_ids)
        output_status_message("PartialErrors:")
        output_array_of_batcherror(add_experiments_response.PartialErrors)

        output_status_message("-----\nGetExperimentsByIds:")
        get_experiments_by_ids_response=campaign_service.GetExperimentsByIds(
            ExperimentIds=experiment_ids,
            PageInfo=None
        )
        output_status_message("Experiments:")
        output_array_of_experiment(get_experiments_by_ids_response.Experiments)

        experiment=get_experiments_by_ids_response.Experiments['Experiment'][0]
        campaign_ids={
            'long': [experiment.ExperimentCampaignId]
        }

        # If the experiment is in a Graduated state, then the former experiment campaign 
        # is now an independent campaign that must be deleted separately. 
        # Otherwise if you delete the base campaign (not shown here), 
        # the experiment campaign and experiment itself are also deleted.

        output_status_message("-----\nDeleteCampaigns:")
        campaign_service.DeleteCampaigns(
            AccountId=authorization_data.account_id, 
            CampaignIds=campaign_ids
        )
        output_status_message("Deleted Experiment Campaign Id {0} with Status '{1}'".format(
            experiment.ExperimentCampaignId,
            experiment.ExperimentStatus))

        output_status_message("-----\nDeleteExperiments:")
        campaign_service.DeleteExperiments(
            ExperimentIds=experiment_ids)
        for id in experiment_ids['long']:
            output_status_message("Deleted Experiment Id {0}".format(id))

    except WebFault as ex:
        output_webfault_errors(ex)
    except Exception as ex:
        output_status_message(ex)


# Main execution
if __name__ == '__main__':

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

See Also

Get Started with the Bing Ads API