Estimating Traffic

The TrafficEstimatorService of the AdWords API retrieves traffic estimates for proposed or existing campaigns, ad groups, and keywords, including estimated stats like:

  • Average CPC
  • Average Position
  • Click Through Rate
  • Clicks Per Day
  • Impressions Per Day
  • Total Cost

You can simulate proposed campaigns and ad groups by using different campaign criteria, network settings, daily budgets, and max CPCs.

You can also retrieve traffic estimates for an existing campaign or ad group by providing the corresponding campaignId and adGroupId.

Use case

When creating a new campaign and ad group, or when modifying existing campaigns, you can use the TrafficEstimatorService to estimate future traffic and help you decide whether your proposed keywords (and settings) are optimal. For example, if the chosen keywords result in a lower CTR, you may want to reconsider using the keyword.

You can also use the TrafficEstimatorService to obtain information similar to the Plan your budget and get forecasts feature of the AdWords Keyword Planner.

Additionally, you can use the TargetingIdeaService to get additional keyword ideas for an ad group. Before implementing the new keyword ideas, use the TrafficEstimatorService to get an estimate on how these new keywords will perform. Check out Generating Targeting Ideas for additional information.

Getting traffic estimates

The primary input to the TrafficEstimatorService is the TrafficEstimatorSelector.

To retrieve traffic estimates, you must either specify existing campaigns and ad groups, or configure proposed campaigns and ad groups by setting the CampaignEstimateRequest and AdGroupEstimateRequest.

Within AdGroupEstimateRequest, you must also specify a KeywordEstimateRequest for the keywords you want traffic estimates for.

The following sections step through an example of getting traffic estimates from the TrafficEstimatorService.

Prepare the request

You'll need to build the TrafficEstimatorSelector from the bottom up. To create a full request, you should build the request in the following order:

  1. KeywordEstimateRequest
  2. AdGroupEstimateRequest
  3. CampaignEstimateRequest

First, you need to build the KeywordEstimateRequest. It's common to retrieve estimates for multiple keywords: Each keyword should have a corresponding KeywordEstimateRequest.

Java

List<Keyword> keywords = new ArrayList<Keyword>();

Keyword marsCruiseKeyword = new Keyword();
marsCruiseKeyword.setText("mars cruise");
marsCruiseKeyword.setMatchType(KeywordMatchType.BROAD);
keywords.add(marsCruiseKeyword);

Keyword cheapCruiseKeyword = new Keyword();
cheapCruiseKeyword.setText("cheap cruise");
cheapCruiseKeyword.setMatchType(KeywordMatchType.PHRASE);
keywords.add(cheapCruiseKeyword);

Keyword cruiseKeyword = new Keyword();
cruiseKeyword.setText("cruise");
cruiseKeyword.setMatchType(KeywordMatchType.EXACT);
keywords.add(cruiseKeyword);

// Create a keyword estimate request for each keyword.
List<KeywordEstimateRequest> keywordEstimateRequests = new ArrayList<KeywordEstimateRequest>();
for (Keyword keyword : keywords) {
  KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest();
  keywordEstimateRequest.setKeyword(keyword);
  keywordEstimateRequests.add(keywordEstimateRequest);
}

// Add a negative keyword to the traffic estimate.
KeywordEstimateRequest negativeKeywordEstimateRequest = new KeywordEstimateRequest();
negativeKeywordEstimateRequest.setKeyword(new Keyword(null, null, null, "hiking tour",
    KeywordMatchType.BROAD));
negativeKeywordEstimateRequest.setIsNegative(true);
keywordEstimateRequests.add(negativeKeywordEstimateRequest);
    

C#

Keyword keyword1 = new Keyword();
keyword1.text = "mars cruise";
keyword1.matchType = KeywordMatchType.BROAD;

Keyword keyword2 = new Keyword();
keyword2.text = "cheap cruise";
keyword2.matchType = KeywordMatchType.PHRASE;

Keyword keyword3 = new Keyword();
keyword3.text = "cruise";
keyword3.matchType = KeywordMatchType.EXACT;

Keyword[] keywords = new Keyword[] { keyword1, keyword2, keyword3 };

