Page Summary
-
This code example demonstrates how to create a new experiment and experiment arms.
-
It shows how to modify the draft campaign associated with the experiment arm.
-
Finally, it illustrates how to schedule and begin the created experiment.
Java
// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.experiments ; import static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime ; import com.beust.jcommander.Parameter ; import com.google.ads.googleads.examples.utils.ArgumentNames ; import com.google.ads.googleads.examples.utils.CodeSampleParams ; import com.google.ads.googleads.lib.GoogleAdsClient ; import com.google.ads.googleads.lib.utils.FieldMasks ; import com.google.ads.googleads.v24.enums.ExperimentStatusEnum.ExperimentStatus ; import com.google.ads.googleads.v24.enums.ExperimentTypeEnum.ExperimentType ; import com.google.ads.googleads.v24.enums.ResponseContentTypeEnum.ResponseContentType ; import com.google.ads.googleads.v24.errors.GoogleAdsError ; import com.google.ads.googleads.v24.errors.GoogleAdsException ; import com.google.ads.googleads.v24.resources.Campaign ; import com.google.ads.googleads.v24.resources.Experiment ; import com.google.ads.googleads.v24.resources.ExperimentArm ; import com.google.ads.googleads.v24.services.CampaignOperation ; import com.google.ads.googleads.v24.services.CampaignServiceClient ; import com.google.ads.googleads.v24.services.ExperimentArmOperation ; import com.google.ads.googleads.v24.services.ExperimentArmServiceClient ; import com.google.ads.googleads.v24.services.ExperimentOperation ; import com.google.ads.googleads.v24.services.ExperimentServiceClient ; import com.google.ads.googleads.v24.services.MutateExperimentArmResult ; import com.google.ads.googleads.v24.services.MutateExperimentArmsRequest ; import com.google.ads.googleads.v24.services.MutateExperimentArmsResponse ; import com.google.ads.googleads.v24.services.MutateExperimentsResponse ; import com.google.ads.googleads.v24.utils.ResourceNames ; import com.google.common.collect.ImmutableList ; import java.io.FileNotFoundException ; import java.io.IOException ; import java.util.ArrayList ; import java.util.List ; /** * Creates a standard, system-managed campaign experiment of type SEARCH_CUSTOM. * * <p>Sets up the experiment, configures its control and treatment arms (where the treatment arm * automatically generates a draft campaign), modifies the system-generated draft campaign, and * schedule the experiment. * * <p>Note: This standard draft-based workflow applies only to experiment types that use * system-generated treatment campaign copies, and excludes intra-campaign or asset-optimization * experiments. */ public class CreateSearchCustomExperiment { private static class CreateSearchCustomExperimentParams extends CodeSampleParams { @Parameter ( names = ArgumentNames . CUSTOMER_ID , required = true ) private Long customerId ; @Parameter ( names = ArgumentNames . BASE_CAMPAIGN_ID , required = true ) private Long baseCampaignId ; } public static void main ( String [] args ) { CreateSearchCustomExperimentParams params = new CreateSearchCustomExperimentParams (); if ( ! params . parseArguments ( args )) { throw new IllegalArgumentException ( "Invalid or missing command line arguments" ); } GoogleAdsClient googleAdsClient = null ; try { googleAdsClient = GoogleAdsClient . newBuilder (). fromPropertiesFile (). build (); } catch ( FileNotFoundException fnfe ) { System . err . printf ( "Failed to load GoogleAdsClient configuration from file. Exception: %s%n" , fnfe ); System . exit ( 1 ); } catch ( IOException ioe ) { System . err . printf ( "Failed to create GoogleAdsClient. Exception: %s%n" , ioe ); System . exit ( 1 ); } try { new CreateSearchCustomExperiment () . runExample ( googleAdsClient , params . customerId , params . baseCampaignId ); } catch ( GoogleAdsException gae ) { // GoogleAdsException is the base class for most exceptions thrown by an API request. // Instances of this exception have a message and a GoogleAdsFailure that contains a // collection of GoogleAdsErrors that indicate the underlying causes of the // GoogleAdsException. System . err . printf ( "Request ID %s failed due to GoogleAdsException. Underlying errors:%n" , gae . getRequestId ()); int i = 0 ; for ( GoogleAdsError googleAdsError : gae . getGoogleAdsFailure (). getErrorsList ()) { System . err . printf ( " Error %d: %s%n" , i ++ , googleAdsError ); } System . exit ( 1 ); } } /** * Runs the example. * * @param googleAdsClient the googleAdsClient. * @param customerId the customer ID. * @param baseCampaignId the ID of the campaign on which to base the experiment. */ private void runExample ( GoogleAdsClient googleAdsClient , long customerId , long baseCampaignId ) { String experiment = createExperimentResource ( googleAdsClient , customerId ); String draftCampaign = createExperimentArms ( googleAdsClient , customerId , baseCampaignId , experiment ); modifyDraftCampaign ( googleAdsClient , customerId , draftCampaign ); // When you're done setting up the experiment and arms and modifying the draft campaign, this // will begin the experiment. try ( ExperimentServiceClient experimentServiceClient = googleAdsClient . getLatestVersion (). createExperimentServiceClient ()) { experimentServiceClient . scheduleExperimentAsync ( experiment ); } } /** Creates a campaign experiment. */ private String createExperimentResource ( GoogleAdsClient googleAdsClient , long customerId ) { ExperimentOperation operation = ExperimentOperation . newBuilder () . setCreate ( Experiment . newBuilder () // Name must be unique. . setName ( "Example Experiment #" + getPrintableDateTime ()) // We specify SEARCH_CUSTOM to create a standard search campaign experiment. // This type uses a standard draft-based workflow where the system automatically // creates a draft/in-design campaign for the treatment arm. . setType ( ExperimentType . SEARCH_CUSTOM ) . setSuffix ( "[experiment]" ) . setStatus ( ExperimentStatus . SETUP ) . build ()) . build (); try ( ExperimentServiceClient experimentServiceClient = googleAdsClient . getLatestVersion (). createExperimentServiceClient ()) { MutateExperimentsResponse response = experimentServiceClient . mutateExperiments ( Long . toString ( customerId ), ImmutableList . of ( operation )); String experiment = response . getResults ( 0 ). getResourceName (); System . out . printf ( "Created experiment with resource name '%s'%n" , experiment ); return experiment ; } } /** Creates control and experiment arms for the experiment. */ private String createExperimentArms ( GoogleAdsClient googleAdsClient , long customerId , long campaignId , String experiment ) { List<ExperimentArmOperation> operations = new ArrayList <> (); operations . add ( ExperimentArmOperation . newBuilder () . setCreate ( // The "control" arm references an already-existing campaign. ExperimentArm . newBuilder () . setControl ( true ) . addCampaigns ( ResourceNames . campaign ( customerId , campaignId )) . setExperiment ( experiment ) . setName ( "control arm" ) . setTrafficSplit ( 40 ) . build ()) . build ()); operations . add ( ExperimentArmOperation . newBuilder () . setCreate ( // In standard campaign experiments, creating the treatment arm automatically // generates a draft campaign that you can modify before starting the experiment. ExperimentArm . newBuilder () . setControl ( false ) . setExperiment ( experiment ) . setName ( "experiment arm" ) . setTrafficSplit ( 60 ) . build ()) . build ()); try ( ExperimentArmServiceClient experimentArmServiceClient = googleAdsClient . getLatestVersion (). createExperimentArmServiceClient ()) { // Constructs the mutate request. MutateExperimentArmsRequest mutateRequest = MutateExperimentArmsRequest . newBuilder () . setCustomerId ( Long . toString ( customerId )) . addAllOperations ( operations ) // We want to fetch the draft campaign IDs from the treatment arm, so the easiest way // to do that is to have the response return the newly created entities. . setResponseContentType ( ResponseContentType . MUTABLE_RESOURCE ) . build (); // Sends the mutate request. MutateExperimentArmsResponse response = experimentArmServiceClient . mutateExperimentArms ( mutateRequest ); // Results always return in the order that you specify them in the request. Since we created // the treatment arm last, it will be the last result. If you don't remember which arm is the // treatment arm, you can always filter the query in the next section with // `experiment_arm.control = false`. MutateExperimentArmResult controlArmResult = response . getResults ( 0 ); MutateExperimentArmResult treatmentArmResult = response . getResults ( response . getResultsCount () - 1 ); System . out . printf ( "Created control arm with resource name '%s'%n" , controlArmResult . getResourceName ()); System . out . printf ( "Created treatment arm with resource name '%s'%n" , treatmentArmResult . getResourceName ()); return treatmentArmResult . getExperimentArm (). getInDesignCampaigns ( 0 ); } } /** Modifies the draft campaign. */ private void modifyDraftCampaign ( GoogleAdsClient googleAdsClient , long customerId , String draftCampaign ) { Campaign . Builder campaignBuilder = Campaign . newBuilder (). setResourceName ( draftCampaign ); // You can change anything you like about the campaign. These are the changes you're testing by // doing this experiment. Here we just change the name for illustrative purposes, but generally // you may want to change more meaningful parts of the campaign. // // You can also change underlying resources, such as ad groups and keywords, just as you // would for any other campaign. When searching with the GoogleAdsService, be sure to // include a PARAMETERS clause with `include_drafts = true` when searching for these // draft entities. Campaign campaign = campaignBuilder . setName ( "Modified Campaign Name " + getPrintableDateTime ()). build (); CampaignOperation operation = CampaignOperation . newBuilder () . setUpdate ( campaign ) . setUpdateMask ( FieldMasks . allSetFieldsOf ( campaign )) . build (); try ( CampaignServiceClient campaignServiceClient = googleAdsClient . getLatestVersion (). createCampaignServiceClient ()) { campaignServiceClient . mutateCampaigns ( Long . toString ( customerId ), ImmutableList . of ( operation )); System . out . printf ( "Updated the name for campaign '%s'%n" , draftCampaign ); } } }
C#
// Copyright 2026 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using CommandLine ; using Google.Ads.Gax.Examples ; using Google.Ads.Gax.Util ; using Google.Ads.GoogleAds.Lib ; using Google.Ads.GoogleAds.V24.Errors ; using Google.Ads.GoogleAds.V24.Resources ; using Google.Ads.GoogleAds.V24.Services ; using System ; using System.Linq ; using static Google . Ads . GoogleAds . V24 . Enums . ExperimentStatusEnum . Types ; using static Google . Ads . GoogleAds . V24 . Enums . ExperimentTypeEnum . Types ; using static Google . Ads . GoogleAds . V24 . Enums . ResponseContentTypeEnum . Types ; namespace Google.Ads.GoogleAds.Examples.V24 { /// <summary> /// Creates a standard, system-managed campaign experiment of type SEARCH_CUSTOM. /// Sets up the experiment, configures control and treatment arms (where the /// treatment arm automatically generates a draft campaign), modifies the /// system-generated draft campaign, and schedules the experiment. /// /// Note: This standard draft-based workflow applies only to experiment types /// that use system-generated treatment campaign copies, and excludes /// intra-campaign or asset optimization experiments. /// </summary> public class CreateSearchCustomExperiment : ExampleBase { /// <summary> /// Command line options for running the <see cref="CreateSearchCustomExperiment"/> example. /// </summary> public class Options : OptionsBase { /// <summary> /// The customer ID for which the call is made. /// </summary> [Option("customerId", Required = true, HelpText = "The customer ID for which the call is made.")] public long CustomerId { get ; set ; } /// <summary> /// Id of the campaign for which the control arm is created. /// </summary> [Option("baseCampaignId", Required = true, HelpText = "Id of the campaign for which the control arm is created.")] public long BaseCampaignId { get ; set ; } } /// <summary> /// Main method, to run this code example as a standalone application. /// </summary> /// <param name="args">The command line arguments.</param> public static void Main ( string [] args ) { Options options = ExampleUtilities . ParseCommandLine<Options> ( args ); CreateSearchCustomExperiment codeExample = new CreateSearchCustomExperiment (); Console . WriteLine ( codeExample . Description ); codeExample . Run ( new GoogleAdsClient (), options . CustomerId , options . BaseCampaignId ); } /// <summary> /// Returns a description about the code example. /// </summary> public override string Description = > "Creates a standard, system-managed campaign experiment of type SEARCH_CUSTOM. " + "Sets up the experiment, configures control and treatment arms (where the " + "treatment arm automatically generates a draft campaign), modifies the " + "system-generated draft campaign, and schedules the experiment." ; /// <summary> /// Runs the code example. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="baseCampaignId">Id of the campaign for which the control arm is created.</param> public void Run ( GoogleAdsClient client , long customerId , long baseCampaignId ) { // Get the ExperimentService. ExperimentServiceClient experimentService = client . GetService ( Services . V24 . ExperimentService ); try { string experimentResourceName = CreateExperimentResource ( client , customerId ); MutateExperimentArmResult controlArm , treatmentArm ; ( controlArm , treatmentArm ) = CreateExperimentArms ( client , customerId , baseCampaignId , experimentResourceName ); ModifyDraftCampaign ( client , customerId , treatmentArm . ExperimentArm . InDesignCampaigns . First ()); // When you're done setting up the experiment and arms and modifying the draft // campaign, this will begin the experiment. experimentService . ScheduleExperiment ( experimentResourceName ); } catch ( GoogleAdsException e ) { Console . WriteLine ( "Failure:" ); Console . WriteLine ( $"Message: {e.Message}" ); Console . WriteLine ( $"Failure: {e.Failure}" ); Console . WriteLine ( $"Request ID: {e.RequestId}" ); throw ; } } /// <summary> /// Creates the experiment resource. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <returns>The resource name of the newly created experiment.</returns> private static string CreateExperimentResource ( GoogleAdsClient client , long customerId ) { // Get the ExperimentService. ExperimentServiceClient experimentService = client . GetService ( Services . V24 . ExperimentService ); // Creates the experiment. Experiment experiment = new Experiment () { // Name must be unique. Name = $"Example Experiment #{ExampleUtilities.GetRandomString()}" , // We specify SearchCustom to create a standard search campaign experiment. // This type uses a standard draft-based workflow where the system automatically // creates a draft/in-design campaign for the treatment arm. Type = ExperimentType . SearchCustom , Suffix = "[experiment]" , Status = ExperimentStatus . Setup }; // Creates the operation. ExperimentOperation operation = new ExperimentOperation () { Create = experiment }; // Makes the API call. MutateExperimentsResponse response = experimentService . MutateExperiments ( customerId . ToString (), new [] { operation }); // Displays the result. string experimentResourceName = response . Results . First (). ResourceName ; Console . WriteLine ( $"Created experiment with resource name " + $"'{experimentResourceName}'." ); return experimentResourceName ; } /// <summary> /// Creates the experiment arms. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="baseCampaignId">ID of the campaign for which the control arm is /// created.</param> /// <param name="experimentResourceName">Resource name of the experiment.</param> /// <returns>The control and treatment arms.</returns> private static ( MutateExperimentArmResult , MutateExperimentArmResult ) CreateExperimentArms ( GoogleAdsClient client , long customerId , long baseCampaignId , string experimentResourceName ) { // Get the ExperimentArmService. ExperimentArmServiceClient experimentService = client . GetService ( Services . V24 . ExperimentArmService ); // Create the control arm. The control arm references an already-existing campaign. ExperimentArmOperation controlArmOperation = new ExperimentArmOperation () { Create = new ExperimentArm () { Control = true , Campaigns = { ResourceNames . Campaign ( customerId , baseCampaignId ) }, Experiment = experimentResourceName , Name = "Control Arm" , TrafficSplit = 40 } }; // Create the non-control arm. // In standard campaign experiments, creating the treatment arm automatically // generates a draft campaign that you can modify before starting the experiment. ExperimentArmOperation treatmentArmOperation = new ExperimentArmOperation () { Create = new ExperimentArm () { Control = false , Experiment = experimentResourceName , Name = "Experiment Arm" , TrafficSplit = 60 } }; // We want to fetch the draft campaign IDs from the treatment arm, so the // easiest way to do that is to have the response return the newly created // entities. MutateExperimentArmsRequest request = new MutateExperimentArmsRequest { CustomerId = customerId . ToString (), Operations = { controlArmOperation , treatmentArmOperation }, ResponseContentType = ResponseContentType . MutableResource }; MutateExperimentArmsResponse response = experimentService . MutateExperimentArms ( request ); // Results always return in the order that you specify them in the request. // Since we created the treatment arm last, it will be the last result. MutateExperimentArmResult controlArm = response . Results . First (); MutateExperimentArmResult treatmentArm = response . Results . Last (); Console . WriteLine ( $"Created control arm with resource name " + $"'{controlArm.ResourceName}'." ); Console . WriteLine ( $"Created treatment arm with resource name" + $" '{treatmentArm.ResourceName}'." ); return ( controlArm , treatmentArm ); } /// <summary> /// Modifies the draft campaign. /// </summary> /// <param name="client">The Google Ads client.</param> /// <param name="customerId">The customer ID for which the call is made.</param> /// <param name="draftCampaignResourceName">Resource name of the draft campaign.</param> private static void ModifyDraftCampaign ( GoogleAdsClient client , long customerId , string draftCampaignResourceName ) { // Get the CampaignService. CampaignServiceClient campaignService = client . GetService ( Services . V24 . CampaignService ); // You can change anything you like about the campaign. These are the changes you're // testing by doing this experiment. Here we just change the name for illustrative // purposes, but generally you may want to change more meaningful parts of the campaign. // // You can also change underlying resources, such as ad groups and keywords, just as // you would for any other campaign. When searching with the GoogleAdsService, be sure // to include a PARAMETERS clause with `include_drafts = true` when searching for // these draft entities. Campaign campaign = new Campaign () { ResourceName = draftCampaignResourceName , Name = $"Modified Campaign Name #{ExampleUtilities.GetRandomString()}" }; // Creates an operation. CampaignOperation operation = new CampaignOperation () { Update = campaign , UpdateMask = FieldMasks . AllSetFieldsOf ( campaign ) }; // Makes the API call. MutateCampaignsResponse response = campaignService . MutateCampaigns ( customerId . ToString (), new [] { operation }); // Displays the result. Console . WriteLine ( $"Updated the name for campaign {draftCampaignResourceName}." ); } } }
PHP
< ?php /** * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Ads\GoogleAds\Examples\CampaignManagement; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Examples\Utils\Helper; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V24\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V24\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V24\GoogleAdsException; use Google\Ads\GoogleAds\Util\FieldMasks; use Google\Ads\GoogleAds\Util\V24\ResourceNames; use Google\Ads\GoogleAds\V24\Enums\ExperimentStatusEnum\ExperimentStatus; use Google\Ads\GoogleAds\V24\Enums\ExperimentTypeEnum\ExperimentType; use Google\Ads\GoogleAds\V24\Enums\ResponseContentTypeEnum\ResponseContentType; use Google\Ads\GoogleAds\V24\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V24\Resources\Campaign; use Google\Ads\GoogleAds\V24\Resources\Experiment; use Google\Ads\GoogleAds\V24\Resources\ExperimentArm; use Google\Ads\GoogleAds\V24\Services\CampaignOperation; use Google\Ads\GoogleAds\V24\Services\Client\ExperimentServiceClient; use Google\Ads\GoogleAds\V24\Services\ExperimentArmOperation; use Google\Ads\GoogleAds\V24\Services\ExperimentOperation; use Google\Ads\GoogleAds\V24\Services\MutateCampaignsRequest; use Google\Ads\GoogleAds\V24\Services\MutateExperimentArmsRequest; use Google\Ads\GoogleAds\V24\Services\MutateExperimentsRequest; use Google\ApiCore\ApiException; /** * This example creates a new experiment, experiment arms, and demonstrates how to modify the draft * campaign as well as begin the experiment. */ class CreateExperiment { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; private const BASE_CAMPAIGN_ID = 'INSERT_BASE_CAMPAIGN_ID_HERE'; public static function main() { // Either pass the required parameters for this example on the command line, or insert them // into the constants above. $options = (new ArgumentParser())->parseCommandArguments([ ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT, ArgumentNames::BASE_CAMPAIGN_ID => GetOpt::REQUIRED_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. $googleAdsClient = (new GoogleAdsClientBuilder()) ->fromFile() ->withOAuth2Credential($oAuth2Credential) ->build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID, $options[ArgumentNames::BASE_CAMPAIGN_ID] ?: self::BASE_CAMPAIGN_ID ); } catch (GoogleAdsException $googleAdsException) { printf( "Request with ID '%s' has failed.%sGoogle Ads failure details:%s", $googleAdsException->getRequestId(), PHP_EOL, PHP_EOL ); foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) { /** @var GoogleAdsError $error */ printf( "\t%s: %s%s", $error->getErrorCode()->getErrorCode(), $error->getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( "ApiException was thrown with message '%s'.%s", $apiException->getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the client customer ID * @param int $campaignId the campaign ID */ public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, int $campaignId ) { $experimentServiceClient = $googleAdsClient->getExperimentServiceClient(); $experimentResourceName = self::createExperimentResource($experimentServiceClient, $customerId); $draftCampaignResourceName = self::createExperimentArms( $googleAdsClient, $customerId, $campaignId, $experimentResourceName ); self::modifyDraftCampaign($googleAdsClient, $customerId, $draftCampaignResourceName); // When you're done setting up the experiment and arms and modifying the draft campaign, // this will begin the experiment. $experimentServiceClient->scheduleExperiment($experimentResourceName); } /** * Creates an experiment resource. * * @param ExperimentServiceClient $experimentServiceClient the experiment service client * @param int $customerId the customer ID * @return string the created experiment's resource name */ private static function createExperimentResource( ExperimentServiceClient $experimentServiceClient, int $customerId ): string { // Creates an experiment and its operation. $experiment = new Experiment([ // Name must be unique. 'name' => 'Example Experiment #' . Helper::getPrintableDatetime(), 'type' => ExperimentType::SEARCH_CUSTOM, 'suffix' => '[experiment]', 'status' => ExperimentStatus::SETUP ]); $experimentOperation = new ExperimentOperation(['create' => $experiment]); // Issues a request to create the experiment. $response = $experimentServiceClient->mutateExperiments( MutateExperimentsRequest::build($customerId, [$experimentOperation]) ); $experimentResourceName = $response->getResults()[0]->getResourceName(); print "Created experiment with resource name '$experimentResourceName'" . PHP_EOL; return $experimentResourceName; } /** * Creates experiment arms and returns the treatment arm resource name, which will be used in * the next step. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param int $campaignId the campaign ID * @param string $experimentResourceName the experiment's resource name * @return string the treatment arm's resource name */ private static function createExperimentArms( GoogleAdsClient $googleAdsClient, int $customerId, int $campaignId, string $experimentResourceName ): string { $operations = []; $experimentArm1 = new ExperimentArm([ // The "control" arm references an already-existing campaign. 'control' => true, 'campaigns' => [ResourceNames::forCampaign($customerId, $campaignId)], 'experiment' => $experimentResourceName, 'name' => 'control arm', 'traffic_split' => 40 ]); $operations[] = new ExperimentArmOperation(['create' => $experimentArm1]); $experimentArm2 = new ExperimentArm([ // The non-"control" arm, also called a "treatment" arm, will automatically // generate draft campaigns that you can modify before starting the // experiment. 'control' => false, 'experiment' => $experimentResourceName, 'name' => 'experiment arm', 'traffic_split' => 60 ]); $operations[] = new ExperimentArmOperation(['create' => $experimentArm2]); // Issues a request to create the experiment arms. $experimentArmServiceClient = $googleAdsClient->getExperimentArmServiceClient(); $response = $experimentArmServiceClient->mutateExperimentArms( MutateExperimentArmsRequest::build($customerId, $operations) // We want to fetch the draft campaign IDs from the treatment arm, so the easiest // way to do that is to have the response return the newly created entities. ->setResponseContentType(ResponseContentType::MUTABLE_RESOURCE) ); // Results always return in the order that you specify them in the request. // Since we created the treatment arm last, it will be the last result. $controlArmResourceName = $response->getResults()[0]->getResourceName(); $treatmentArm = $response->getResults()[count($operations) - 1]; print "Created control arm with resource name '$controlArmResourceName'" . PHP_EOL; print "Created treatment arm with resource name '{$treatmentArm->getResourceName()}'" . PHP_EOL; return $treatmentArm->getExperimentArm()->getInDesignCampaigns()[0]; } /** * Modifies the draft campaign to simulate the experiment where you're testing changing * attributes of the campaign. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param string $draftCampaignResourceName the draft campaign's resource name */ private static function modifyDraftCampaign( GoogleAdsClient $googleAdsClient, int $customerId, string $draftCampaignResourceName ): void { // You can change anything you like about the campaign. These are the changes you're testing // by doing this experiment. Here we just change the name for illustrative purposes, but // generally you may want to change more meaningful parts of the campaign. $updatedCampaign = new Campaign([ 'resource_name' => $draftCampaignResourceName, 'name' => 'Modified Campaign Name ' . Helper::getShortPrintableDatetime() ]); $campaignOperation = new CampaignOperation(); $campaignOperation->setUpdate($updatedCampaign); $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($updatedCampaign)); // Issues a request to update the campaign. $campaignServiceClient = $googleAdsClient->getCampaignServiceClient(); $campaignServiceClient->mutateCampaigns( MutateCampaignsRequest::build($customerId, [$campaignOperation]) ); print "Updated the name for the campaign '$draftCampaignResourceName'" . PHP_EOL; } } CreateExperiment::main();
Python
# Encoding: utf-8 # # Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Creates a standard, system-managed campaign experiment of type SEARCH_CUSTOM. Sets up the experiment, configures control and treatment arms (where the treatment arm automatically generates a draft campaign), modifies the system-generated draft campaign, and schedules the experiment. Note: This standard draft-based workflow applies only to experiment types that use system-generated treatment campaign copies, and excludes intra-campaign or asset optimization experiments. """ import argparse import sys import uuid from typing import List , Any from google.api_core import protobuf_helpers from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v24.services.types.experiment_service import ( ExperimentOperation , MutateExperimentsResponse , ) from google.ads.googleads.v24.services.types.experiment_arm_service import ( ExperimentArmOperation , MutateExperimentArmsRequest , MutateExperimentArmsResponse , ) from google.ads.googleads.v24.resources.types.experiment import Experiment from google.ads.googleads.v24.resources.types.experiment_arm import ( ExperimentArm , ) from google.ads.googleads.v24.services.services.experiment_service import ( ExperimentServiceClient , ) from google.ads.googleads.v24.services.services.experiment_arm_service import ( ExperimentArmServiceClient , ) from google.ads.googleads.v24.services.services.campaign_service import ( CampaignServiceClient , ) from google.ads.googleads.v24.services.types.campaign_service import ( CampaignOperation , ) from google.ads.googleads.v24.resources.types.campaign import Campaign def main ( client : GoogleAdsClient , customer_id : str , base_campaign_id : str ) - > None : """The main method that creates all necessary entities for the example. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. base_campaign_id: the campaign ID to associate with the control arm of the experiment. """ experiment : str = create_experiment_resource ( client , customer_id ) draft_campaign : str = create_experiment_arms ( client , customer_id , base_campaign_id , experiment ) modify_draft_campaign ( client , customer_id , draft_campaign ) # When you're done setting up the experiment and arms and modifying the # draft campaign, this will begin the experiment. experiment_service : ExperimentServiceClient = client . get_service ( "ExperimentService" ) experiment_service . schedule_experiment ( resource_name = experiment ) def create_experiment_resource ( client : GoogleAdsClient , customer_id : str ) - > str : """Creates a new experiment resource. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. Returns: the resource name for the new experiment. """ experiment_operation : ExperimentOperation = client . get_type ( "ExperimentOperation" ) experiment : Experiment = experiment_operation . create experiment . name = f "Example Experiment # { uuid . uuid4 () } " # We specify SEARCH_CUSTOM to create a standard search campaign experiment. # This type uses a standard draft-based workflow where the system automatically # creates a draft/in-design campaign for the treatment arm. experiment . type_ = client . enums . ExperimentTypeEnum . SEARCH_CUSTOM experiment . suffix = "[experiment]" experiment . status = client . enums . ExperimentStatusEnum . SETUP experiment_service : ExperimentServiceClient = client . get_service ( "ExperimentService" ) response : MutateExperimentsResponse = experiment_service . mutate_experiments ( customer_id = customer_id , operations = [ experiment_operation ] ) experiment_resource_name : str = response . results [ 0 ] . resource_name print ( f "Created experiment with resource name { experiment_resource_name } " ) return experiment_resource_name def create_experiment_arms ( client : GoogleAdsClient , customer_id : str , base_campaign_id : str , experiment : str , ) - > str : """Creates a control and treatment experiment arms. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. base_campaign_id: the campaign ID to associate with the control arm of the experiment. experiment: the resource name for an experiment. Returns: the resource name for the new treatment experiment arm. """ operations : List [ ExperimentArmOperation ] = [] campaign_service : CampaignServiceClient = client . get_service ( "CampaignService" ) # The "control" arm references an already-existing campaign. operation_1 : ExperimentArmOperation = client . get_type ( "ExperimentArmOperation" ) exa_1 : ExperimentArm = operation_1 . create exa_1 . control = True exa_1 . campaigns . append ( campaign_service . campaign_path ( customer_id , base_campaign_id ) ) exa_1 . experiment = experiment exa_1 . name = "control arm" exa_1 . traffic_split = 40 operations . append ( operation_1 ) # In standard campaign experiments, creating the treatment arm automatically # generates a draft campaign that you can modify before starting the experiment. operation_2 : ExperimentArmOperation = client . get_type ( "ExperimentArmOperation" ) exa_2 : ExperimentArm = operation_2 . create exa_2 . control = False exa_2 . experiment = experiment exa_2 . name = "experiment arm" exa_2 . traffic_split = 60 operations . append ( operation_2 ) experiment_arm_service : ExperimentArmServiceClient = client . get_service ( "ExperimentArmService" ) request : MutateExperimentArmsRequest = client . get_type ( "MutateExperimentArmsRequest" ) request . customer_id = customer_id request . operations = operations # We want to fetch the draft campaign IDs from the treatment arm, so the # easiest way to do that is to have the response return the newly created # entities. request . response_content_type = ( client . enums . ResponseContentTypeEnum . MUTABLE_RESOURCE ) response : MutateExperimentArmsResponse = ( experiment_arm_service . mutate_experiment_arms ( request = request ) ) # Results always return in the order that you specify them in the request. # Since we created the treatment arm second, it will be the second result. control_arm_result : Any = response . results [ 0 ] treatment_arm_result : Any = response . results [ 1 ] print ( f "Created control arm with resource name { control_arm_result . resource_name } " ) print ( f "Created treatment arm with resource name { treatment_arm_result . resource_name } " ) return treatment_arm_result . experiment_arm . in_design_campaigns [ 0 ] def modify_draft_campaign ( client : GoogleAdsClient , customer_id : str , draft_campaign : str ) - > None : """Modifies the given in-design campaign. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. draft_campaign: the resource name for an in-design campaign. """ campaign_service : CampaignServiceClient = client . get_service ( "CampaignService" ) campaign_operation : CampaignOperation = client . get_type ( "CampaignOperation" ) campaign : Campaign = campaign_operation . update campaign . resource_name = draft_campaign # You can change anything you like about the campaign. These are the changes # you're testing by doing this experiment. Here we just change the name for # illustrative purposes, but generally you may want to change more # meaningful parts of the campaign. campaign . name = f "Modified Campaign Name # { uuid . uuid4 () } " client . copy_from ( campaign_operation . update_mask , protobuf_helpers . field_mask ( None , campaign . _pb ), ) campaign_service . mutate_campaigns ( customer_id = customer_id , operations = [ campaign_operation ] ) print ( f "Updated name for campaign { draft_campaign } " ) if __name__ == "__main__" : parser : argparse . ArgumentParser = argparse . ArgumentParser ( description = ( "Create a campaign experiment based on a campaign draft." ) ) # The following argument(s) need to be provided to run the example. parser . add_argument ( "-c" , "--customer_id" , type = str , required = True , help = "The Google Ads customer ID." , ) parser . add_argument ( "-i" , "--base_campaign_id" , type = str , required = True , help = "The campaign id." , ) args : argparse . Namespace = parser . parse_args () # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client : GoogleAdsClient = GoogleAdsClient . load_from_storage ( version = "v24" ) try : main ( googleads_client , args . customer_id , args . base_campaign_id ) except GoogleAdsException as ex : print ( f 'Request with ID " { ex . request_id } " failed with status ' f '" { ex . error . code () . name } " and includes the following errors:' ) for error in ex . failure . errors : print ( f ' \t Error with message " { error . message } ".' ) if error . location : for field_path_element in error . location . field_path_elements : print ( f " \t\t On field: { field_path_element . field_name } " ) sys . exit ( 1 )
Ruby
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example creates a new experiment, experiment arms, and demonstrates # how to modify the draft campaign as well as begin the experiment. require 'optparse' require 'google/ads/google_ads' def create_experiment ( customer_id , base_campaign_id ) # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google :: Ads :: GoogleAds :: GoogleAdsClient . new experiment = create_experiment_resource ( client , customer_id ) draft_campaign = create_experiment_arms ( client , customer_id , base_campaign_id , experiment ) modify_draft_campaign ( client , customer_id , draft_campaign ) # When you're done setting up the experiment and arms and modifying the draft # campaign, this will begin the experiment. response = client . service . experiment . schedule_experiment ( # This is from the very first step above. resource_name : experiment , ) end def create_experiment_resource ( client , customer_id ) operation = client . operation . create_resource . experiment do | e | # Name must be unique. e . name = "Example Experiment #{ ( Time . new . to_f * 1000 ) . to_i } " e . type = :SEARCH_CUSTOM e . suffix = '[experiment]' e . status = :SETUP end response = client . service . experiment . mutate_experiments ( customer_id : customer_id , operations : [ operation ] , ) experiment = response . results . first . resource_name puts "Created experiment with resource name #{ experiment } ." experiment end def create_experiment_arms ( client , customer_id , base_campaign_id , experiment ) operations = [] operations << client . operation . create_resource . experiment_arm do | ea | # The "control" arm references an already-existing campaign. ea . control = true ea . campaigns << client . path . campaign ( customer_id , base_campaign_id ) ea . experiment = experiment ea . name = 'control arm' ea . traffic_split = 40 end operations << client . operation . create_resource . experiment_arm do | ea | # The non-"control" arm, also called a "treatment" arm, will automatically # generate draft campaigns that you can modify before starting the # experiment. ea . control = false ea . experiment = experiment ea . name = 'experiment arm' ea . traffic_split = 60 end response = client . service . experiment_arm . mutate_experiment_arms ( customer_id : customer_id , operations : operations , # We want to fetch the draft campaign IDs from the treatment arm, so the # easiest way to do that is to have the response return the newly created # entities. response_content_type : :MUTABLE_RESOURCE , ) # Results always return in the order that you specify them in the request. # Since we created the treatment arm last, it will be the last result. control_arm_result = response . results . first treatment_arm_result = response . results . last puts "Created control arm with resource name #{ control_arm_result . resource_name } ." puts "Created treatment arm with resource name #{ treatment_arm_result . resource_name } ." treatment_arm_result . experiment_arm . in_design_campaigns . first end def modify_draft_campaign ( client , customer_id , draft_campaign ) operation = client . operation . update_resource . campaign ( draft_campaign ) do | c | # In this block you can change anything you like about the campaign. These # are the changes you're testing by doing this experiment. Here we just # change the name for illustrative purposes, but generally you may want to # change more meaningful parts of the campaign. # # You can also change underlying resources, such as ad groups and keywords, # just as you would for any other campaign. When searching with the # GoogleAdsService, be sure to include a PARAMETERS clause with # `include_drafts = true` when searching for these draft entities. c . name = "Modified Campaign Name #{ ( Time . new . to_f * 1000 ) . to_i } " end response = client . service . campaign . mutate_campaigns ( customer_id : customer_id , operations : [ operation ] , ) puts "Updated the name for campaign #{ draft_campaign } ." end if __FILE__ == $0 options = {} # Running the example with -h will print the command line usage. OptionParser . new do | opts | opts . banner = sprintf ( 'Usage: %s [options]' , File . basename ( __FILE__ )) opts . separator '' opts . separator 'Options:' opts . on ( '-C' , '--customer-id CUSTOMER-ID' , String , 'Customer ID' ) do | v | options [ :customer_id ] = v end opts . on ( '-c' , '--base-campaign-id BASE-CAMPAIGN' , String , 'Base Campaign ID' ) do | v | options [ :base_campaign_id ] = v end opts . separator '' opts . separator 'Help:' opts . on_tail ( '-h' , '--help' , 'Show this message' ) do puts opts exit end end . parse! begin create_experiment ( options . fetch ( :customer_id ) . tr ( "-" , "" ), options . fetch ( :base_campaign_id ), ) rescue Google :: Ads :: GoogleAds :: Errors :: GoogleAdsError = > e e . failure . errors . each do | error | STDERR . printf ( "Error with message: %s \n " , error . message ) if error . location error . location . field_path_elements . each do | field_path_element | STDERR . printf ( " \t On field: %s \n " , field_path_element . field_name ) end end error . error_code . to_h . each do | k , v | next if v == :UNSPECIFIED STDERR . printf ( " \t Type: %s \n\t Code: %s \n " , k , v ) end end raise end end
Perl
#!/usr/bin/perl -w # # Copyright 2022, Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example creates a new experiment, experiment arms, and demonstrates # how to modify the draft campaign as well as begin the experiment. use strict ; use warnings ; use utf8 ; use FindBin qw($Bin) ; use lib "$Bin/../../lib" ; use Google::Ads::GoogleAds::Client ; use Google::Ads::GoogleAds::Utils::GoogleAdsHelper ; use Google::Ads::GoogleAds::Utils::FieldMasks ; use Google::Ads::GoogleAds::V24::Enums::ExperimentStatusEnum qw(SETUP) ; use Google::Ads::GoogleAds::V24::Enums::ExperimentTypeEnum qw(SEARCH_CUSTOM) ; use Google::Ads::GoogleAds::V24::Enums::ResponseContentTypeEnum qw(MUTABLE_RESOURCE) ; use Google::Ads::GoogleAds::V24::Resources::Campaign ; use Google::Ads::GoogleAds::V24::Resources::Experiment ; use Google::Ads::GoogleAds::V24::Resources::ExperimentArm ; use Google::Ads::GoogleAds::V24::Services::CampaignService::CampaignOperation ; use Google::Ads::GoogleAds::V24::Services::ExperimentService::ExperimentOperation ; use Google::Ads::GoogleAds::V24::Services::ExperimentArmService::ExperimentArmOperation ; use Google::Ads::GoogleAds::V24::Utils::ResourceNames ; use Getopt::Long qw(:config auto_help) ; use Pod::Usage ; use Cwd qw(abs_path) ; use Data::Uniqid qw(uniqid) ; use POSIX qw(strftime) ; sub create_experiment { my ( $api_client , $customer_id , $base_campaign_id ) = @_ ; my $experiment = create_experiment_resource ( $api_client , $customer_id ); my $draft_campaign = create_experiment_arms ( $api_client , $customer_id , $base_campaign_id , $experiment ); modify_draft_campaign ( $api_client , $customer_id , $draft_campaign ); # When you're done setting up the experiment and arms and modifying the draft # campaign, this will begin the experiment. my $response = $api_client - > ExperimentService () - > schedule_experiment ({ # This is from the very first step above. resourceName = > $experiment }); return 1 ; } sub create_experiment_resource { my ( $api_client , $customer_id ) = @_ ; my $experiment = Google::Ads::GoogleAds::V24::Resources:: Experiment - > new ({ # Name must be unique. name = > "Example Experiment #" . uniqid (), type = > SEARCH_CUSTOM , suffix = > "[experiment]" , status = > SETUP }); my $operation = Google::Ads::GoogleAds::V24::Services::ExperimentService:: ExperimentOperation - > new ({ create = > $experiment }); my $response = $api_client - > ExperimentService () - > mutate ({ customerId = > $customer_id , operations = > [ $operation ]}); my $resource_name = $response - > { results }[ 0 ]{ resourceName }; printf "Created experiment with resource name '%s'.\n" , $resource_name ; return $resource_name ; } sub create_experiment_arms { my ( $api_client , $customer_id , $base_campaign_id , $experiment ) = @_ ; my $operations = [] ; push @$operations , Google::Ads::GoogleAds::V24::Services::ExperimentArmService:: ExperimentArmOperation - > new ({ create = > Google::Ads::GoogleAds::V24::Resources:: ExperimentArm - > new ({ # The "control" arm references an already-existing campaign. control = > "true" , campaigns = > [ Google::Ads::GoogleAds::V24::Utils::ResourceNames:: campaign ( $customer_id , $base_campaign_id ) ], experiment = > $experiment , name = > "control arm" , trafficSplit = > 40 })}); push @$operations , Google::Ads::GoogleAds::V24::Services::ExperimentArmService:: ExperimentArmOperation - > new ({ create = > Google::Ads::GoogleAds::V24::Resources:: ExperimentArm - > new ({ # The non-"control" arm, also called a "treatment" arm, will automatically # generate draft campaigns that you can modify before starting the # experiment. control = > "false" , experiment = > $experiment , name = > "experiment arm" , trafficSplit = > 60 })}); my $response = $api_client - > ExperimentArmService () - > mutate ({ customerId = > $customer_id , operations = > $operations , # We want to fetch the draft campaign IDs from the treatment arm, so the # easiest way to do that is to have the response return the newly created # entities. responseContentType = > MUTABLE_RESOURCE }); # Results always return in the order that you specify them in the request. # Since we created the treatment arm last, it will be the last result. my $control_arm_result = $response - > { results }[ 0 ]; my $treatment_arm_result = $response - > { results }[ 1 ]; printf "Created control arm with resource name '%s'.\n" , $control_arm_result - > { resourceName }; printf "Created treatment arm with resource name '%s'.\n" , $treatment_arm_result - > { resourceName }; return $treatment_arm_result - > { experimentArm }{ inDesignCampaigns }[ 0 ]; } sub modify_draft_campaign { my ( $api_client , $customer_id , $draft_campaign ) = @_ ; # In this block you can change anything you like about the campaign. These # are the changes you're testing by doing this experiment. Here we just # change the name for illustrative purposes, but generally you may want to # change more meaningful parts of the campaign. # # You can also change underlying resources, such as ad groups and keywords, # just as you would for any other campaign. When searching with the # GoogleAdsService, be sure to include a PARAMETERS clause with # `include_drafts = true` when searching for these draft entities. my $updated_campaign = Google::Ads::GoogleAds::V24::Resources:: Campaign - > new ({ resourceName = > $draft_campaign , name = > "Modified Campaign Name " . strftime ( "%Y%m%d" , localtime ( time ))}); my $operation = Google::Ads::GoogleAds::V24::Services::CampaignService:: CampaignOperation - > new ({ update = > $updated_campaign , updateMask = > all_set_fields_of ( $updated_campaign )}); my $response = $api_client - > CampaignService () - > mutate ({ customerId = > $customer_id , operations = > [ $operation ]}); printf "Updated the name for the campaign '%s'.\n" , $draft_campaign ; return 1 ; } # Don't run the example if the file is being included. if ( abs_path ( $0 ) ne abs_path ( __FILE__ )) { return 1 ; } # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds:: Client - > new (); # By default examples are set to die on any server returned fault. $api_client - > set_die_on_faults ( 1 ); my $customer_id ; my $base_campaign_id ; # Parameters passed on the command line will override any parameters set in code. GetOptions ( "customer_id=s" = > \ $customer_id , "base_campaign_id=i" = > \ $base_campaign_id ); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage ( 2 ) if not check_params ( $customer_id , $base_campaign_id ); # Call the example. create_experiment ( $api_client , $customer_id =~ s/-//g r , $base_campaign_id ); =pod =head1 NAME create_experiment =head1 DESCRIPTION This example creates a new experiment, experiment arms, and demonstrates how to modify the draft campaign as well as begin the experiment. =head1 SYNOPSIS create_experiment.pl [options] -help Show the help message. -customer_id The Google Ads customer ID. -base_campaign_id The base campaign ID. =cut

