Generate keyword ideas

  • The KeywordPlanIdeaService can be used to find new keywords and historical metrics for Google Search campaigns.

  • Keyword ideas can be generated using keywords, a URL, or both as seeds.

  • Targeting parameters such as location, language, and network settings can be used to refine keyword idea generation.

  • Historical statistics like search volume data are provided with the results to help determine keyword usability.

  • This service offers similar functionality to the Keyword Planner tool in the Google Ads UI.

Using the KeywordPlanIdeaService, you can programmatically discover keyword recommendations and retrieve historical search metrics (such as average monthly search volume and competition scores) based on seed terms or website URLs. This functionality is the programmatic equivalent of the Keyword Planner UI tool in Google Ads.


1. Overview and synergy with custom audiences

While keyword planning is commonly used to construct standard search campaigns, it also offers powerful synergy with Custom Audiences:

  • Data-Driven Signals: Instead of manually guessing which keywords your target audience searches for, you can use KeywordPlanIdeaService to input general industry terms or competitor URLs, and discover high-performing, relevant search terms.
  • Automated Pipeline: You can programmatically filter these discovered keyword recommendations (e.g., by minimum monthly search volume) and directly feed them into a CustomAudience creation service. This ensures your Custom Audiences are populated with validated, high-intent targeting signals.

2. Prerequisites

Before generating keyword ideas, ensure you have:

  1. Configured API Credentials: See the Onboarding Guide for instructions on setting up your Google Cloud project, OAuth 2.0, and developer token.
  2. Target Customer ID: The 10-digit Google Ads client account ID.
  3. Targeting Constant IDs:
    • Language ID: The numeric criterion ID representing the language (e.g., 1000 for English). See the Language Constants Documentation for the full lookup table.
    • Geo Target ID: The numeric criterion ID representing the geographic location (e.g., 2840 for the United States). See the Geo Targets Documentation for the complete list of geographical criteria.

3. Core API resources and architecture

KeywordPlanIdeaService

The gRPC service responsible for keyword generation. The primary method is generate_keyword_ideas(), which accepts a GenerateKeywordIdeasRequest and returns an iterable stream of keyword ideas.

GenerateKeywordIdeasRequest

The Protobuf request object configuring the generation parameters (GenerateKeywordIdeasRequest). Key fields:

  • customer_id: The client account ID.
  • language: The formatted language resource name (e.g., languageConstants/1000).
  • geo_target_constants: A list of formatted geo target resource names (e.g., geoTargetConstants/2840).
  • keyword_plan_network: The search network scope (GOOGLE_SEARCH or GOOGLE_SEARCH_AND_PARTNERS).
  • include_adult_keywords: Boolean indicating whether adult terms should be included (defaults to False).

Seed Types (oneof seed)

To generate ideas, you must populate exactly one seed configuration field:

  1. keyword_seed: Generates ideas based on a list of seed words or phrases. Use KeywordSeed.
  2. url_seed: Generates ideas based on the content and themes of a specific webpage URL. Use UrlSeed.
  3. keyword_and_url_seed: Combines both seed terms and a webpage URL to generate highly focused ideas. Use KeywordAndUrlSeed.
  4. site_seed: Generates ideas based on an entire top-level website domain. Use SiteSeed.

4. Step-by-step implementation

Step 1: Initialize client and services

Load the client configuration and obtain instances of KeywordPlanIdeaService and GoogleAdsService.

from google.ads.googleads.client import GoogleAdsClient

client = GoogleAdsClient.load_from_storage()
keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")
google_ads_service = client.get_service("GoogleAdsService")

Step 2: Format targeting resource names

Use helper methods on GoogleAdsService to convert raw numeric IDs into valid Protobuf resource names.

language_rn = google_ads_service.language_constant_path("1000") # English
geo_rn = google_ads_service.geo_target_constant_path("2840")   # United States

Step 3: Construct the request object

Instantiate GenerateKeywordIdeasRequest and set the targeting parameters.

request = client.get_type("GenerateKeywordIdeasRequest")
request.customer_id = "1234567890"
request.language = language_rn
request.geo_target_constants.append(geo_rn)
request.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH

Step 4: Configure the seed

Populate the chosen seed container (e.g., keyword_seed).

request.keyword_seed.keywords.extend(["marathon training", "running shoes"])

Step 5: Execute and parse results

Call generate_keyword_ideas() and iterate through the response to examine metrics.

response = keyword_plan_idea_service.generate_keyword_ideas(request=request)
for idea in response:
    print(f"Idea: {idea.text}, Monthly Searches: {idea.keyword_idea_metrics.avg_monthly_searches}")

5. Complete Python code example

Below is a robust, fully functional script that generates keyword ideas from seed terms and filters them by minimum monthly search volume.

import sys
from typing import List
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException

def generate_keywords(
    client: GoogleAdsClient, customer_id: str, seed_keywords: List[str], min_monthly_searches: int = 1000
) -> List[str]:
    """Generates keyword ideas and filters them by minimum monthly search volume."""
    keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")
    google_ads_service = client.get_service("GoogleAdsService")

    # 1. Construct resource names for targeting (English, US)
    language_rn = google_ads_service.language_constant_path("1000")
    geo_rn = google_ads_service.geo_target_constant_path("2840")

    # 2. Initialize the request
    request = client.get_type("GenerateKeywordIdeasRequest")
    request.customer_id = customer_id
    request.language = language_rn
    request.geo_target_constants.append(geo_rn)
    request.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH
    request.include_adult_keywords = False

    # 3. Set the keyword seed
    request.keyword_seed.keywords.extend(seed_keywords)

    validated_keywords = []

    # 4. Issue the request and filter results
    try:
        response = keyword_plan_idea_service.generate_keyword_ideas(request=request)
        print(f"\nGenerating keyword ideas for seeds: {seed_keywords}...\n")
        
        for idea in response:
            metrics = idea.keyword_idea_metrics
            searches = metrics.avg_monthly_searches
            competition = client.enums.KeywordPlanCompetitionLevelEnum.to_name(metrics.competition)
            
            # Filter for relevance and volume
            if searches and searches >= min_monthly_searches:
                print(f"Found matching keyword: '{idea.text}' (Volume: {searches} | Competition: {competition})")
                validated_keywords.append(idea.text)
                
        return validated_keywords

    except GoogleAdsException as ex:
        print(f"Request failed with status {ex.error.code().name} and includes the following errors:")
        for error in ex.failure.errors:
            print(f"\tError with message '{error.message}'.")
        sys.exit(1)

if __name__ == "__main__":
    try:
        googleads_client = GoogleAdsClient.load_from_storage()
        target_customer_id = "1234567890"
        seeds = ["trail running", "ultra marathon"]
        
        results = generate_keywords(googleads_client, target_customer_id, seeds)
        print(f"\nSuccessfully extracted {len(results)} high-volume keywords.")
    except GoogleAdsException as ex:
        print(f"Failed to initialize client: {ex}")
        sys.exit(1)

6. Pipeline: Feed keyword ideas into custom audiences

Once you generate and filter high-quality keyword ideas, you can pass them directly into a Custom Audience creation function to build an end-to-end keyword discovery and targeting pipeline.

The following script demonstrates how to bridge generate_keywords() with the Custom Audience workflow described in the Custom Audiences Guide:

def create_audience_from_keyword_ideas(client: GoogleAdsClient, customer_id: str, seed_keywords: List[str]):
    """Generates keyword ideas and immediately builds a Custom Audience from them."""
    
    # 1. Fetch high-volume keyword ideas
    generated_keywords = generate_keywords(client, customer_id, seed_keywords, min_monthly_searches=5000)
    
    if not generated_keywords:
        print("No valid keywords found matching criteria. Aborting audience creation.")
        return
        
    # 2. Initialize CustomAudienceService and resource
    custom_audience_service = client.get_service("CustomAudienceService")
    custom_audience = client.get_type("CustomAudience")
    custom_audience.name = f"Automated Intent: {seed_keywords[0].title()}"
    custom_audience.description = "Audience dynamically populated from Keyword Planner API recommendations."
    custom_audience.type_ = client.enums.CustomAudienceTypeEnum.AUTO
    custom_audience.status = client.enums.CustomAudienceStatusEnum.ENABLED
    
    # 3. Populate Custom Audience Members with the generated keywords
    for kw in generated_keywords:
        member = client.get_type("CustomAudienceMember")
        member.member_type = client.enums.CustomAudienceMemberTypeEnum.KEYWORD
        member.keyword = kw
        custom_audience.members.append(member)
        
    # 4. Mutate and create the Custom Audience
    operation = client.get_type("CustomAudienceOperation")
    operation.create = custom_audience
    
    try:
        response = custom_audience_service.mutate_custom_audiences(
            customer_id=customer_id, operations=[operation]
        )
        print(f"\nSuccessfully created Custom Audience: '{response.results[0].resource_name}'")
    except GoogleAdsException as ex:
        print(f"Audience creation failed: {ex.error.code().name}")

7. Best practices and limitations

Seed limits

  • Keyword Seed: Maximum of 20 seed keywords per request.
  • URL / Site Seed: Exactly 1 URL or domain per request.

Pagination and response size

The generate_keyword_ideas() stream returns up to 700 keyword ideas by default (the exact number depends on the seed breadth). If you need broader discovery, run multiple requests across different seed themes rather than packing disparate keywords into a single request.

Metric interpretation

Historical search volume metrics (avg_monthly_searches) are 12-month averages and may not reflect sudden seasonal spikes. Use monthly_search_volumes within KeywordIdeaMetrics if you need granular month-over-month trends.


8. Map to the UI

The services and fields in KeywordPlanIdeaService.GenerateKeywordIdeas correspond to various elements within the Keyword Planner tool in the Google Ads UI.

Keyword Planner UI Google Ads API
Enter Keywords and URLs
Locations GenerateKeywordIdeasRequest.geo_target_constants
Adult Keywords GenerateKeywordIdeasRequest.include_adult_keywords
Language GenerateKeywordIdeasRequest.language
Search Networks GenerateKeywordIdeasRequest.keyword_plan_network
Refine Keywords GenerateKeywordIdeasRequest.keyword_annotation
Date Range GenerateKeywordIdeasRequest.historical_metrics_options
Results: Keyword GenerateKeywordIdeaResult.text
Results: Metrics GenerateKeywordIdeaResult.keyword_idea_metrics