// Create a keyword estimate request for each keyword.
List<KeywordEstimateRequest> keywordEstimateRequests = new List<KeywordEstimateRequest>();

foreach (Keyword keyword in keywords) {
  KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest();
  keywordEstimateRequest.keyword = keyword;
  keywordEstimateRequests.Add(keywordEstimateRequest);
}

// Create negative keywords.
Keyword negativeKeyword1 = new Keyword();
negativeKeyword1.text = "moon walk";
negativeKeyword1.matchType = KeywordMatchType.BROAD;

KeywordEstimateRequest negativeKeywordEstimateRequest = new KeywordEstimateRequest();
negativeKeywordEstimateRequest.keyword = negativeKeyword1;
negativeKeywordEstimateRequest.isNegative = true;
keywordEstimateRequests.Add(negativeKeywordEstimateRequest);
    

Python

keywords = [
    {'text': 'mars cruise', 'matchType': 'BROAD'},
    {'text': 'cheap cruise', 'matchType': 'PHRASE'},
    {'text': 'cruise', 'matchType': 'EXACT'}
]
negative_keywords = [
    {'text': 'moon walk', 'matchType': 'BROAD'}
]
keyword_estimate_requests = []
for keyword in keywords:
  keyword_estimate_requests.append({
      'keyword': {
          'xsi_type': 'Keyword',
          'matchType': keyword['matchType'],
          'text': keyword['text']
      }
  })

for keyword in negative_keywords:
  keyword_estimate_requests.append({
      'keyword': {
          'xsi_type': 'Keyword',
          'matchType': keyword['matchType'],
          'text': keyword['text']
      },
      'isNegative': 'true'
  })
    

PHP

// Create keywords. Up to 2000 keywords can be passed in a single request.
$keywords = [];

$keyword = new Keyword();
$keyword->setText('mars cruise');
$keyword->setMatchType(KeywordMatchType::BROAD);
$keywords[] = $keyword;

$keyword = new Keyword();
$keyword->setText('cheap cruise');
$keyword->setMatchType(KeywordMatchType::PHRASE);
$keywords[] = $keyword;

$keyword = new Keyword();
$keyword->setText('cruise');
$keyword->setMatchType(KeywordMatchType::EXACT);
$keywords[] = $keyword;

// Create a keyword estimate request for each keyword.
$keywordEstimateRequests = [];
foreach ($keywords as $keyword) {
  $keywordEstimateRequest = new KeywordEstimateRequest();
  $keywordEstimateRequest->setKeyword($keyword);
  $keywordEstimateRequests[] = $keywordEstimateRequest;
}

// Negative keywords don't return estimates, but adjust the estimates of the
// other keywords in the hypothetical ad group.
$negativeKeywords = [];

$keyword = new Keyword();
$keyword->setText('moon walk');
$keyword->setMatchType(KeywordMatchType::BROAD);
$negativeKeywords[] = $keyword;

// Create a keyword estimate request for each negative keyword.
foreach ($negativeKeywords as $negativeKeyword) {
  $keywordEstimateRequest = new KeywordEstimateRequest();
  $keywordEstimateRequest->setKeyword($negativeKeyword);
  $keywordEstimateRequest->setIsNegative(true);
  $keywordEstimateRequests[] = $keywordEstimateRequest;
}
    

Perl

# Create keywords. Refer to the TrafficEstimatorService documentation for
# the maximum number of keywords that can be passed in a single request.
# https://developers.google.com/adwords/api/docs/reference/latest/TrafficEstimatorService
my @keywords = (
  Google::Ads::AdWords::v201710::Keyword->new({
      text      => "mars cruise",
      matchType => "BROAD"
    }
  ),
  Google::Ads::AdWords::v201710::Keyword->new({
      text      => "cheap cruise",
      matchType => "PHRASE"
    }
  ),
  Google::Ads::AdWords::v201710::Keyword->new({
      text      => "cruise",
      matchType => "EXACT"
    }));

my @negative_keywords = (
  Google::Ads::AdWords::v201710::Keyword->new({
      text      => "moon walk",
      matchType => "BROAD"
    }));

