Generate a Reach Curve

Once you've gathered the targeting settings and a product mix for your media plan, you can generate a curve of budgets versus potential reach using the GenerateReachForecast method in ReachPlanService . See the glossary and media plan guide for details on the request fields.

Save curves

You can only save individual curves to provide convenience for your users. Caching curves en masse is strictly prohibited. If you do need to generate curves en masse, check first with your Google representative.

Changes for YouTube Select

YouTube Select (YTS) in Reach Plan Service now supports lineup-level targeting, as compared to Run-of-Network previously, for all eligible YTS locations on Instant Reserve pricing. With Instant Reserve, these errors may also occur when requesting a forecast for YTS:

  1. Not enough inventory available
  2. Non-spending accounts disabled

Forecast reach for Demand Gen

When generating curves for DEMAND_GEN plannable products, you must also include an expected conversion rate for each product.

To obtain conversion rate suggestions for supported plannable products, use the GenerateConversionRates method.

Code example

The curve includes impression and user reach in absolute numbers, as well as universe sizes corresponding to the census population and YouTube audience size for the requested demographic and country.

Java

 private 
  
 void 
  
 getReachCurve 
 ( 
  
 ReachPlanServiceClient 
  
 reachPlanServiceClient 
 , 
  
 GenerateReachForecastRequest 
  
 request 
 ) 
  
 { 
  
 GenerateReachForecastResponse 
  
 response 
  
 = 
  
 reachPlanServiceClient 
 . 
 generateReachForecast 
 ( 
 request 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
 "Reach curve output:" 
 ); 
  
 System 
 . 
 out 
 . 
 println 
 ( 
  
 "Currency, Cost Micros, On-Target Reach, On-Target Imprs, Total Reach, Total Imprs," 
  
 + 
  
 " Products" 
 ); 
  
 for 
  
 ( 
 ReachForecast 
  
 point 
  
 : 
  
 response 
 . 
 getReachCurve 
 (). 
 getReachForecastsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "%s, \"" 
 , 
  
 Joiner 
 . 
 on 
 ( 
 ", " 
 ) 
  
 . 
 join 
 ( 
  
 request 
 . 
 getCurrencyCode 
 (), 
  
 String 
 . 
 valueOf 
 ( 
 point 
 . 
 getCostMicros 
 ()), 
  
 String 
 . 
 valueOf 
 ( 
 point 
 . 
 getForecast 
 (). 
 getOnTargetReach 
 ()), 
  
 String 
 . 
 valueOf 
 ( 
 point 
 . 
 getForecast 
 (). 
 getOnTargetImpressions 
 ()), 
  
 String 
 . 
 valueOf 
 ( 
 point 
 . 
 getForecast 
 (). 
 getTotalReach 
 ()), 
  
 String 
 . 
 valueOf 
 ( 
 point 
 . 
 getForecast 
 (). 
 getTotalImpressions 
 ()))); 
  
 for 
  
 ( 
 PlannedProductReachForecast 
  
 product 
  
 : 
  
 point 
 . 
 getPlannedProductReachForecastsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "[Product: %s, " 
 , 
  
 product 
 . 
 getPlannableProductCode 
 ()); 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "Budget Micros: %s]" 
 , 
  
 product 
 . 
 getCostMicros 
 ()); 
  
 } 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
 "\"%n" 
 ); 
  
 } 
 } 
  
  

C#

 public 
  
 void 
  
 GetReachCurve 
 ( 
 ReachPlanServiceClient 
  
 reachPlanService 
 , 
  
 GenerateReachForecastRequest 
  
 request 
 ) 
 { 
  
 GenerateReachForecastResponse 
  
 response 
  
 = 
  
 reachPlanService 
 . 
 GenerateReachForecast 
 ( 
  
 request 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "Reach curve output:" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
  
 "Currency, Cost Micros, On-Target Reach, On-Target Impressions, Total Reach," 
  
 + 
  
 " Total Impressions, Products" 
 ); 
  
 foreach 
  
 ( 
 ReachForecast 
  
 point 
  
 in 
  
 response 
 . 
 ReachCurve 
 . 
 ReachForecasts 
 ) 
  
 { 
  
 Console 
 . 
 Write 
 ( 
 $"{request.CurrencyCode}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"{point.CostMicros}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"{point.Forecast.OnTargetReach}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"{point.Forecast.OnTargetImpressions}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"{point.Forecast.TotalReach}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"{point.Forecast.TotalImpressions}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 "\"[" 
 ); 
  
 foreach 
  
 ( 
 PlannedProductReachForecast 
  
 productReachForecast 
  
 in 
  
 point 
 . 
 PlannedProductReachForecasts 
 ) 
  
 { 
  
 Console 
 . 
 Write 
 ( 
 $"(Product: {productReachForecast.PlannableProductCode}, " 
 ); 
  
 Console 
 . 
 Write 
 ( 
 $"Budget Micros: {productReachForecast.CostMicros}), " 
 ); 
  
 } 
  
 Console 
 . 
 WriteLine 
 ( 
 "]\"" 
 ); 
  
 } 
 } 
  
  

