Client library for the Google Ads API providing comprehensive access to advertising management, reporting, and analytics capabilities.
—
Keyword research, planning, and management including keyword plan creation, keyword idea generation, shared keyword sets, and advanced targeting configurations. The Google Ads API provides comprehensive capabilities for keyword research, competitive analysis, and targeting optimization.
Keyword planning operations for research, forecasting, and planning keyword strategies including competitive analysis and traffic estimation.
def mutate_keyword_plans(
self,
request: Optional[MutateKeywordPlansRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[KeywordPlanOperation]] = None,
partial_failure: bool = False,
validate_only: bool = False
) -> MutateKeywordPlansResponse:
"""
Create, update, or remove keyword plans.
Args:
request: The request object
customer_id: Required customer ID
operations: List of keyword plan operations
partial_failure: Continue on individual failures
validate_only: Validate without executing
Returns:
MutateKeywordPlansResponse with results
"""
def generate_forecast_curve(
self,
request: Optional[GenerateForecastCurveRequest] = None,
keyword_plan: Optional[str] = None
) -> GenerateForecastCurveResponse:
"""
Generate forecast curve for a keyword plan.
Args:
request: The request object
keyword_plan: Keyword plan resource name
Returns:
Forecast curve with traffic and cost projections
"""
def generate_forecast_timeline(
self,
request: Optional[GenerateForecastTimelineRequest] = None,
keyword_plan: Optional[str] = None
) -> GenerateForecastTimelineResponse:
"""
Generate forecast timeline for a keyword plan.
Args:
request: The request object
keyword_plan: Keyword plan resource name
Returns:
Timeline forecast with weekly projections
"""
def generate_forecast_metrics(
self,
request: Optional[GenerateForecastMetricsRequest] = None,
keyword_plan: Optional[str] = None
) -> GenerateForecastMetricsResponse:
"""
Generate forecast metrics for a keyword plan.
Args:
request: The request object
keyword_plan: Keyword plan resource name
Returns:
Forecast metrics including clicks, impressions, and costs
"""Keyword research and idea generation operations for discovering new keyword opportunities, competitive analysis, and search volume data.
def generate_keyword_ideas(
self,
request: Optional[GenerateKeywordIdeasRequest] = None,
customer_id: Optional[str] = None,
language: Optional[str] = None,
geo_target_constants: Optional[Sequence[str]] = None,
keyword_plan_network: Optional[KeywordPlanNetworkEnum.KeywordPlanNetwork] = None,
keyword_annotation: Optional[Sequence[KeywordAnnotationEnum.KeywordAnnotation]] = None
) -> GenerateKeywordIdeasResponse:
"""
Generate keyword ideas based on seed keywords or URLs.
Args:
request: The request object
customer_id: Required customer ID
language: Language for keyword ideas
geo_target_constants: Geographic targeting
keyword_plan_network: Network for keyword planning
keyword_annotation: Additional keyword annotations
Returns:
GenerateKeywordIdeasResponse with keyword suggestions
"""
def generate_keyword_historical_metrics(
self,
request: Optional[GenerateKeywordHistoricalMetricsRequest] = None,
customer_id: Optional[str] = None,
keywords: Optional[Sequence[str]] = None,
language: Optional[str] = None,
geo_target_constants: Optional[Sequence[str]] = None,
keyword_plan_network: Optional[KeywordPlanNetworkEnum.KeywordPlanNetwork] = None
) -> GenerateKeywordHistoricalMetricsResponse:
"""
Get historical metrics for specific keywords.
Args:
request: The request object
customer_id: Required customer ID
keywords: List of keywords to analyze
language: Language for metrics
geo_target_constants: Geographic targeting
keyword_plan_network: Network for metrics
Returns:
Historical metrics including search volume and competition
"""
def generate_ad_group_themes(
self,
request: Optional[GenerateAdGroupThemesRequest] = None,
customer_id: Optional[str] = None,
keywords: Optional[Sequence[str]] = None,
ad_groups: Optional[Sequence[str]] = None
) -> GenerateAdGroupThemesResponse:
"""
Generate ad group themes for keyword organization.
Args:
request: The request object
customer_id: Required customer ID
keywords: Keywords to organize into themes
ad_groups: Existing ad groups for theme analysis
Returns:
Suggested ad group themes and keyword groupings
"""Shared keyword set operations for managing negative keyword lists and other shared targeting criteria across multiple campaigns and ad groups.
def mutate_shared_sets(
self,
request: Optional[MutateSharedSetsRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[SharedSetOperation]] = None,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: Optional[ResponseContentTypeEnum.ResponseContentType] = None
) -> MutateSharedSetsResponse:
"""
Create, update, or remove shared sets.
Args:
request: The request object
customer_id: Required customer ID
operations: List of shared set operations
partial_failure: Continue on individual failures
validate_only: Validate without executing
response_content_type: Response content type
Returns:
MutateSharedSetsResponse with results
"""
def mutate_shared_criteria(
self,
request: Optional[MutateSharedCriteriaRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[SharedCriterionOperation]] = None,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: Optional[ResponseContentTypeEnum.ResponseContentType] = None
) -> MutateSharedCriteriaResponse:
"""
Create, update, or remove shared criteria.
Args:
request: The request object
customer_id: Required customer ID
operations: List of shared criterion operations
partial_failure: Continue on individual failures
validate_only: Validate without executing
response_content_type: Response content type
Returns:
MutateSharedCriteriaResponse with results
"""Geographic and location targeting operations including geo target constants, location views, and proximity targeting configurations.
def get_geo_target_constant(
self,
request: Optional[GetGeoTargetConstantRequest] = None,
resource_name: Optional[str] = None
) -> GeoTargetConstant:
"""
Retrieve geographic target constant information.
Args:
request: The request object
resource_name: Geo target constant resource name
Returns:
GeoTargetConstant with location details
"""
def suggest_geo_target_constants(
self,
request: Optional[SuggestGeoTargetConstantsRequest] = None,
locale: Optional[str] = None,
country_code: Optional[str] = None
) -> SuggestGeoTargetConstantsResponse:
"""
Suggest geographic target constants based on location names.
Args:
request: The request object
locale: Locale for suggestions
country_code: Country code for suggestions
Returns:
Suggested geographic target constants
"""from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
import datetime
def create_keyword_plan(client, customer_id, plan_name):
"""Create a keyword plan for keyword research and forecasting."""
keyword_plan_service = client.get_service("KeywordPlanService")
# Create keyword plan
operation = client.get_type("KeywordPlanOperation")
keyword_plan = operation.create
keyword_plan.name = plan_name
# Set forecast period (next 12 months)
forecast_period = keyword_plan.forecast_period
forecast_period.date_interval = client.enums.KeywordPlanForecastIntervalEnum.NEXT_QUARTER
try:
response = keyword_plan_service.mutate_keyword_plans(
customer_id=customer_id,
operations=[operation]
)
keyword_plan_resource_name = response.results[0].resource_name
print(f"Created keyword plan: {keyword_plan_resource_name}")
return keyword_plan_resource_name
except GoogleAdsException as ex:
print(f"Request failed with status {ex.error.code().name}")
for error in ex.failure.errors:
print(f"Error: {error.message}")
return Nonedef create_keyword_plan_campaign(client, customer_id, keyword_plan_resource_name, campaign_name):
"""Create a keyword plan campaign within a keyword plan."""
keyword_plan_campaign_service = client.get_service("KeywordPlanCampaignService")
operation = client.get_type("KeywordPlanCampaignOperation")
campaign = operation.create
campaign.name = campaign_name
campaign.keyword_plan = keyword_plan_resource_name
# Set targeting
campaign.cpc_bid_micros = 1000000 # $1.00 default bid
campaign.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH
# Set geographic targeting (US)
geo_target = client.get_type("KeywordPlanGeoTarget")
geo_target.geo_target_constant = "geoTargetConstants/2840" # United States
campaign.geo_targets.append(geo_target)
# Set language targeting (English)
language_constant = "languageConstants/1000" # English
campaign.language_constants.append(language_constant)
response = keyword_plan_campaign_service.mutate_keyword_plan_campaigns(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef add_keywords_to_plan(client, customer_id, keyword_plan_ad_group_resource_name, keywords):
"""Add keywords to a keyword plan ad group."""
keyword_plan_ad_group_keyword_service = client.get_service("KeywordPlanAdGroupKeywordService")
operations = []
for keyword_text in keywords:
operation = client.get_type("KeywordPlanAdGroupKeywordOperation")
keyword = operation.create
keyword.ad_group = keyword_plan_ad_group_resource_name
keyword.text = keyword_text
keyword.match_type = client.enums.KeywordMatchTypeEnum.BROAD
keyword.cpc_bid_micros = 2000000 # $2.00 bid
operations.append(operation)
response = keyword_plan_ad_group_keyword_service.mutate_keyword_plan_ad_group_keywords(
customer_id=customer_id,
operations=operations
)
return [result.resource_name for result in response.results]def generate_keyword_ideas(client, customer_id, seed_keywords, location_ids, language_id):
"""Generate keyword ideas based on seed keywords."""
keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")
request = client.get_type("GenerateKeywordIdeasRequest")
request.customer_id = customer_id
# Set up keyword seed
keyword_seed = request.keyword_seed
keyword_seed.keywords.extend(seed_keywords)
# Set targeting
request.geo_target_constants = [f"geoTargetConstants/{loc_id}" for loc_id in location_ids]
request.language = f"languageConstants/{language_id}"
request.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH_AND_PARTNERS
# Include keyword annotations for additional data
request.keyword_annotation = [
client.enums.KeywordAnnotationEnum.KEYWORD_CONCEPT
]
try:
response = keyword_plan_idea_service.generate_keyword_ideas(request=request)
ideas = []
for result in response.results:
idea = {
'keyword': result.text,
'avg_monthly_searches': result.keyword_idea_metrics.avg_monthly_searches,
'competition': result.keyword_idea_metrics.competition.name,
'competition_index': result.keyword_idea_metrics.competition_index,
'low_top_of_page_bid_micros': result.keyword_idea_metrics.low_top_of_page_bid_micros,
'high_top_of_page_bid_micros': result.keyword_idea_metrics.high_top_of_page_bid_micros
}
ideas.append(idea)
return ideas
except GoogleAdsException as ex:
print(f"Request failed with status {ex.error.code().name}")
for error in ex.failure.errors:
print(f"Error: {error.message}")
return []
# Example usage
seed_keywords = ["running shoes", "athletic footwear", "sports sneakers"]
location_ids = [2840] # United States
language_id = 1000 # English
ideas = generate_keyword_ideas(client, customer_id, seed_keywords, location_ids, language_id)
for idea in ideas:
print(f"Keyword: {idea['keyword']}")
print(f"Avg Monthly Searches: {idea['avg_monthly_searches']}")
print(f"Competition: {idea['competition']}")
print(f"Top of Page Bid Range: ${idea['low_top_of_page_bid_micros']/1_000_000:.2f} - ${idea['high_top_of_page_bid_micros']/1_000_000:.2f}")
print("---")def get_keyword_historical_metrics(client, customer_id, keywords, location_ids, language_id):
"""Get historical search volume and competition metrics for keywords."""
keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")
request = client.get_type("GenerateKeywordHistoricalMetricsRequest")
request.customer_id = customer_id
request.keywords = keywords
request.geo_target_constants = [f"geoTargetConstants/{loc_id}" for loc_id in location_ids]
request.language = f"languageConstants/{language_id}"
request.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH
response = keyword_plan_idea_service.generate_keyword_historical_metrics(request=request)
metrics = []
for result in response.results:
metric = {
'keyword': result.text,
'search_volume': result.keyword_metrics.avg_monthly_searches,
'competition': result.keyword_metrics.competition.name,
'competition_index': result.keyword_metrics.competition_index,
'monthly_search_volumes': []
}
# Monthly breakdown
for monthly_volume in result.keyword_metrics.monthly_search_volumes:
monthly_data = {
'year': monthly_volume.year,
'month': monthly_volume.month.name,
'searches': monthly_volume.monthly_searches
}
metric['monthly_search_volumes'].append(monthly_data)
metrics.append(metric)
return metricsdef create_negative_keyword_list(client, customer_id, list_name, negative_keywords):
"""Create a shared negative keyword list."""
# Create shared set
shared_set_service = client.get_service("SharedSetService")
shared_criterion_service = client.get_service("SharedCriterionService")
# Create the shared set
set_operation = client.get_type("SharedSetOperation")
shared_set = set_operation.create
shared_set.name = list_name
shared_set.type_ = client.enums.SharedSetTypeEnum.NEGATIVE_KEYWORDS
set_response = shared_set_service.mutate_shared_sets(
customer_id=customer_id,
operations=[set_operation]
)
shared_set_resource_name = set_response.results[0].resource_name
# Add negative keywords to the shared set
criterion_operations = []
for keyword_text in negative_keywords:
criterion_operation = client.get_type("SharedCriterionOperation")
criterion = criterion_operation.create
criterion.shared_set = shared_set_resource_name
criterion.keyword.text = keyword_text
criterion.keyword.match_type = client.enums.KeywordMatchTypeEnum.BROAD
criterion_operations.append(criterion_operation)
if criterion_operations:
criterion_response = shared_criterion_service.mutate_shared_criteria(
customer_id=customer_id,
operations=criterion_operations
)
return shared_set_resource_name
# Example usage
negative_keywords = [
"free",
"cheap",
"used",
"broken",
"repair"
]
list_resource_name = create_negative_keyword_list(
client,
customer_id,
"Brand Protection List",
negative_keywords
)def associate_negative_list_with_campaign(client, customer_id, campaign_resource_name, shared_set_resource_name):
"""Associate a shared negative keyword list with a campaign."""
campaign_shared_set_service = client.get_service("CampaignSharedSetService")
operation = client.get_type("CampaignSharedSetOperation")
campaign_shared_set = operation.create
campaign_shared_set.campaign = campaign_resource_name
campaign_shared_set.shared_set = shared_set_resource_name
response = campaign_shared_set_service.mutate_campaign_shared_sets(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef get_location_suggestions(client, location_names, locale="en", country_code="US"):
"""Get geographic target constant suggestions for location names."""
geo_target_constant_service = client.get_service("GeoTargetConstantService")
request = client.get_type("SuggestGeoTargetConstantsRequest")
request.locale = locale
request.country_code = country_code
# Add location names
for location_name in location_names:
location_name_filter = request.location_names.names.add()
location_name_filter.name = location_name
response = geo_target_constant_service.suggest_geo_target_constants(request=request)
suggestions = []
for suggestion in response.geo_target_constant_suggestions:
geo_target_constant = suggestion.geo_target_constant
suggestion_data = {
'resource_name': geo_target_constant.resource_name,
'id': geo_target_constant.id,
'name': geo_target_constant.name,
'country_code': geo_target_constant.country_code,
'target_type': geo_target_constant.target_type.name,
'status': geo_target_constant.status.name
}
suggestions.append(suggestion_data)
return suggestions
# Example usage
location_names = ["New York", "Los Angeles", "Chicago"]
suggestions = get_location_suggestions(client, location_names)
for suggestion in suggestions:
print(f"Location: {suggestion['name']}")
print(f"ID: {suggestion['id']}")
print(f"Type: {suggestion['target_type']}")
print("---")def create_proximity_targeting(client, customer_id, campaign_resource_name, address, radius_miles):
"""Add proximity (radius) targeting to a campaign."""
campaign_criterion_service = client.get_service("CampaignCriterionService")
operation = client.get_type("CampaignCriterionOperation")
criterion = operation.create
criterion.campaign = campaign_resource_name
criterion.type_ = client.enums.CriterionTypeEnum.PROXIMITY
# Set proximity details
proximity = criterion.proximity
proximity.address.street_address = address['street']
proximity.address.city_name = address['city']
proximity.address.province_code = address['state']
proximity.address.postal_code = address['zip']
proximity.address.country_code = address['country']
proximity.radius = radius_miles
proximity.radius_units = client.enums.ProximityRadiusUnitsEnum.MILES
response = campaign_criterion_service.mutate_campaign_criteria(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_name
# Example usage
store_address = {
'street': '123 Main St',
'city': 'New York',
'state': 'NY',
'zip': '10001',
'country': 'US'
}
proximity_criterion = create_proximity_targeting(
client,
customer_id,
campaign_resource_name,
store_address,
10 # 10 mile radius
)# Keyword plan types
class KeywordPlan:
resource_name: str
id: Optional[int]
name: Optional[str]
forecast_period: KeywordPlanForecastPeriod
class KeywordPlanForecastPeriod:
date_interval: KeywordPlanForecastIntervalEnum.KeywordPlanForecastInterval
date_range: DateRange
class KeywordPlanCampaign:
resource_name: str
keyword_plan: Optional[str]
id: Optional[int]
name: Optional[str]
language_constants: List[str]
keyword_plan_network: KeywordPlanNetworkEnum.KeywordPlanNetwork
cpc_bid_micros: Optional[int]
geo_targets: List[KeywordPlanGeoTarget]
class KeywordPlanAdGroup:
resource_name: str
keyword_plan_campaign: Optional[str]
id: Optional[int]
name: Optional[str]
cpc_bid_micros: Optional[int]
class KeywordPlanAdGroupKeyword:
resource_name: str
ad_group: Optional[str]
id: Optional[int]
text: Optional[str]
match_type: KeywordMatchTypeEnum.KeywordMatchType
cpc_bid_micros: Optional[int]
negative: Optional[bool]
# Keyword idea types
class KeywordIdea:
text: Optional[str]
keyword_idea_metrics: KeywordPlanHistoricalMetrics
class KeywordPlanHistoricalMetrics:
avg_monthly_searches: Optional[int]
monthly_search_volumes: List[MonthlySearchVolume]
competition: KeywordPlanCompetitionLevelEnum.KeywordPlanCompetitionLevel
competition_index: Optional[int]
low_top_of_page_bid_micros: Optional[int]
high_top_of_page_bid_micros: Optional[int]
class MonthlySearchVolume:
year: Optional[int]
month: MonthOfYearEnum.MonthOfYear
monthly_searches: Optional[int]
# Shared set types
class SharedSet:
resource_name: str
id: Optional[int]
type_: SharedSetTypeEnum.SharedSetType
name: Optional[str]
status: SharedSetStatusEnum.SharedSetStatus
member_count: Optional[int]
reference_count: Optional[int]
class SharedCriterion:
resource_name: str
shared_set: Optional[str]
criterion_id: Optional[int]
type_: CriterionTypeEnum.CriterionType
# Criterion types (subset of available types)
keyword: KeywordInfo
youtube_video: YouTubeVideoInfo
youtube_channel: YouTubeChannelInfo
placement: PlacementInfo
mobile_app_category: MobileAppCategoryInfo
# Geographic targeting types
class GeoTargetConstant:
resource_name: str
id: Optional[int]
name: Optional[str]
country_code: Optional[str]
target_type: Optional[str]
status: GeoTargetConstantStatusEnum.GeoTargetConstantStatus
canonical_name: Optional[str]
parent_geo_target: Optional[str]
class ProximityInfo:
geo_point: GeoPointInfo
radius: Optional[float]
radius_units: ProximityRadiusUnitsEnum.ProximityRadiusUnits
address: AddressInfo
class AddressInfo:
postal_code: Optional[str]
province_code: Optional[str]
country_code: Optional[str]
province_name: Optional[str]
street_address: Optional[str]
street_address2: Optional[str]
city_name: Optional[str]
# Request types
class GenerateKeywordIdeasRequest:
customer_id: str
language: Optional[str]
geo_target_constants: List[str]
keyword_plan_network: KeywordPlanNetworkEnum.KeywordPlanNetwork
keyword_annotation: List[KeywordAnnotationEnum.KeywordAnnotation]
aggregate_metrics: AggregateMetricsSelector
# One of the following seed sources
keyword_seed: KeywordSeed
url_seed: UrlSeed
site_seed: SiteSeed
class KeywordSeed:
keywords: List[str]
class UrlSeed:
url: Optional[str]
# Response types
class GenerateKeywordIdeasResponse:
results: List[KeywordIdea]
aggregate_metric_results: KeywordPlanAggregateMetrics
next_page_token: str
total_size: int
class GenerateKeywordHistoricalMetricsResponse:
results: List[KeywordPlanKeywordHistoricalMetrics]
aggregate_metric_results: KeywordPlanAggregateMetrics
# Operation types
class KeywordPlanOperation:
update_mask: FieldMask
create: KeywordPlan
update: KeywordPlan
remove: str
class SharedSetOperation:
update_mask: FieldMask
create: SharedSet
update: SharedSet
remove: str
class SharedCriterionOperation:
update_mask: FieldMask
create: SharedCriterion
update: SharedCriterion
remove: strInstall with Tessl CLI
npx tessl i tessl/pypi-google-ads