# Create a keyword estimate request for each keyword.
my @keyword_estimate_requests;
foreach my $keyword (@keywords) {
  push @keyword_estimate_requests,
    Google::Ads::AdWords::v201710::KeywordEstimateRequest->new(
    {keyword => $keyword,});
}
foreach my $keyword (@negative_keywords) {
  push @keyword_estimate_requests,
    Google::Ads::AdWords::v201710::KeywordEstimateRequest->new({
      keyword    => $keyword,
      isNegative => 1
    });
}
    

Ruby

# Create keywords. Up to 2000 keywords can be passed in a single request.
keywords = [
    # The 'xsi_type' field allows you to specify the xsi:type of the object
    # being created. It's only necessary when you must provide an explicit
    # type that the client library can't infer.
  {:xsi_type => 'Keyword', :text => 'mars cruise', :match_type => 'BROAD'},
  {:xsi_type => 'Keyword', :text => 'cheap cruise', :match_type => 'PHRASE'},
  {:xsi_type => 'Keyword', :text => 'cruise', :match_type => 'EXACT'},
  {:xsi_type => 'Keyword', :text => 'moon walk', :match_type => 'BROAD'}
]

# Create a keyword estimate request for each keyword.
keyword_requests = keywords.map {|keyword| {:keyword => keyword}}

# Negative keywords don't return estimates, but adjust the estimates of the
# other keywords in the hypothetical ad group. To specify a negative keyword
# set the is_negative field to true.
keyword_requests[3][:is_negative] = true
    

The list of keywords you send to TrafficEstimatorService can contain what you already have in your keyword taxonomy, or it can contain new keywords you retrieve from the TargetingIdeaService.

Next, build the AdGroupEstimateRequest. Like the keywords list, you can estimate on multiple ad groups. This example estimates only for a single ad group:

Java

// Create ad group estimate requests.
List<AdGroupEstimateRequest> adGroupEstimateRequests = new ArrayList<AdGroupEstimateRequest>();
AdGroupEstimateRequest adGroupEstimateRequest = new AdGroupEstimateRequest();
adGroupEstimateRequest.setKeywordEstimateRequests(keywordEstimateRequests
    .toArray(new KeywordEstimateRequest[] {}));
adGroupEstimateRequest.setMaxCpc(new Money(null, 1000000L));
adGroupEstimateRequests.add(adGroupEstimateRequest);
    

C#

// Create ad group estimate requests.
AdGroupEstimateRequest adGroupEstimateRequest = new AdGroupEstimateRequest();
adGroupEstimateRequest.keywordEstimateRequests = keywordEstimateRequests.ToArray();
adGroupEstimateRequest.maxCpc = new Money();
adGroupEstimateRequest.maxCpc.microAmount = 1000000;
    

Python

# Create ad group estimate requests.
adgroup_estimate_requests = [{
    'keywordEstimateRequests': keyword_estimate_requests,
    'maxCpc': {
        'xsi_type': 'Money',
        'microAmount': '1000000'
    }
}]
    

PHP

// Create ad group estimate requests.
$adGroupEstimateRequest = new AdGroupEstimateRequest();
$adGroupEstimateRequest->setKeywordEstimateRequests(
    $keywordEstimateRequests);
$money = new Money();
$money->setMicroAmount(1000000);
$adGroupEstimateRequest->setMaxCpc($money);
    

Perl

# Create ad group estimate requests.
my $ad_group_estimate_request =
  Google::Ads::AdWords::v201710::AdGroupEstimateRequest->new({
    keywordEstimateRequests => \@keyword_estimate_requests,
    maxCpc =>
      Google::Ads::AdWords::v201710::Money->new({microAmount => 1000000})});
    

Ruby

# Create ad group estimate requests.
ad_group_request = {
    :keyword_estimate_requests => keyword_requests,
    :max_cpc => {
        :micro_amount => 1000000
    }
}
    

Next, build the CampaignEstimateRequest To get more accurate results, you should also set additional campaign criteria when building the CampaignEstimateRequest, such as location and language. You can also specify existing campaign IDs and ad group IDs in the CampaignEstimateRequest and AdGroupEstimateRequest, which allows the service to load historical data.

Java

// Create campaign estimate requests.
List<CampaignEstimateRequest> campaignEstimateRequests =
    new ArrayList<CampaignEstimateRequest>();
CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest();
campaignEstimateRequest.setAdGroupEstimateRequests(adGroupEstimateRequests
    .toArray(new AdGroupEstimateRequest[] {}));

Location unitedStates = new Location();
unitedStates.setId(2840L);
Language english = new Language();
english.setId(1000L);
campaignEstimateRequest.setCriteria(new Criterion[] {unitedStates, english});
campaignEstimateRequests.add(campaignEstimateRequest);
    

C#

// Create campaign estimate requests.
CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest();
campaignEstimateRequest.adGroupEstimateRequests = new AdGroupEstimateRequest[] {
    adGroupEstimateRequest};

// Optional: Set additional criteria for filtering estimates.
// See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
// for a detailed list of country codes.
Location countryCriterion = new Location();
countryCriterion.id = 2840; //US

// See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
// for a detailed list of language codes.
Language languageCriterion = new Language();
languageCriterion.id = 1000; //en

campaignEstimateRequest.criteria = new Criterion[] { countryCriterion, languageCriterion };
    

Python

# Create campaign estimate requests.
campaign_estimate_requests = [{
    'adGroupEstimateRequests': adgroup_estimate_requests,
    'criteria': [
        {
            'xsi_type': 'Location',
            'id': '2840'  # United States.
        },
        {
            'xsi_type': 'Language',
            'id': '1000'  # English.
        }
    ],
}]
    

PHP

// Create campaign estimate requests.
$campaignEstimateRequest = new CampaignEstimateRequest();
$campaignEstimateRequest->setAdGroupEstimateRequests(
    [$adGroupEstimateRequest]);

// Optional: Set additional criteria for filtering estimates.
// See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
// for a detailed list of country codes.
// Set targeting criteria. Only locations and languages are supported.
$unitedStates = new Location();
$unitedStates->setId(2840);

// See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
// for a detailed list of language codes.
$english = new Language();
$english->setId(1000);

$campaignEstimateRequest->setCriteria([$unitedStates, $english]);
    

Perl

my $location = Google::Ads::AdWords::v201710::Location->new({
    id => "2840"    # US - see http://goo.gl/rlrFr
});
my $language = Google::Ads::AdWords::v201710::Language->new({
    id => "1000"    # en - see http://goo.gl/LvMmS
});

# Create campaign estimate requests.
my $campaign_estimate_request =
  Google::Ads::AdWords::v201710::CampaignEstimateRequest->new({
    adGroupEstimateRequests => [$ad_group_estimate_request],
    criteria                => [$location, $language]});
    

Ruby

# Create campaign estimate requests.
campaign_request = {
    :ad_group_estimate_requests => [ad_group_request],
    # Set targeting criteria. Only locations and languages are supported.
    :criteria => [
        {:xsi_type => 'Location', :id => 2840}, # United States
        {:xsi_type => 'Language', :id => 1000}  # English
    ]
}
    

Finally, configure the TrafficEstimatorSelector. You can then send it through the get() operation to retrieve the traffic estimates encapsulated in the TrafficEstimatorResult object. You can request a list of campaign-level estimates segmented by platform using the platformEstimateRequested property.

Java

// Create selector.
TrafficEstimatorSelector selector = new TrafficEstimatorSelector();
selector.setCampaignEstimateRequests(campaignEstimateRequests
    .toArray(new CampaignEstimateRequest[] {}));

// Optional: Request a list of campaign level estimates segmented by platform.
selector.setPlatformEstimateRequested(true);

// Get traffic estimates.
TrafficEstimatorResult result = trafficEstimatorService.get(selector);
    

C#

// Create the selector.
TrafficEstimatorSelector selector = new TrafficEstimatorSelector() {
  campaignEstimateRequests = new CampaignEstimateRequest[] { campaignEstimateRequest },

  // Optional: Request a list of campaign level estimates segmented by platform.
  platformEstimateRequested = true
};

// Get traffic estimates.
TrafficEstimatorResult result = trafficEstimatorService.get(selector);
    

Python

# Create the selector.
selector = {
    'campaignEstimateRequests': campaign_estimate_requests,
}

# Optional: Request a list of campaign-level estimates segmented by
# platform.
selector['platformEstimateRequested'] = True

# Get traffic estimates.
estimates = traffic_estimator_service.get(selector)
    