PHP

 private static function getReachCurve( 
 GoogleAdsClient $googleAdsClient, 
 int $customerId, 
 array $productMix, 
 string $locationId, 
 string $currencyCode 
 ) { 
 // Valid durations are between 1 and 90 days. 
 $duration = new CampaignDuration(['duration_in_days' => 28]); 
 $targeting = new Targeting([ 
 'plannable_location_id' => $locationId, 
 'age_range' => ReachPlanAgeRange::AGE_RANGE_18_65_UP, 
 'genders' => [ 
 new GenderInfo(['type' => GenderType::FEMALE]), 
 new GenderInfo(['type' => GenderType::MALE]) 
 ], 
 'devices' => [ 
 new DeviceInfo(['type' => Device::DESKTOP]), 
 new DeviceInfo(['type' => Device::MOBILE]), 
 new DeviceInfo(['type' => Device::TABLET]) 
 ] 
 ]); 
 // See the docs for defaults and valid ranges: 
 // https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest 
 $response = $googleAdsClient->getReachPlanServiceClient()->generateReachForecast( 
 GenerateReachForecastRequest::build($customerId, $duration, $productMix) 
 ->setCurrencyCode($currencyCode) 
 ->setTargeting($targeting) 
 ); 
 printf( 
 "Reach curve output:%sCurrency, Cost Micros, On-Target Reach, On-Target Imprs," . 
 " Total Reach, Total Imprs, Products%s", 
 PHP_EOL, 
 PHP_EOL 
 ); 
 foreach ($response->getReachCurve()->getReachForecasts() as $point) { 
 $products = ''; 
 /** @var ReachForecast $point */ 
 foreach ($point->getPlannedProductReachForecasts() as $plannedProductReachForecast) { 
 /** @var PlannedProductReachForecast $plannedProductReachForecast */ 
 $products .= sprintf( 
 '(Product: %s, Budget Micros: %s)', 
 $plannedProductReachForecast->getPlannableProductCode(), 
 $plannedProductReachForecast->getCostMicros() 
 ); 
 } 
 printf( 
 "%s, %d, %d, %d, %d, %d, %s%s", 
 $currencyCode, 
 $point->getCostMicros(), 
 $point->getForecast()->getOnTargetReach(), 
 $point->getForecast()->getOnTargetImpressions(), 
 $point->getForecast()->getTotalReach(), 
 $point->getForecast()->getTotalImpressions(), 
 $products, 
 PHP_EOL 
 ); 
 } 
 }  
 

