Custom audiences guide

  • Custom audiences allow targeting specific user groups using keywords, URLs, and apps, combining the functionality of Custom Intent and Custom Affinity.

  • You can define a custom audience by specifying interests, relevant website URLs, and related app package names.

  • Custom audiences can be targeted at either the campaign or ad group level to reach your defined audience.

  • Recommendations for creating custom audiences are available to help improve account optimization score.

  • Performance of custom audiences can be reviewed using specific reporting views to analyze metrics like conversions and cost per conversion.

Custom Audiences (which encompass legacy Custom Intent and Custom Affinity audiences) allow advertisers to reach ideal target audiences by entering relevant keywords, URLs, and apps related to their products or services. Google Ads automatically determines the most appropriate audience targeting based on campaign type, bidding strategy, and optimization goals.

This guide provides an end-to-end walkthrough on how to create and manage Custom Audiences using keywords and URLs using the Google Ads API.


1. Understand custom audiences

In the Google Ads API, legacy concepts such as Custom Intent and Custom Affinity have been unified into a single overarching resource: Custom Audiences.

When you target a custom audience, Google Ads shows ads to users with these interests or purchase intentions on Display, Demand Gen, Gmail, Video, and Performance Max campaigns:

  • Keyword Members: Reach users who search for specific terms on Google, or users with interests related to those keywords.
  • URL Members: Reach users who browse websites similar to the specified URLs.
  • App Members: Reach users who use specific mobile applications.

2. Prerequisites

Before creating Custom Audiences, ensure you have:

  1. Completed API Onboarding: See the Onboarding Guide for instructions on obtaining a developer token, setting up Google Cloud, and configuring OAuth 2.0.
  2. Target Customer ID: The 10-digit Google Ads client account ID where the custom audience will be created.
  3. Installed Client Library: The official Google Ads client library (e.g., google-ads for Python).

3. Core API resources and architecture

Managing custom audiences involves several distinct Protocol Buffer (Protobuf) entities within the Google Ads API:

CustomAudienceService

The gRPC service responsible for managing custom audiences. Key methods include MutateCustomAudiences, which takes a list of operations to create, update, or remove audiences.

CustomAudience

The primary resource representing the audience (CustomAudience). Key fields:

  • name: A unique, descriptive name for the custom audience.
  • description: Optional text describing the audience's intended target.
  • status: Set to ENABLED to make the audience active and usable.
  • type: The custom audience type (AUTO or SEARCH).
  • members: A list of CustomAudienceMember objects defining the target signals.

CustomAudienceMember

An individual targeting signal within the audience (CustomAudienceMember).

  • member_type: The enum specifying the signal type (KEYWORD, URL, APP).
  • keyword / url / app: The string value corresponding to the member type.

4. Step-by-step implementation

Step 1: Initialize the client

Instantiate the GoogleAdsClient using your configured google-ads.yaml file.

from google.ads.googleads.client import GoogleAdsClient

# Initialize the Google Ads client library
client = GoogleAdsClient.load_from_storage()
custom_audience_service = client.get_service("CustomAudienceService")

Step 2: Construct the custom audience

Create a new CustomAudience instance and configure its metadata (name, description, type, status).

# Construct the CustomAudience resource
custom_audience = client.get_type("CustomAudience")
custom_audience.name = "Target Audience Name"
custom_audience.description = "Description of the target audience."
custom_audience.type_ = client.enums.CustomAudienceTypeEnum.AUTO
custom_audience.status = client.enums.CustomAudienceStatusEnum.ENABLED

Step 3: Populate keyword members

Instantiate CustomAudienceMember objects, set member_type to CustomAudienceMemberTypeEnum.KEYWORD, and populate the keyword string field with your targeting terms.

# Create and append a keyword member
keyword_member = client.get_type("CustomAudienceMember")
keyword_member.member_type = client.enums.CustomAudienceMemberTypeEnum.KEYWORD
keyword_member.keyword = "marathon training"
custom_audience.members.append(keyword_member)

Step 4: Populate URL members

Instantiate CustomAudienceMember objects, set member_type to CustomAudienceMemberTypeEnum.URL, and populate the url string field with competitor or industry websites.

# Create and append a URL member
url_member = client.get_type("CustomAudienceMember")
url_member.member_type = client.enums.CustomAudienceMemberTypeEnum.URL
url_member.url = "https://www.runnersworld.com"
custom_audience.members.append(url_member)

Step 5: Execute the mutation

Wrap the CustomAudience in a CustomAudienceOperation, set it to the create field, and call CustomAudienceService.mutate_custom_audiences().

# Wrap in an operation and execute the mutation request
operation = client.get_type("CustomAudienceOperation")
operation.create = custom_audience

response = custom_audience_service.mutate_custom_audiences(
    customer_id="1234567890", operations=[operation]
)
print(f"Created custom audience: {response.results[0].resource_name}")

5. Complete Python code example

Below is a fully functional Python script demonstrating how to create a Custom Audience with both keyword and URL members.

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

def create_custom_intent_audience(client: GoogleAdsClient, customer_id: str):
    """Creates a custom audience using keywords and URLs."""
    
    # 1. Get the CustomAudienceService
    custom_audience_service = client.get_service("CustomAudienceService")
    
    # 2. Create the CustomAudience resource
    custom_audience = client.get_type("CustomAudience")
    custom_audience.name = "Running Enthusiasts & Gear Shoppers"
    custom_audience.description = "Targeting users actively researching running shoes and visiting marathon websites."
    
    # Use AUTO for standard custom audiences (combines intent and affinity signals)
    custom_audience.type_ = client.enums.CustomAudienceTypeEnum.AUTO
    custom_audience.status = client.enums.CustomAudienceStatusEnum.ENABLED

    # 3. Add Keyword Members (Search Terms / Purchase Intent Keywords)
    keywords = [
        "best marathon running shoes",
        "carbon plate running shoes",
        "marathon training plan",
        "trail running gear"
    ]
    
    for kw in keywords:
        member = client.get_type("CustomAudienceMember")
        member.member_type = client.enums.CustomAudienceMemberTypeEnum.KEYWORD
        member.keyword = kw
        custom_audience.members.append(member)

    # 4. Add URL Members (Relevant websites/competitors)
    urls = [
        "https://www.runnersworld.com",
        "https://www.marathonrunning.com",
        "https://www.trailrunnermag.com"
    ]
    
    for url in urls:
        member = client.get_type("CustomAudienceMember")
        member.member_type = client.enums.CustomAudienceMemberTypeEnum.URL
        member.url = url
        custom_audience.members.append(member)

    # 5. Create the Operation
    operation = client.get_type("CustomAudienceOperation")
    operation.create = custom_audience

    # 6. Issue the Mutate Request
    try:
        response = custom_audience_service.mutate_custom_audiences(
            customer_id=customer_id, operations=[operation]
        )
        created_resource_name = response.results[0].resource_name
        print(f"Successfully created Custom Audience with resource name: '{created_resource_name}'")
    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}'.")
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

if __name__ == "__main__":
    # Ensure the client is configured correctly (loads from google-ads.yaml)
    try:
        googleads_client = GoogleAdsClient.load_from_storage()
        # Replace with your actual Google Ads Customer ID (without hyphens)
        target_customer_id = "1234567890"
        create_custom_intent_audience(googleads_client, target_customer_id)
    except GoogleAdsException as ex:
        print(f"Failed to initialize client or execute request: {ex}")
        sys.exit(1)

6. Apply custom audiences to campaigns

Once a Custom Audience is created, it exists in your account's audience library but does not actively target users until attached to an Ad Group or Campaign.

What is an AdGroupCriterion?

In the Google Ads API architecture, targeting rules (such as keywords, audiences, placements, and demographics) are not configured directly on the Ad Group object. Instead, Google Ads unifies all targeting methods under a single standalone entity called AdGroupCriterion.

An AdGroupCriterion acts as a universal container. You specify which Ad Group it applies to, and then populate exactly one of its specific targeting fields (e.g., keyword, custom_audience, or placement). By creating an AdGroupCriterion and configuring its custom_audience field, you instruct Google Ads to restrict or observe ad serving for that Ad Group based on the members of your Custom Audience.

Step-by-step breakdown (explicit two-step creation)

To clearly distinguish between the targeting configuration and the API request container, we use the Explicit Two-Step Creation pattern:

  1. Instantiate an AdGroupCriterion Resource: Create a standalone AdGroupCriterion object. This resource represents the targeting relationship.
  2. Set the Target ad_group: Assign the formatted resource name of your Ad Group (e.g., customers/{customer_id}/adGroups/{ad_group_id}) to the criterion's ad_group field.
  3. Populate the custom_audience Field: Assign the resource_name of your previously created Custom Audience to ad_group_criterion.custom_audience.custom_audience.
  4. Package into an AdGroupCriterionOperation: To send this new criterion to the API, instantiate an AdGroupCriterionOperation container and assign your standalone criterion object to operation.create.
  5. Send using AdGroupCriterionService: Pass the operation container to mutate_ad_group_criteria() to execute the creation.
import sys
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException

def attach_custom_audience_to_ad_group(
    client: GoogleAdsClient, customer_id: str, ad_group_id: str, custom_audience_resource_name: str
):
    """Attaches a Custom Audience to an Ad Group using explicit two-step creation."""
    ad_group_criterion_service = client.get_service("AdGroupCriterionService")
    
    # Step 1: Instantiate the standalone AdGroupCriterion resource
    ad_group_criterion = client.get_type("AdGroupCriterion")
    
    # Step 2: Set the target Ad Group
    ad_group_criterion.ad_group = client.get_service("AdGroupService").ad_group_path(
        customer_id, ad_group_id
    )
    
    # Step 3: Set the custom audience targeting information
    ad_group_criterion.custom_audience.custom_audience = custom_audience_resource_name
    
    # Step 4: Package the resource into an AdGroupCriterionOperation
    operation = client.get_type("AdGroupCriterionOperation")
    operation.create = ad_group_criterion
    
    # Step 5: Issue the API Request
    try:
        response = ad_group_criterion_service.mutate_ad_group_criteria(
            customer_id=customer_id, operations=[operation]
        )
        print(
            "Successfully attached custom audience to Ad Group. "
            f"New criterion resource name: '{response.results[0].resource_name}'"
        )
    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)

7. Custom audience recommendation

You can retrieve recommendations of type CUSTOM_AUDIENCE_OPT_IN, which recommends creating a custom audience. This is especially useful if you are a third-party advertiser that enables its users to create and manage audience segments. When users act on the recommendation to create a custom audience, it serves to improve the overall optimization score of the account.

For more information, visit the Optimization score and recommendations guide.


8. Best practices and limitations

Quality over quantity

Focus on highly specific, relevant keywords and URLs. Adding hundreds of generic keywords dilutes intent and decreases campaign efficiency.

URL formatting rules

  • URLs must be valid website addresses (e.g., https://www.example.com).
  • Avoid deep, highly specific sub-pages with low traffic; domain-level or category-level URLs yield better reach.

Member limits

While custom audiences can hold numerous members, keep lists focused around a single coherent theme or persona per custom audience.

Policy and privacy

Google enforces strict personalized advertising policies. Do not use custom audiences to target sensitive categories such as medical conditions, financial hardship, or religious beliefs.


9. Review list performance

Before you can review performance, you must first attach your custom audience targeting to a campaign or ad group, as described in the Target the custom audience section.

In order to collect performance data for your audience segments, issue a search request against the ad_group_audience_view or the campaign_audience_view resource. For example, you might look at the conversions or cost_per_conversion to determine if targeting the audience segment is actually leading to more conversions, then adjust your bid modifiers accordingly.

SELECT
  ad_group_criterion.criterion_id,
  metrics.conversions,
  metrics.cost_per_conversion
FROM ad_group_audience_view

10. Resources and reference