PHP

// Create selector.
$selector = new TrafficEstimatorSelector();
$selector->setCampaignEstimateRequests([$campaignEstimateRequest]);

// Optional: Request a list of campaign level estimates segmented by
// platform.
$selector->setPlatformEstimateRequested(true);

$result = $trafficEstimatorService->get($selector);
    

Perl

# Optional: Request a list of campaign level estimates segmented by platform.
my $platform_estimate_request = "1";

# Create selector.
my $selector = Google::Ads::AdWords::v201710::TrafficEstimatorSelector->new({
    campaignEstimateRequests  => [$campaign_estimate_request],
    platformEstimateRequested => [$platform_estimate_request]});

# Get traffic estimates.
my $result = $client->TrafficEstimatorService()->get({selector => $selector});
    

Ruby

# Create a selector.
selector = {
  :campaign_estimate_requests => [campaign_request],
  # Optional: Request a list of campaign level estimates segmented by
  # platform.
  :platform_estimate_requested => true
}

# Execute the request.
response = traffic_estimator_srv.get(selector)
    

Process the response

Each CampaignEstimateRequest object in the selector generates a corresponding CampaignEstimate object in the TrafficEstimatorResult. Similarly, each AdGroupEstimateRequest object will have a corresponding AdGroupEstimate object in the result. If you requested campaign-level estimates segmented by platform, they'll be available through the platformEstimates property of the CampaignEstimate object.

Java

// Display traffic estimates.
if (result != null
    && result.getCampaignEstimates() != null
    && result.getCampaignEstimates().length > 0) {
  CampaignEstimate campaignEstimate = result.getCampaignEstimates()[0];

  // Display the campaign level estimates segmented by platform.
  if (campaignEstimate.getPlatformEstimates() != null) {
    for (PlatformCampaignEstimate platformEstimate : campaignEstimate.getPlatformEstimates()) {
      String platformMessage =
          String.format(
              "Results for the platform with ID %d and name '%s':%n",
              platformEstimate.getPlatform().getId(),
              platformEstimate.getPlatform().getPlatformName());
      displayMeanEstimates(
          platformMessage,
          platformEstimate.getMinEstimate(),
          platformEstimate.getMaxEstimate());
    }
  }

  // Display the keyword estimates.
  KeywordEstimate[] keywordEstimates =
      campaignEstimate.getAdGroupEstimates()[0].getKeywordEstimates();
  for (int i = 0; i < keywordEstimates.length; i++) {
    if (Boolean.TRUE.equals(keywordEstimateRequests.get(i).getIsNegative())) {
      continue;
    }

    Keyword keyword = keywordEstimateRequests.get(i).getKeyword();
    KeywordEstimate keywordEstimate = keywordEstimates[i];

    String keywordMessage =
        String.format(
            "Results for the keyword with text '%s' and match type '%s':%n",
            keyword.getText(), keyword.getMatchType());
    displayMeanEstimates(keywordMessage, keywordEstimate.getMin(), keywordEstimate.getMax());
  }
} else {
  System.out.println("No traffic estimates were returned.");
}
    

C#

// Display traffic estimates.
if (result != null && result.campaignEstimates != null &&
    result.campaignEstimates.Length > 0) {
  CampaignEstimate campaignEstimate = result.campaignEstimates[0];

  // Display the campaign level estimates segmented by platform.
  if (campaignEstimate.platformEstimates != null) {
    foreach (PlatformCampaignEstimate platformEstimate in
        campaignEstimate.platformEstimates) {
      string platformMessage = string.Format("Results for the platform with ID: " +
          "{0} and name : {1}.", platformEstimate.platform.id,
          platformEstimate.platform.platformName);

      DisplayMeanEstimates(platformMessage, platformEstimate.minEstimate,
          platformEstimate.maxEstimate);
    }
  }

  // Display the keyword estimates.
  if (campaignEstimate.adGroupEstimates != null &&
      campaignEstimate.adGroupEstimates.Length > 0) {
    AdGroupEstimate adGroupEstimate = campaignEstimate.adGroupEstimates[0];

    if (adGroupEstimate.keywordEstimates != null) {
      for (int i = 0; i < adGroupEstimate.keywordEstimates.Length; i++) {
        Keyword keyword = keywordEstimateRequests[i].keyword;
        KeywordEstimate keywordEstimate = adGroupEstimate.keywordEstimates[i];

        if (keywordEstimateRequests[i].isNegative) {
          continue;
        }
        string kwdMessage = string.Format("Results for the keyword with text = '{0}' " +
            "and match type = '{1}':", keyword.text, keyword.matchType);
        DisplayMeanEstimates(kwdMessage, keywordEstimate.min, keywordEstimate.max);
      }
    }
  }
} else {
  Console.WriteLine("No traffic estimates were returned.");
}
trafficEstimatorService.Close();
    

