CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-google-ads

Client library for the Google Ads API providing comprehensive access to advertising management, reporting, and analytics capabilities.

Pending
Overview
Eval results
Files

audience-management.mddocs/

Audience Management

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.

Capabilities

User List Operations

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 Operations

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 Operations

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 Operations

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
    """

User List Creation Examples

Website Remarketing List

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
)

Customer Match List (Email)

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
)

Similar Audiences (Lookalike)

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_name

Custom Audience Examples

Interest-Based Custom Audience

def 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
)

Purchase Intent Custom Audience

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_name

Audience Targeting Examples

Apply Audience to Campaign

def 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_name

Audience Exclusions

def 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_name

Audience Insights Examples

Generate Audience Composition Report

def 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 []

Audience Finder Report

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

Types

# 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: float

Install with Tessl CLI

npx tessl i tessl/pypi-google-ads

docs

ad-management.md

asset-management.md

audience-management.md

batch-operations.md

campaign-management.md

client-setup.md

conversion-tracking.md

index.md

reporting-search.md

targeting-keywords.md

tile.json