Client library for the Google Ads API providing comprehensive access to advertising management, reporting, and analytics capabilities.
—
Comprehensive audience and user list management including custom audience creation, user list management, audience insights, and advanced audience targeting capabilities. The Google Ads API provides extensive audience management features for remarketing, lookalike audiences, and behavioral targeting.
User list management operations for creating and managing remarketing lists, customer match lists, and other audience segments for targeted advertising.
def mutate_user_lists(
self,
request: Optional[MutateUserListsRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[UserListOperation]] = None,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: Optional[ResponseContentTypeEnum.ResponseContentType] = None
) -> MutateUserListsResponse:
"""
Create, update, or remove user lists.
Args:
request: The request object containing all parameters
customer_id: Required customer ID for the account
operations: List of user list operations to perform
partial_failure: Continue processing on individual failures
validate_only: Validate operations without executing
response_content_type: Type of response content to return
Returns:
MutateUserListsResponse with operation results
"""
def get_user_list(
self,
request: Optional[GetUserListRequest] = None,
resource_name: Optional[str] = None
) -> UserList:
"""
Retrieve a user list by resource name.
Args:
request: The request object
resource_name: User list resource name (customers/{customer_id}/userLists/{user_list_id})
Returns:
UserList resource object
"""Custom audience management for creating and managing interest-based and intent-based custom audiences for broader targeting beyond existing customer data.
def mutate_custom_audiences(
self,
request: Optional[MutateCustomAudiencesRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[CustomAudienceOperation]] = None,
validate_only: bool = False
) -> MutateCustomAudiencesResponse:
"""
Create, update, or remove custom audiences.
Args:
request: The request object
customer_id: Required customer ID
operations: List of custom audience operations
validate_only: Validate without executing
Returns:
MutateCustomAudiencesResponse with results
"""
def get_custom_audience(
self,
request: Optional[GetCustomAudienceRequest] = None,
resource_name: Optional[str] = None
) -> CustomAudience:
"""
Retrieve a custom audience by resource name.
Args:
request: The request object
resource_name: Custom audience resource name
Returns:
CustomAudience resource object
"""Audience insights and analytics operations for understanding audience characteristics, interests, and behaviors to inform targeting strategies.
def generate_insights_finder_report(
self,
request: Optional[GenerateInsightsFinderReportRequest] = None,
customer_id: Optional[str] = None,
baseline_audience: Optional[BasicInsightsAudience] = None,
specific_audience: Optional[BasicInsightsAudience] = None
) -> GenerateInsightsFinderReportResponse:
"""
Generate audience insights report comparing audiences.
Args:
request: The request object
customer_id: Required customer ID
baseline_audience: Baseline audience for comparison
specific_audience: Specific audience to analyze
Returns:
Audience insights data and recommendations
"""
def generate_audience_composition_insights(
self,
request: Optional[GenerateAudienceCompositionInsightsRequest] = None,
customer_id: Optional[str] = None,
audience: Optional[InsightsAudience] = None,
dimensions: Optional[Sequence[AudienceInsightsDimensionEnum.AudienceInsightsDimension]] = None
) -> GenerateAudienceCompositionInsightsResponse:
"""
Generate audience composition insights for demographic analysis.
Args:
request: The request object
customer_id: Required customer ID
audience: Audience to analyze
dimensions: Dimensions for analysis (age, gender, etc.)
Returns:
Demographic composition insights
"""
def list_insights_eligible_dates(
self,
request: Optional[ListInsightsEligibleDatesRequest] = None
) -> ListInsightsEligibleDatesResponse:
"""
List available dates for audience insights analysis.
Args:
request: The request object
Returns:
Available date ranges for insights
"""Remarketing action management for defining conversion events and user interactions that trigger remarketing list membership.
def mutate_remarketing_actions(
self,
request: Optional[MutateRemarketingActionsRequest] = None,
customer_id: Optional[str] = None,
operations: Optional[Sequence[RemarketingActionOperation]] = None,
partial_failure: bool = False,
validate_only: bool = False
) -> MutateRemarketingActionsResponse:
"""
Create, update, or remove remarketing actions.
Args:
request: The request object
customer_id: Required customer ID
operations: List of remarketing action operations
partial_failure: Continue on individual failures
validate_only: Validate without executing
Returns:
MutateRemarketingActionsResponse with results
"""
def get_remarketing_action(
self,
request: Optional[GetRemarketingActionRequest] = None,
resource_name: Optional[str] = None
) -> RemarketingAction:
"""
Retrieve a remarketing action by resource name.
Args:
request: The request object
resource_name: Remarketing action resource name
Returns:
RemarketingAction resource object
"""from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
def create_remarketing_list(client, customer_id, list_name, rule_items):
"""Create a remarketing list based on website visits."""
user_list_service = client.get_service("UserListService")
# Create user list operation
operation = client.get_type("UserListOperation")
user_list = operation.create
user_list.name = list_name
user_list.description = f"Website visitors for {list_name}"
user_list.membership_status = client.enums.UserListMembershipStatusEnum.OPEN
user_list.membership_life_span = 30 # 30 days
# Configure rule-based user list
rule_based_user_list = user_list.rule_based_user_list
rule_based_user_list.prepopulation_status = client.enums.UserListPrepopulationStatusEnum.REQUESTED
# Create flexible rule user list
flexible_rule_user_list = rule_based_user_list.flexible_rule_user_list
flexible_rule_user_list.inclusive_rule_operator = client.enums.UserListFlexibleRuleOperatorEnum.AND
# Add rule groups
rule_group = client.get_type("FlexibleRuleOperandInfo")
rule_group.rule.rule_type = client.enums.UserListRuleTypeEnum.URL
# Add rule items (URL conditions)
for rule_item_data in rule_items:
rule_item = client.get_type("UserListRuleItemInfo")
rule_item.name = rule_item_data['name']
rule_item.string_rule_item.operator = rule_item_data['operator']
rule_item.string_rule_item.value = rule_item_data['value']
rule_group.rule.rule_item_groups.append(
client.get_type("UserListRuleItemGroupInfo", rule_items=[rule_item])
)
flexible_rule_user_list.inclusive_operands.append(rule_group)
try:
response = user_list_service.mutate_user_lists(
customer_id=customer_id,
operations=[operation]
)
user_list_resource_name = response.results[0].resource_name
print(f"Created remarketing list: {user_list_resource_name}")
return user_list_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 None
# Example usage - visitors to specific product pages
rule_items = [
{
'name': 'url',
'operator': client.enums.UserListStringRuleItemOperatorEnum.CONTAINS,
'value': '/products/'
}
]
remarketing_list = create_remarketing_list(
client,
customer_id,
"Product Page Visitors",
rule_items
)def create_customer_match_email_list(client, customer_id, list_name, emails):
"""Create a customer match list using email addresses."""
user_list_service = client.get_service("UserListService")
offline_user_data_job_service = client.get_service("OfflineUserDataJobService")
# Create customer match user list
operation = client.get_type("UserListOperation")
user_list = operation.create
user_list.name = list_name
user_list.description = f"Customer match list: {list_name}"
user_list.membership_status = client.enums.UserListMembershipStatusEnum.OPEN
user_list.membership_life_span = 10000 # Maximum lifespan
# Configure customer match user list
crm_based_user_list = user_list.crm_based_user_list
crm_based_user_list.upload_key_type = client.enums.CustomerMatchUploadKeyTypeEnum.CONTACT_INFO
crm_based_user_list.data_source_type = client.enums.UserListCrmDataSourceTypeEnum.FIRST_PARTY
# Create the user list first
response = user_list_service.mutate_user_lists(
customer_id=customer_id,
operations=[operation]
)
user_list_resource_name = response.results[0].resource_name
# Create offline user data job to upload emails
job_operation = client.get_type("OfflineUserDataJobOperation")
job = job_operation.create
job.type_ = client.enums.OfflineUserDataJobTypeEnum.CUSTOMER_MATCH_USER_LIST
job.customer_match_user_list_metadata.user_list = user_list_resource_name
job_response = offline_user_data_job_service.create_offline_user_data_job(
customer_id=customer_id,
job=job
)
job_resource_name = job_response.resource_name
# Add email operations
operations = []
for email in emails:
user_data_operation = client.get_type("OfflineUserDataJobOperation")
user_data = user_data_operation.create
user_data.user_identifiers.append(
client.get_type("UserIdentifier",
hashed_email=hashlib.sha256(email.lower().encode()).hexdigest())
)
operations.append(user_data_operation)
# Add operations to job
offline_user_data_job_service.add_offline_user_data_job_operations(
resource_name=job_resource_name,
operations=operations
)
# Run the job
offline_user_data_job_service.run_offline_user_data_job(
resource_name=job_resource_name
)
return user_list_resource_name
# Example usage
import hashlib
customer_emails = [
"customer1@example.com",
"customer2@example.com",
"customer3@example.com"
]
customer_match_list = create_customer_match_email_list(
client,
customer_id,
"VIP Customers",
customer_emails
)def create_similar_user_list(client, customer_id, list_name, seed_user_list_resource_name):
"""Create a similar audiences (lookalike) list based on a seed list."""
user_list_service = client.get_service("UserListService")
operation = client.get_type("UserListOperation")
user_list = operation.create
user_list.name = list_name
user_list.description = f"Similar audience based on {seed_user_list_resource_name}"
user_list.membership_status = client.enums.UserListMembershipStatusEnum.OPEN
user_list.membership_life_span = 30
# Configure similar user list
similar_user_list = user_list.similar_user_list
similar_user_list.seed_user_list = seed_user_list_resource_name
response = user_list_service.mutate_user_lists(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef create_interest_custom_audience(client, customer_id, audience_name, interests, urls=None):
"""Create a custom audience based on interests and URLs."""
custom_audience_service = client.get_service("CustomAudienceService")
operation = client.get_type("CustomAudienceOperation")
custom_audience = operation.create
custom_audience.name = audience_name
custom_audience.type_ = client.enums.CustomAudienceTypeEnum.INTEREST
custom_audience.description = f"Interest-based audience: {audience_name}"
custom_audience.status = client.enums.CustomAudienceStatusEnum.ENABLED
# Add interest members
for interest in interests:
member = client.get_type("CustomAudienceMember")
member.member_type = client.enums.CustomAudienceMemberTypeEnum.KEYWORD
member.keyword = interest
custom_audience.members.append(member)
# Add URL members if provided
if urls:
for url in urls:
member = client.get_type("CustomAudienceMember")
member.member_type = client.enums.CustomAudienceMemberTypeEnum.URL
member.url = url
custom_audience.members.append(member)
try:
response = custom_audience_service.mutate_custom_audiences(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_name
except GoogleAdsException as ex:
print(f"Request failed: {ex.error.code().name}")
for error in ex.failure.errors:
print(f"Error: {error.message}")
return None
# Example usage
interests = [
"outdoor sports",
"hiking equipment",
"camping gear",
"adventure travel"
]
urls = [
"https://www.outdoor-gear.com",
"https://www.hiking-equipment.com"
]
custom_audience = create_interest_custom_audience(
client,
customer_id,
"Outdoor Enthusiasts",
interests,
urls
)def create_purchase_intent_audience(client, customer_id, audience_name, intent_keywords, apps=None):
"""Create a purchase intent custom audience."""
custom_audience_service = client.get_service("CustomAudienceService")
operation = client.get_type("CustomAudienceOperation")
custom_audience = operation.create
custom_audience.name = audience_name
custom_audience.type_ = client.enums.CustomAudienceTypeEnum.PURCHASE_INTENT
custom_audience.description = f"Purchase intent audience: {audience_name}"
custom_audience.status = client.enums.CustomAudienceStatusEnum.ENABLED
# Add intent keywords
for keyword in intent_keywords:
member = client.get_type("CustomAudienceMember")
member.member_type = client.enums.CustomAudienceMemberTypeEnum.KEYWORD
member.keyword = keyword
custom_audience.members.append(member)
# Add app members if provided
if apps:
for app in apps:
member = client.get_type("CustomAudienceMember")
member.member_type = client.enums.CustomAudienceMemberTypeEnum.APP
member.app = app
custom_audience.members.append(member)
response = custom_audience_service.mutate_custom_audiences(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef add_audience_to_campaign(client, customer_id, campaign_resource_name, audience_resource_name, bid_modifier=None):
"""Add audience 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.status = client.enums.CampaignCriterionStatusEnum.ENABLED
# Determine audience type and set accordingly
if "userLists" in audience_resource_name:
criterion.type_ = client.enums.CriterionTypeEnum.USER_LIST
criterion.user_list.user_list = audience_resource_name
elif "customAudiences" in audience_resource_name:
criterion.type_ = client.enums.CriterionTypeEnum.CUSTOM_AUDIENCE
criterion.custom_audience.custom_audience = audience_resource_name
# Set bid modifier if provided
if bid_modifier:
criterion.bid_modifier = bid_modifier
response = campaign_criterion_service.mutate_campaign_criteria(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef exclude_audience_from_campaign(client, customer_id, campaign_resource_name, audience_resource_name):
"""Add audience exclusion to a campaign."""
campaign_criterion_service = client.get_service("CampaignCriterionService")
operation = client.get_type("CampaignCriterionOperation")
criterion = operation.create
criterion.campaign = campaign_resource_name
criterion.negative = True # Mark as exclusion
if "userLists" in audience_resource_name:
criterion.type_ = client.enums.CriterionTypeEnum.USER_LIST
criterion.user_list.user_list = audience_resource_name
elif "customAudiences" in audience_resource_name:
criterion.type_ = client.enums.CriterionTypeEnum.CUSTOM_AUDIENCE
criterion.custom_audience.custom_audience = audience_resource_name
response = campaign_criterion_service.mutate_campaign_criteria(
customer_id=customer_id,
operations=[operation]
)
return response.results[0].resource_namedef get_audience_demographics(client, customer_id, user_list_resource_name):
"""Generate demographic insights for an audience."""
audience_insights_service = client.get_service("AudienceInsightsService")
# Create insights audience from user list
insights_audience = client.get_type("InsightsAudience")
insights_audience.country_location.append(
client.get_type("LocationInfo", geo_target_constant="geoTargetConstants/2840") # US
)
insights_audience.user_lists.append(user_list_resource_name)
# Request demographic dimensions
dimensions = [
client.enums.AudienceInsightsDimensionEnum.AGE_RANGE,
client.enums.AudienceInsightsDimensionEnum.GENDER,
client.enums.AudienceInsightsDimensionEnum.INCOME_RANGE,
client.enums.AudienceInsightsDimensionEnum.PARENTAL_STATUS
]
request = client.get_type("GenerateAudienceCompositionInsightsRequest")
request.customer_id = customer_id
request.audience = insights_audience
request.dimensions = dimensions
try:
response = audience_insights_service.generate_audience_composition_insights(
request=request
)
insights_data = []
for section in response.sections:
section_data = {
'dimension': section.dimension.name,
'breakdown': []
}
for attribute in section.breakdown:
attribute_data = {
'attribute': attribute.attribute_metadata.dimension_value.display_name,
'coverage_percentage': attribute.coverage_percentage,
'index': attribute.index,
'score': attribute.score
}
section_data['breakdown'].append(attribute_data)
insights_data.append(section_data)
return insights_data
except GoogleAdsException as ex:
print(f"Insights request failed: {ex.error.code().name}")
for error in ex.failure.errors:
print(f"Error: {error.message}")
return []def find_similar_audiences(client, customer_id, baseline_audience_resource_name):
"""Find audiences similar to a baseline audience."""
audience_insights_service = client.get_service("AudienceInsightsService")
# Create baseline audience
baseline_audience = client.get_type("BasicInsightsAudience")
baseline_audience.country_location.append(
client.get_type("LocationInfo", geo_target_constant="geoTargetConstants/2840")
)
baseline_audience.user_list = baseline_audience_resource_name
request = client.get_type("GenerateInsightsFinderReportRequest")
request.customer_id = customer_id
request.baseline_audience = baseline_audience
response = audience_insights_service.generate_insights_finder_report(
request=request
)
similar_audiences = []
for audience_insights in response.audience_insights:
audience_data = {
'audience_definition': audience_insights.audience_definition,
'targetable_audience_size': audience_insights.targetable_audience_size,
'coverage_percentage': audience_insights.coverage_percentage,
'index': audience_insights.index,
'score': audience_insights.score
}
similar_audiences.append(audience_data)
return similar_audiences# User list types
class UserList:
resource_name: str
id: Optional[int]
read_only: Optional[bool]
name: Optional[str]
description: Optional[str]
membership_status: UserListMembershipStatusEnum.UserListMembershipStatus
integration_code: Optional[str]
membership_life_span: Optional[int]
size_for_display: Optional[int]
size_range_for_display: UserListSizeRangeEnum.UserListSizeRange
size_for_search: Optional[int]
size_range_for_search: UserListSizeRangeEnum.UserListSizeRange
type_: UserListTypeEnum.UserListType
closing_reason: UserListClosingReasonEnum.UserListClosingReason
access_reason: AccessReasonEnum.AccessReason
account_user_list_status: UserListAccessStatusEnum.UserListAccessStatus
eligible_for_search: Optional[bool]
eligible_for_display: Optional[bool]
match_rate_percentage: Optional[int]
# User list types (one of the following)
crm_based_user_list: CrmBasedUserListInfo
similar_user_list: SimilarUserListInfo
rule_based_user_list: RuleBasedUserListInfo
logical_user_list: LogicalUserListInfo
basic_user_list: BasicUserListInfo
lookalike_user_list: LookalikeUserListInfo
class CrmBasedUserListInfo:
app_id: Optional[str]
upload_key_type: CustomerMatchUploadKeyTypeEnum.CustomerMatchUploadKeyType
data_source_type: UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType
class RuleBasedUserListInfo:
prepopulation_status: UserListPrepopulationStatusEnum.UserListPrepopulationStatus
flexible_rule_user_list: FlexibleRuleUserListInfo
class FlexibleRuleUserListInfo:
inclusive_rule_operator: UserListFlexibleRuleOperatorEnum.UserListFlexibleRuleOperator
inclusive_operands: List[FlexibleRuleOperandInfo]
exclusive_operands: List[FlexibleRuleOperandInfo]
class FlexibleRuleOperandInfo:
rule: UserListRuleInfo
lookaback_window_days: Optional[int]
class UserListRuleInfo:
rule_type: UserListRuleTypeEnum.UserListRuleType
rule_item_groups: List[UserListRuleItemGroupInfo]
class UserListRuleItemGroupInfo:
rule_items: List[UserListRuleItemInfo]
class UserListRuleItemInfo:
name: Optional[str]
number_rule_item: UserListNumberRuleItemInfo
string_rule_item: UserListStringRuleItemInfo
date_rule_item: UserListDateRuleItemInfo
class SimilarUserListInfo:
seed_user_list: Optional[str]
# Custom audience types
class CustomAudience:
resource_name: str
id: Optional[int]
status: CustomAudienceStatusEnum.CustomAudienceStatus
name: Optional[str]
type_: CustomAudienceTypeEnum.CustomAudienceType
description: Optional[str]
members: List[CustomAudienceMember]
class CustomAudienceMember:
member_type: CustomAudienceMemberTypeEnum.CustomAudienceMemberType
keyword: Optional[str]
url: Optional[str]
place_category: Optional[int]
app: Optional[str]
# Remarketing action types
class RemarketingAction:
resource_name: str
id: Optional[int]
name: Optional[str]
tag_snippets: List[TagSnippet]
class TagSnippet:
type_: TrackingCodeTypeEnum.TrackingCodeType
page_format: TrackingCodePageFormatEnum.TrackingCodePageFormat
global_site_tag: Optional[str]
event_snippet: Optional[str]
# Audience insights types
class InsightsAudience:
country_location: List[LocationInfo]
sub_country_location: List[LocationInfo]
gender: List[GenderInfo]
age_ranges: List[AgeRangeInfo]
user_interests: List[UserInterestInfo]
user_lists: List[str]
custom_audiences: List[str]
class BasicInsightsAudience:
country_location: List[LocationInfo]
sub_country_location: List[LocationInfo]
gender: List[GenderInfo]
age_ranges: List[AgeRangeInfo]
user_interests: List[UserInterestInfo]
user_list: Optional[str]
custom_audience: Optional[str]
class AudienceCompositionSection:
dimension: AudienceInsightsDimensionEnum.AudienceInsightsDimension
breakdown: List[AudienceCompositionBreakdown]
class AudienceCompositionBreakdown:
attribute_metadata: AudienceCompositionAttribute
coverage_percentage: float
index: float
score: float
class AudienceCompositionAttribute:
attribute_value: AttributeValue
display_name: str
display_info: str
# Operation types
class UserListOperation:
update_mask: FieldMask
create: UserList
update: UserList
remove: str
class CustomAudienceOperation:
update_mask: FieldMask
create: CustomAudience
update: CustomAudience
remove: str
class RemarketingActionOperation:
update_mask: FieldMask
create: RemarketingAction
update: RemarketingAction
remove: str
# Response types
class MutateUserListsResponse:
partial_failure_error: Status
results: List[MutateUserListResult]
class MutateUserListResult:
resource_name: str
user_list: UserList
class MutateCustomAudiencesResponse:
results: List[MutateCustomAudienceResult]
class MutateCustomAudienceResult:
resource_name: str
custom_audience: CustomAudience
class GenerateAudienceCompositionInsightsResponse:
sections: List[AudienceCompositionSection]
class GenerateInsightsFinderReportResponse:
audience_insights: List[AudienceInsights]
class AudienceInsights:
audience_definition: InsightsAudience
targetable_audience_size: int
coverage_percentage: float
index: float
score: floatInstall with Tessl CLI
npx tessl i tessl/pypi-google-ads