Python

campaign_estimate = estimates['campaignEstimates'][0]

# Display the campaign level estimates segmented by platform.
if 'platformEstimates' in campaign_estimate:
  platform_template = ('Results for the platform with ID: "%d" and name: '
                       '"%s".')
  for platform_estimate in campaign_estimate['platformEstimates']:
    platform = platform_estimate['platform']
    DisplayEstimate(platform_template % (platform['id'],
                                         platform['platformName']),
                    platform_estimate['minEstimate'],
                    platform_estimate['maxEstimate'])

# Display the keyword estimates.
if 'adGroupEstimates' in campaign_estimate:
  ad_group_estimate = campaign_estimate['adGroupEstimates'][0]
  if 'keywordEstimates' in ad_group_estimate:
    keyword_estimates = ad_group_estimate['keywordEstimates']
    keyword_template = ('Results for the keyword with text "%s" and match '
                        'type "%s":')

    keyword_estimates_and_requests = zip(keyword_estimates,
                                         keyword_estimate_requests)

    for keyword_tuple in keyword_estimates_and_requests:
      if keyword_tuple[1].get('isNegative', False):
        continue
      keyword = keyword_tuple[1]['keyword']
      keyword_estimate = keyword_tuple[0]
      DisplayEstimate(keyword_template % (keyword['text'],
                                          keyword['matchType']),
                      keyword_estimate['min'], keyword_estimate['max'])
    

PHP

$platformEstimates =
    $result->getCampaignEstimates()[0]->getPlatformEstimates();
if ($platformEstimates !== null) {
  foreach ($platformEstimates as $platformEstimate) {
    if ($platformEstimate->getMinEstimate() !== null
        && $platformEstimate->getMaxEstimate() !== null) {
      printf(
          "Results for the platform with ID %d and name '%s':\n",
          $platformEstimate->getPlatform()->getId(),
          $platformEstimate->getPlatform()->getPlatformName()
      );
      self::printMeanEstimate($platformEstimate->getMinEstimate(),
          $platformEstimate->getMaxEstimate());
    }
  }
}

$keywordEstimates = $result
    ->getCampaignEstimates()[0]
    ->getAdGroupEstimates()[0]
    ->getKeywordEstimates();
$estimatesCount = count($keywordEstimates);
for ($i = 0; $i < $estimatesCount; $i++) {
  $keywordEstimateRequest = $keywordEstimateRequests[$i];
  // Skip negative keywords, since they don't return estimates.
  if ($keywordEstimateRequest->getIsNegative() !== true) {
    $keyword = $keywordEstimateRequest->getKeyword();
    $keywordEstimate = $keywordEstimates[$i];

    if ($keywordEstimate->getMin() !== null
        && $keywordEstimate->getMax() !== null) {
      // Print the mean of the min and max values.
      printf(
          "Results for the keyword with text '%s' and match type '%s':\n",
          $keyword->getText(),
          $keyword->getMatchType()
      );
      self::printMeanEstimate($keywordEstimate->getMin(),
          $keywordEstimate->getMax());
    }
  }
}
    

Perl

# Display traffic estimates.
if ($result) {
  my $campaign_estimates = $result->get_campaignEstimates();
  if ($campaign_estimates) {
    # Display the campaign level estimates segmented by platform.
    foreach my $campaign_estimate (@{$campaign_estimates}) {
      if ($campaign_estimate->get_platformEstimates()) {
        foreach
          my $platform_estimate (@{$campaign_estimate->get_platformEstimates()})
        {
          my $platform_message = sprintf(
            "Results for the platform with ID: %d and name : %s",
            $platform_estimate->get_platform()->get_id(),
            $platform_estimate->get_platform()->get_platformName());
          display_mean_estimates(
            $platform_message,
            $platform_estimate->get_minEstimate(),
            $platform_estimate->get_maxEstimate());
        }
      }

      if ($campaign_estimate->get_adGroupEstimates()) {
        my $keyword_estimates =
          $campaign_estimate->get_adGroupEstimates()->[0]
          ->get_keywordEstimates();
        for (my $i = 0 ; $i < scalar(@{$keyword_estimates}) ; $i++) {
          # Negative keywords don't generate estimates but instead affect
          # estimates of your other keywords, the following condition just
          # skips printing out estimates for a negative keyword.
          if ($keyword_estimate_requests[$i]->get_isNegative()) {
            next;
          }

          my $keyword = $keyword_estimate_requests[$i]->get_keyword();
          my $keyword_estimate = $keyword_estimates->[$i];
          my $keyword_message =
            sprintf
            "Results for the keyword with text '%s' and match type '%s':\n",
            $keyword->get_text(), $keyword->get_matchType();
          display_mean_estimates(
            $keyword_message,
            $keyword_estimate->get_min(),
            $keyword_estimate->get_max());
        }
      }
    }
  }
    

Ruby

# Display traffic estimates.
if response and response[:campaign_estimates] and
    response[:campaign_estimates].size > 0
  campaign_estimate = response[:campaign_estimates].first

  unless campaign_estimate[:platform_estimates].nil?
    # Display the campaign level estimates segmented by platform.
    campaign_estimate[:platform_estimates].each do |platform_estimate|
      platform_message = ('Results for the platform with ID %d and name ' +
          '"%s":') % [platform_estimate[:platform][:id],
          platform_estimate[:platform][:platform_name]]
      display_mean_estimates(
          platform_message,
          platform_estimate[:min_estimate],
          platform_estimate[:max_estimate]
      )
    end
  end

  # Display the keyword estimates.
  keyword_estimates =
      campaign_estimate[:ad_group_estimates].first[:keyword_estimates]
  keyword_estimates.each_with_index do |keyword_estimate, index|
    next if keyword_requests[index][:is_negative]
    keyword = keyword_requests[index][:keyword]

    keyword_message = ('Results for the keyword with text "%s" and match ' +
        'type "%s":') % [keyword[:text], keyword[:match_type]]
    display_mean_estimates(
        keyword_message,
        keyword_estimate[:min],
        keyword_estimate[:max]
    )
  end
else
  puts 'No traffic estimates were returned.'
end
    

The most important and interesting result object is the corresponding KeywordEstimate object within the AdGroupEstimate. It contains the lower bound (min) and upper bound (max) of the traffic estimation (StatsEstimate) for each keyword.

Bear in mind that the returned values are estimates, and are not a guarantee that actual performance will be within these bounds.

Calculating estimated total conversion value

The API doesn't directly provide an estimated total conversion value like the Keyword Planner, but you can calculate one from the stats provided:

Estimated total conversions = Estimated clicks * Historical conversion rate
Estimated total conversion value = Estimated total conversions * Conversion value

Mapping to the Keyword Planner

You can use the TrafficEstimatorService like you use Enter or upload a list of keywords to get forecasts in the AdWords Keyword Planner.

To use the TrafficEstimatorService for this, you need to specify either a pre-existing campaign, or create a mock campaign, complete with ad groups and keywords:

Keyword Planner AdWords API
Enter Keywords KeywordEstimateRequest
Targeting - Location Use the Location criterion in CampaignEstimateRequest.criteria
Targeting - Language Use the Language criterion in CampaignEstimateRequest.criteria
Targeting - Network CampaignEstimateRequest.networkSetting
Date Range Not Supported

In the Keyword Planner, you can specify a daily budget and a bid amount. In the AdWords API, a dailyBudget is part of the CampaignEstimateRequest, and the bid amount, called maxCpc, can be set either in the AdGroupEstimateRequest or the KeywordEstimateRequest. These must be specified at request time; so even though they're on the Results screen of the Keyword Planner, they must be included as part of the request when using the API.

Complete code examples

Each client library contains a complete code example in its Optimization folder:

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.