Python

 def 
  
 request_reach_curve 
 ( 
 client 
 : 
 GoogleAdsClient 
 , 
 customer_id 
 : 
 str 
 , 
 product_mix 
 : 
 list 
 [ 
 PlannedProduct 
 ], 
 location_id 
 : 
 str 
 , 
 currency_code 
 : 
 str 
 , 
 ): 
  
 """Creates a sample request for a given product mix. 
 Args: 
 client: an initialized GoogleAdsClient instance. 
 customer_id: The customer ID for the reach forecast. 
 product_mix: The product mix for the reach forecast. 
 location_id: The location ID to plan for. 
 currency_code: Three-character ISO 4217 currency code. 
 """ 
 # See the docs for defaults and valid ranges: 
 # https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest 
 request 
 : 
 GenerateReachForecastRequest 
 = 
 client 
 . 
 get_type 
 ( 
 "GenerateReachForecastRequest" 
 ) 
 request 
 . 
 customer_id 
 = 
 customer_id 
 # Valid durations are between 1 and 90 days. 
 request 
 . 
 campaign_duration 
 . 
 duration_in_days 
 = 
 28 
 request 
 . 
 currency_code 
 = 
 currency_code 
 request 
 . 
 cookie_frequency_cap 
 = 
 0 
 request 
 . 
 min_effective_frequency 
 = 
 1 
 request 
 . 
 planned_products 
 = 
 product_mix 
 request 
 . 
 targeting 
 . 
 plannable_location_id 
 = 
 location_id 
 request 
 . 
 targeting 
 . 
 age_range 
 = 
 ( 
 client 
 . 
 enums 
 . 
 ReachPlanAgeRangeEnum 
 . 
 AGE_RANGE_18_65_UP 
 ) 
 # Add gender targeting to the request. 
 gender_type 
 : 
 GenderTypeEnum 
 for 
 gender_type 
 in 
 [ 
 client 
 . 
 enums 
 . 
 GenderTypeEnum 
 . 
 FEMALE 
 , 
 client 
 . 
 enums 
 . 
 GenderTypeEnum 
 . 
 MALE 
 , 
 ]: 
 gender 
 : 
 GenderInfo 
 = 
 client 
 . 
 get_type 
 ( 
 "GenderInfo" 
 ) 
 gender 
 . 
 type_ 
 = 
 gender_type 
 request 
 . 
 targeting 
 . 
 genders 
 . 
 append 
 ( 
 gender 
 ) 
 # Add device targeting to the request. 
 device_type 
 : 
 DeviceEnum 
 for 
 device_type 
 in 
 [ 
 client 
 . 
 enums 
 . 
 DeviceEnum 
 . 
 DESKTOP 
 , 
 client 
 . 
 enums 
 . 
 DeviceEnum 
 . 
 MOBILE 
 , 
 client 
 . 
 enums 
 . 
 DeviceEnum 
 . 
 TABLET 
 , 
 ]: 
 device 
 : 
 DeviceInfo 
 = 
 client 
 . 
 get_type 
 ( 
 "DeviceInfo" 
 ) 
 device 
 . 
 type_ 
 = 
 device_type 
 request 
 . 
 targeting 
 . 
 devices 
 . 
 append 
 ( 
 device 
 ) 
 reach_plan_service 
 : 
 ReachPlanServiceClient 
 = 
 client 
 . 
 get_service 
 ( 
 "ReachPlanService" 
 ) 
 response 
 : 
 GenerateReachForecastResponse 
 = 
 ( 
 reach_plan_service 
 . 
 generate_reach_forecast 
 ( 
 request 
 = 
 request 
 ) 
 ) 
 print 
 ( 
 "Currency, Cost, On-Target Reach, On-Target Imprs, Total Reach," 
 " Total Imprs, Products" 
 ) 
 point 
 : 
 ReachForecast 
 for 
 point 
 in 
 response 
 . 
 reach_curve 
 . 
 reach_forecasts 
 : 
 product_splits 
 = 
 [] 
 p 
 : 
 PlannedProductReachForecast 
 for 
 p 
 in 
 point 
 . 
 planned_product_reach_forecasts 
 : 
 product_splits 
 . 
 append 
 ( 
 { 
 p 
 . 
 plannable_product_code 
 : 
 p 
 . 
 cost_micros 
 / 
 ONE_MILLION 
 } 
 ) 
 print 
 ( 
 [ 
 currency_code 
 , 
 point 
 . 
 cost_micros 
 / 
 ONE_MILLION 
 , 
 point 
 . 
 forecast 
 . 
 on_target_reach 
 , 
 point 
 . 
 forecast 
 . 
 on_target_impressions 
 , 
 point 
 . 
 forecast 
 . 
 total_reach 
 , 
 point 
 . 
 forecast 
 . 
 total_impressions 
 , 
 product_splits 
 , 
 ] 
 ) 
  

Ruby

 def 
  
 get_reach_curve 
 ( 
  
 client 
 , 
  
 reach_plan_service 
 , 
  
 customer_id 
 , 
  
 product_mix 
 , 
  
 location_id 
 , 
  
 currency_code 
 ) 
  
 duration 
  
 = 
  
 client 
 . 
 resource 
 . 
 campaign_duration 
  
 do 
  
 | 
 d 
 | 
  
 # Valid durations are between 1 and 90 days. 
  
 d 
 . 
 duration_in_days 
  
 = 
  
 28 
  
 end 
  
 targeting 
  
 = 
  
 client 
 . 
 resource 
 . 
 targeting 
  
 do 
  
 | 
 t 
 | 
  
 t 
 . 
 plannable_location_id 
  
 = 
  
 location_id 
  
 t 
 . 
 age_range 
  
 = 
  
 :AGE_RANGE_18_65_UP 
  
 t 
 . 
 genders 
 << 
 client 
 . 
 resource 
 . 
 gender_info 
  
 do 
  
 | 
 gender 
 | 
  
 gender 
 . 
 type 
  
 = 
  
 :FEMALE 
  
 end 
  
 t 
 . 
 genders 
 << 
 client 
 . 
 resource 
 . 
 gender_info 
  
 do 
  
 | 
 gender 
 | 
  
 gender 
 . 
 type 
  
 = 
  
 :MALE 
  
 end 
  
 t 
 . 
 devices 
 << 
 client 
 . 
 resource 
 . 
 device_info 
  
 do 
  
 | 
 device 
 | 
  
 device 
 . 
 type 
  
 = 
  
 :DESKTOP 
  
 end 
  
 t 
 . 
 devices 
 << 
 client 
 . 
 resource 
 . 
 device_info 
  
 do 
  
 | 
 device 
 | 
  
 device 
 . 
 type 
  
 = 
  
 :MOBILE 
  
 end 
  
 t 
 . 
 devices 
 << 
 client 
 . 
 resource 
 . 
 device_info 
  
 do 
  
 | 
 device 
 | 
  
 device 
 . 
 type 
  
 = 
  
 :TABLET 
  
 end 
  
 end 
  
 # See the docs for defaults and valid ranges: 
  
 # https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest 
  
 response 
  
 = 
  
 reach_plan_service 
 . 
 generate_reach_forecast 
 ( 
  
 customer_id 
 : 
  
 customer_id 
 , 
  
 campaign_duration 
 : 
  
 duration 
 , 
  
 planned_products 
 : 
  
 product_mix 
 , 
  
 currency_code 
 : 
  
 currency_code 
 , 
  
 targeting 
 : 
  
 targeting 
 , 
  
 ) 
  
 puts 
  
 "Reach curve output:" 
  
 puts 
  
 "Currency, Cost Micros, On-Target Reach, On-Target Imprs, " 
  
 \ 
  
 "Total Reach, Total Imprs, Products" 
  
 response 
 . 
 reach_curve 
 . 
 reach_forecasts 
 . 
 each 
  
 do 
  
 | 
 point 
 | 
  
 products 
  
 = 
  
 "" 
  
 point 
 . 
 planned_product_reach_forecasts 
 . 
 each 
  
 do 
  
 | 
 product 
 | 
  
 products 
  
 += 
  
 "(Product: 
 #{ 
 product 
 . 
 plannable_product_code 
 } 
 , " 
 \ 
  
 "Cost Micros: 
 #{ 
 product 
 . 
 cost_micros 
 } 
 )" 
  
 end 
  
 puts 
  
 " 
 #{ 
 currency_code 
 } 
 , 
 #{ 
 point 
 . 
 cost_micros 
 } 
 , " 
  
 \ 
  
 " 
 #{ 
 point 
 . 
 forecast 
 . 
 on_target_reach 
 } 
 , " 
  
 \ 
  
 " 
 #{ 
 point 
 . 
 forecast 
 . 
 on_target_impressions 
 } 
 , " 
  
 \ 
  
 " 
 #{ 
 point 
 . 
 forecast 
 . 
 total_reach 
 } 
 , " 
  
 \ 
  
 " 
 #{ 
 point 
 . 
 forecast 
 . 
 total_impressions 
 } 
 , " 
  
 \ 
  
 " 
 #{ 
 products 
 } 
 " 
  
 end 
 end  
 
 . 
 rb 
  

Perl

 sub 
  
 pull_reach_curve 
  
 { 
  
 my 
  
 ( 
 $reach_plan_service 
 , 
  
 $reach_request 
 ) 
  
 = 
  
 @_ 
 ; 
  
 my 
  
 $response 
  
 = 
  
 $reach_plan_service 
 - 
> generate_reach_forecast 
 ( 
 $reach_request 
 ); 
  
 print 
  
 "Reach curve output:\n" 
 ; 
  
 print 
  
 "Currency,\tCost Micros,\tOn-Target Reach,\tOn-Target Imprs,\t" 
  
 . 
  
 "Total Reach,\tTotal Imprs,\tProducts\n" 
 ; 
  
 foreach 
  
 my 
  
 $point 
  
 ( 
 @ 
 { 
 $response 
 - 
> { 
 reachCurve 
 }{ 
 reachForecasts 
 }}) 
  
 { 
  
 printf 
  
 "%s,\t%d,\t%d,\t%d,\t%d,\t%d,\t'[" 
 , 
  
 $reach_request 
 - 
> { 
 currencyCode 
 }, 
  
 $point 
 - 
> { 
 costMicros 
 }, 
  
 $point 
 - 
> { 
 forecast 
 }{ 
 onTargetReach 
 }, 
  
 $point 
 - 
> { 
 forecast 
 }{ 
 onTargetImpressions 
 }, 
  
 $point 
 - 
> { 
 forecast 
 }{ 
 totalReach 
 }, 
  
 $point 
 - 
> { 
 forecast 
 }{ 
 totalImpressions 
 }; 
  
 foreach 
  
 my 
  
 $productReachForecast 
  
 ( 
 @ 
 { 
 $point 
 - 
> { 
 plannedProductReachForecasts 
 }}) 
  
 { 
  
 printf 
  
 "(Product: %s, Budget Micros: %d), " 
 , 
  
 $productReachForecast 
 - 
> { 
 plannableProductCode 
 }, 
  
 $productReachForecast 
 - 
> { 
 costMicros 
 }; 
  
 } 
  
 print 
  
 "]'\n" 
 ; 
  
 } 
 } 
  
  
Design a Mobile Site
View Site in Mobile | Classic
Share by: