Google Ads API AI Automation: Complete October 2025 Guide
Master Google Ads API v22 with AI-powered automation. Learn view-based conversions, AI Max reporting, and generative asset creation. Complete implementation guide with production-ready code examples for October 2025.
Key Takeaways
What's New in Google Ads API v22
Released on October 15, 2025, Google Ads API v22 introduces significant AI-powered capabilities, enhanced reporting, and improved automation features. This update represents Google's push toward AI-driven advertising and greater transparency across campaign types.
Major Features in v22
- AssetGenerationService (Beta): Generate text and image assets using generative AI based on URLs, prompts, keywords, and campaign context
- View-Based Conversions: Track engaged-view conversions for Display and Video campaigns with improved attribution
- AI Max Reporting: New
ai_max_search_term_ad_combination_viewprovides detailed performance data for AI Max for Search campaigns - Performance Max Enhancements: Image enhancement, extraction automation, and enhanced reporting with
feed_typesfield - Targetless Bidding for App Campaigns: New
OPTIMIZE_IN_APP_CONVERSIONS_WITHOUT_TARGET_CPAandOPTIMIZE_TOTAL_VALUE_WITHOUT_TARGET_ROASgoals - Smart Bidding Diversity Metrics: Target ROAS strategies on Search can retrieve time-segmented diversity metrics
These updates make Google Ads API v22 the most AI-focused release to date, enabling advertisers to automate asset creation, gain deeper insights into AI-driven campaigns, and optimize performance with enhanced bidding strategies.
View-Based Conversions: Complete Setup Guide
View-based conversions (also called engaged-view conversions) allow you to track conversions from users who viewed your Display or Video ads but didn't click. This provides more complete attribution for upper-funnel campaigns.
What Are View-Based Conversions?
View-based conversions count when a user:
- • Views your video ad for at least 10 seconds
- • Views your Display ad (meets Engaged View requirements)
- • Converts within the attribution window without clicking
- • Has not clicked any of your ads more recently
Step 1: Enable View-Based Conversions
Configure view-based conversion tracking via the API:
# Python: Enable view-based conversions
from google.ads.googleads.client import GoogleAdsClient
def enable_view_conversions(client, customer_id, conversion_action_id):
"""Enable view-based conversions for a conversion action"""
conversion_action_service = client.get_service("ConversionActionService")
conversion_action_operation = client.get_type("ConversionActionOperation")
conversion_action = conversion_action_operation.update
conversion_action.resource_name = (
f"customers/{customer_id}/conversionActions/{conversion_action_id}"
)
# Enable view-through conversion tracking
conversion_action.view_through_lookback_window_days = 30
conversion_action.include_in_conversions_metric = True
# Set counting type (ONE_PER_CLICK or MANY_PER_CLICK)
conversion_action.counting_type = client.enums.ConversionActionCountingTypeEnum.ONE_PER_CLICK
# Update field mask
field_mask = client.field_mask.build(
conversion_action_operation.update,
conversion_action
)
conversion_action_operation.update_mask.CopyFrom(field_mask)
# Execute the update
response = conversion_action_service.mutate_conversion_actions(
customer_id=customer_id,
operations=[conversion_action_operation]
)
print(f"Updated conversion action: {response.results[0].resource_name}")
return response
# Usage
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
enable_view_conversions(client, "YOUR_CUSTOMER_ID", "YOUR_CONVERSION_ACTION_ID")Step 2: Report on View-Based Conversions
# Python: Query view-based conversion metrics
def get_view_conversion_report(client, customer_id, date_range="LAST_30_DAYS"):
"""Generate report with view-based conversion data"""
ga_service = client.get_service("GoogleAdsService")
query = f"""
SELECT
campaign.name,
campaign.id,
metrics.conversions,
metrics.view_through_conversions,
metrics.all_conversions,
metrics.cost_micros,
metrics.impressions,
metrics.video_views,
segments.conversion_action_name,
segments.date
FROM campaign
WHERE segments.date DURING {date_range}
AND campaign.advertising_channel_type IN ('DISPLAY', 'VIDEO')
AND campaign.status = 'ENABLED'
ORDER BY metrics.view_through_conversions DESC
"""
response = ga_service.search_stream(customer_id=customer_id, query=query)
# Process results
results = []
for batch in response:
for row in batch.results:
results.append({
'campaign': row.campaign.name,
'campaign_id': row.campaign.id,
'click_conversions': row.metrics.conversions,
'view_conversions': row.metrics.view_through_conversions,
'all_conversions': row.metrics.all_conversions,
'cost': row.metrics.cost_micros / 1_000_000,
'impressions': row.metrics.impressions,
'video_views': row.metrics.video_views,
'conversion_action': row.segments.conversion_action_name,
'date': row.segments.date,
'view_conversion_rate': (
row.metrics.view_through_conversions / row.metrics.impressions
if row.metrics.impressions > 0 else 0
)
})
return results
# Usage
results = get_view_conversion_report(client, "YOUR_CUSTOMER_ID")
for result in results[:5]:
print(f"{result['campaign']}: {result['view_conversions']} view conversions")Best Practices
- • Use 30-day attribution window for Display
- • Use 7-14 day window for Video
- • Exclude view conversions from automated bidding
- • Monitor view-to-click conversion ratio
Common Pitfalls
- • Including views in Smart Bidding too early
- • Setting attribution window too long
- • Not distinguishing view vs click conversions
- • Forgetting to exclude search remarketing
AI Max Reporting: Access Enhanced Insights
Google Ads API v22 introduces the ai_max_search_term_ad_combination_view report, providing unprecedented transparency into AI Max for Search campaign performance. This report shows how different combinations of search terms, headlines, and landing pages perform.
What AI Max Reporting Reveals
- • Performance metrics for search term + headline + landing page combinations
- • Which AI-generated headlines perform best for specific queries
- • Landing page effectiveness by search intent and user segment
- • Real conversion data to optimize AI Max campaign structure
- • Impression share and quality metrics at the combination level
Query AI Max Performance Data
# Python: Access AI Max reporting
def get_ai_max_performance(client, customer_id, campaign_id):
"""Query AI Max search term ad combination performance"""
ga_service = client.get_service("GoogleAdsService")
query = f"""
SELECT
ai_max_search_term_ad_combination_view.search_term,
ai_max_search_term_ad_combination_view.headline,
ai_max_search_term_ad_combination_view.landing_page_url,
campaign.name,
ad_group.name,
metrics.impressions,
metrics.clicks,
metrics.conversions,
metrics.cost_micros,
metrics.average_cpc,
metrics.conversion_rate,
metrics.cost_per_conversion,
segments.date
FROM ai_max_search_term_ad_combination_view
WHERE campaign.id = {campaign_id}
AND segments.date DURING LAST_30_DAYS
AND metrics.impressions > 100
ORDER BY metrics.conversions DESC
LIMIT 100
"""
response = ga_service.search_stream(customer_id=customer_id, query=query)
# Analyze combinations
combinations = []
for batch in response:
for row in batch.results:
view = row.ai_max_search_term_ad_combination_view
combinations.append({
'search_term': view.search_term,
'headline': view.headline,
'landing_page': view.landing_page_url,
'campaign': row.campaign.name,
'ad_group': row.ad_group.name,
'impressions': row.metrics.impressions,
'clicks': row.metrics.clicks,
'conversions': row.metrics.conversions,
'cost': row.metrics.cost_micros / 1_000_000,
'avg_cpc': row.metrics.average_cpc / 1_000_000,
'conversion_rate': row.metrics.conversion_rate,
'cpa': row.metrics.cost_per_conversion,
'date': row.segments.date
})
return combinations
# Analyze top-performing combinations
combinations = get_ai_max_performance(client, "YOUR_CUSTOMER_ID", "CAMPAIGN_ID")
# Find best headlines by search intent
from collections import defaultdict
headline_performance = defaultdict(list)
for combo in combinations:
headline_performance[combo['headline']].append({
'search_term': combo['search_term'],
'conversions': combo['conversions'],
'conversion_rate': combo['conversion_rate']
})
# Print top headlines
for headline, performance in sorted(
headline_performance.items(),
key=lambda x: sum(p['conversions'] for p in x[1]),
reverse=True
)[:5]:
total_conversions = sum(p['conversions'] for p in performance)
avg_conv_rate = sum(p['conversion_rate'] for p in performance) / len(performance)
print(f"Headline: {headline}")
print(f" Total Conversions: {total_conversions}")
print(f" Avg Conversion Rate: {avg_conv_rate:.2%}")
print(f" Used for {len(performance)} search terms")Optimization Strategies
High-Performing Patterns
- • Identify winning headline formulas
- • Map best landing pages to intents
- • Scale successful combinations
- • Create more similar ad variations
Low-Performing Culling
- • Pause poor-performing headlines
- • Add negative keywords for bad matches
- • Redirect ineffective landing pages
- • Adjust AI Max settings based on data
AI-Powered Asset Generation Service
The new AssetGenerationService (beta) in API v22 allows you to generate text and image assets automatically using generative AI. This feature can create headlines, descriptions, and images based on your inputs like URLs, prompts, keywords, and existing campaign context.
Text Asset Generation
Generate headlines and descriptions from various inputs:
# Python: Generate text assets with AI
def generate_text_assets(client, customer_id, final_url, keywords=None, prompt=None):
"""Generate ad headlines and descriptions using AI"""
asset_generation_service = client.get_service("AssetGenerationService")
# Build request
request = client.get_type("GenerateTextAssetsRequest")
request.customer_id = customer_id
# Input: Final URL (required)
request.final_url = final_url
# Optional: Add keywords for context
if keywords:
request.keywords.extend(keywords)
# Optional: Add freeform prompt for customization
if prompt:
request.prompt = prompt
# Optional: Use existing campaign context
# request.campaign_id = "YOUR_CAMPAIGN_ID"
# Configure generation parameters
request.number_of_headlines = 10
request.number_of_descriptions = 5
request.headline_length_preference = "SHORT" # SHORT, MEDIUM, or LONG
# Generate assets
response = asset_generation_service.generate_text_assets(request=request)
# Process results
generated_assets = {
'headlines': [],
'descriptions': []
}
for headline in response.headlines:
generated_assets['headlines'].append({
'text': headline.text,
'length': len(headline.text),
'confidence_score': headline.confidence_score
})
for description in response.descriptions:
generated_assets['descriptions'].append({
'text': description.text,
'length': len(description.text),
'confidence_score': description.confidence_score
})
return generated_assets
# Usage example
assets = generate_text_assets(
client=client,
customer_id="YOUR_CUSTOMER_ID",
final_url="https://example.com/product-page",
keywords=["affordable", "high-quality", "fast shipping"],
prompt="Focus on eco-friendly benefits and sustainability"
)
print("Generated Headlines:")
for headline in assets['headlines'][:5]:
print(f" {headline['text']} (confidence: {headline['confidence_score']:.2f})")
print("\nGenerated Descriptions:")
for desc in assets['descriptions'][:3]:
print(f" {desc['text']} (confidence: {desc['confidence_score']:.2f})")Image Asset Generation
Generate images from existing assets or create new ones:
# Python: Generate image assets with AI
def generate_image_assets(
client,
customer_id,
final_url=None,
existing_images=None,
prompt=None
):
"""Generate image assets using generative AI"""
asset_generation_service = client.get_service("AssetGenerationService")
request = client.get_type("GenerateImageAssetsRequest")
request.customer_id = customer_id
# Option 1: Generate from URL
if final_url:
request.final_url = final_url
# Option 2: Recontextualize existing product images
if existing_images:
for image_url in existing_images:
request.existing_image_urls.append(image_url)
# Option 3: Use freeform prompt
if prompt:
request.prompt = prompt
# Configure image parameters
request.aspect_ratio = "SQUARE" # SQUARE, LANDSCAPE, or PORTRAIT
request.number_of_images = 5
# Generate images
response = asset_generation_service.generate_image_assets(request=request)
# Process results
generated_images = []
for image in response.images:
generated_images.append({
'url': image.url,
'asset_id': image.asset_id,
'width': image.width,
'height': image.height,
'size_bytes': image.size_bytes
})
return generated_images
# Usage: Generate images from product page
images = generate_image_assets(
client=client,
customer_id="YOUR_CUSTOMER_ID",
final_url="https://example.com/product",
prompt="Professional lifestyle photos with warm lighting"
)
print("Generated Images:")
for img in images:
print(f" Asset ID: {img['asset_id']}")
print(f" Dimensions: {img['width']}x{img['height']}")
print(f" URL: {img['url']}")Best Practices for AI Asset Generation
Input Quality
- • Use high-quality landing pages
- • Provide specific keywords
- • Write clear prompts
- • Include brand guidelines
Review & Test
- • Always review generated assets
- • A/B test AI vs human-created
- • Monitor confidence scores
- • Iterate based on performance
Integration
- • Automate for large catalogs
- • Combine with existing assets
- • Use for seasonal variations
- • Scale winning combinations
Performance Max Campaign Enhancements
Google Ads API v22 brings significant improvements to Performance Max campaigns, including image enhancement automation, image extraction features, and enhanced reporting capabilities with new segments and the feed_types field.
Image Enhancement
Automatically enhance product images for better performance:
- • Background removal and replacement
- • Automatic cropping and resizing
- • Quality improvements and filters
- • Format optimization for each placement
Enhanced Reporting
New segments and fields for better insights:
- • feed_types field for asset source tracking
- • New performance segments by asset group
- • Detailed conversion path reporting
- • Enhanced audience insights
Query Performance Max with New Fields
# Python: Query PMax campaigns with v22 enhancements
def get_pmax_performance(client, customer_id):
"""Query Performance Max campaigns with enhanced reporting"""
ga_service = client.get_service("GoogleAdsService")
query = """
SELECT
campaign.name,
campaign.id,
asset_group.name,
asset_group.id,
asset_group_asset.feed_types,
metrics.impressions,
metrics.clicks,
metrics.conversions,
metrics.all_conversions,
metrics.cost_micros,
metrics.conversion_value,
segments.asset_interaction_target.asset,
segments.asset_interaction_target.interaction_on_this_asset,
segments.date
FROM asset_group_asset
WHERE campaign.advertising_channel_type = 'PERFORMANCE_MAX'
AND segments.date DURING LAST_30_DAYS
AND campaign.status = 'ENABLED'
ORDER BY metrics.conversions DESC
"""
response = ga_service.search_stream(customer_id=customer_id, query=query)
# Analyze by feed type
performance_by_feed = {}
for batch in response:
for row in batch.results:
feed_types = row.asset_group_asset.feed_types
for feed_type in feed_types:
if feed_type not in performance_by_feed:
performance_by_feed[feed_type] = {
'impressions': 0,
'clicks': 0,
'conversions': 0,
'cost': 0,
'value': 0
}
performance_by_feed[feed_type]['impressions'] += row.metrics.impressions
performance_by_feed[feed_type]['clicks'] += row.metrics.clicks
performance_by_feed[feed_type]['conversions'] += row.metrics.conversions
performance_by_feed[feed_type]['cost'] += row.metrics.cost_micros / 1_000_000
performance_by_feed[feed_type]['value'] += row.metrics.conversion_value
# Calculate ROAS by feed type
for feed_type, data in performance_by_feed.items():
data['roas'] = data['value'] / data['cost'] if data['cost'] > 0 else 0
data['cpa'] = data['cost'] / data['conversions'] if data['conversions'] > 0 else 0
return performance_by_feed
# Usage
feed_performance = get_pmax_performance(client, "YOUR_CUSTOMER_ID")
print("Performance by Feed Type:")
for feed_type, metrics in sorted(
feed_performance.items(),
key=lambda x: x[1]['conversions'],
reverse=True
):
print(f"\n{'{'}feed_type{'}'}:")
print(f" Conversions: {'{'}metrics['conversions']:.0f{'}'}")
print(f" ROAS: {'{'}metrics['roas']:.2f{'}'}")
print(f" CPA: {metrics['cpa']:.2f{'}'}")Smart Bidding & Targetless Bidding
API v22 introduces targetless bidding for App campaigns, allowing rapid scaling without specific CPA or ROAS targets. Additionally, Target ROAS strategies on Search campaigns now support time-segmented diversity metrics for better performance analysis.
Targetless Bidding for App Campaigns
Perfect for rapid scaling when you don't have enough conversion data for target-based bidding:
# Python: Set up targetless bidding for App campaigns
def setup_targetless_bidding(client, customer_id, campaign_id, goal_type):
"""Configure targetless bidding for rapid scaling"""
campaign_service = client.get_service("CampaignService")
campaign_operation = client.get_type("CampaignOperation")
campaign = campaign_operation.update
campaign.resource_name = f"customers/{customer_id}/campaigns/{campaign_id}"
# Choose targetless bidding goal
if goal_type == "CONVERSIONS":
# Optimize for in-app conversions without target CPA
campaign.bidding_strategy_type = (
client.enums.BiddingStrategyTypeEnum.OPTIMIZE_IN_APP_CONVERSIONS_WITHOUT_TARGET_CPA
)
elif goal_type == "VALUE":
# Optimize for total value without target ROAS
campaign.bidding_strategy_type = (
client.enums.BiddingStrategyTypeEnum.OPTIMIZE_TOTAL_VALUE_WITHOUT_TARGET_ROAS
)
# Set field mask
field_mask = client.field_mask.build(
campaign_operation.update,
campaign
)
campaign_operation.update_mask.CopyFrom(field_mask)
# Apply update
response = campaign_service.mutate_campaigns(
customer_id=customer_id,
operations=[campaign_operation]
)
print(f"Updated campaign to targetless bidding: {response.results[0].resource_name}")
return response
# Usage
setup_targetless_bidding(
client=client,
customer_id="YOUR_CUSTOMER_ID",
campaign_id="YOUR_APP_CAMPAIGN_ID",
goal_type="CONVERSIONS"
)Target ROAS Diversity Metrics
Query time-segmented diversity metrics for Search campaigns using Target ROAS:
# Python: Retrieve diversity metrics for Target ROAS
def get_diversity_metrics(client, customer_id, campaign_id):
"""Get time-segmented diversity metrics for Target ROAS campaigns"""
ga_service = client.get_service("GoogleAdsService")
query = f"""
SELECT
campaign.name,
metrics.impressions,
metrics.clicks,
metrics.conversions,
metrics.conversion_value,
metrics.average_cpc,
metrics.search_budget_lost_impression_share,
metrics.search_rank_lost_impression_share,
segments.hour,
segments.day_of_week,
segments.device
FROM campaign
WHERE campaign.id = {campaign_id}
AND campaign.bidding_strategy_type = 'TARGET_ROAS'
AND segments.date DURING LAST_7_DAYS
ORDER BY segments.hour, segments.device
"""
response = ga_service.search_stream(customer_id=customer_id, query=query)
# Analyze diversity by time and device
diversity_analysis = {
'by_hour': {},
'by_device': {},
'by_day': {}
}
for batch in response:
for row in batch.results:
hour = row.segments.hour
device = row.segments.device.name
day = row.segments.day_of_week.name
# Track performance by hour
if hour not in diversity_analysis['by_hour']:
diversity_analysis['by_hour'][hour] = {
'impressions': 0,
'conversions': 0,
'value': 0,
'cost': 0
}
diversity_analysis['by_hour'][hour]['impressions'] += row.metrics.impressions
diversity_analysis['by_hour'][hour]['conversions'] += row.metrics.conversions
diversity_analysis['by_hour'][hour]['value'] += row.metrics.conversion_value
diversity_analysis['by_hour'][hour]['cost'] += row.metrics.cost_micros / 1_000_000
# Similar tracking for device and day...
# Calculate ROAS variance
for hour, metrics in diversity_analysis['by_hour'].items():
metrics['roas'] = metrics['value'] / metrics['cost'] if metrics['cost'] > 0 else 0
return diversity_analysis
# Usage and analysis
diversity = get_diversity_metrics(client, "YOUR_CUSTOMER_ID", "CAMPAIGN_ID")
print("ROAS by Hour:")
for hour in sorted(diversity['by_hour'].keys()):
metrics = diversity['by_hour'][hour]
print(f" Hour {hour:02d}: ROAS = {metrics['roas']:.2f}")Production-Ready Code Examples
Here are complete, production-ready examples integrating multiple v22 features for common automation scenarios:
Example: Automated Campaign Creator with AI Assets
# Python: Complete automation - create campaign with AI-generated assets
from google.ads.googleads.client import GoogleAdsClient
import pandas as pd
class CampaignAutomator:
def __init__(self, client, customer_id):
self.client = client
self.customer_id = customer_id
def create_campaign_with_ai_assets(self, product_data):
"""
Create complete campaign with AI-generated assets
Args:
product_data: dict with 'name', 'url', 'keywords', 'budget'
"""
# Step 1: Generate text assets
print("Generating AI text assets...")
text_assets = self.generate_assets(
final_url=product_data['url'],
keywords=product_data['keywords']
)
# Step 2: Generate image assets
print("Generating AI image assets...")
image_assets = self.generate_images(
final_url=product_data['url']
)
# Step 3: Create campaign
print("Creating campaign...")
campaign = self.create_campaign(
name=product_data['name'],
budget=product_data['budget']
)
# Step 4: Create ad group
print("Creating ad group...")
ad_group = self.create_ad_group(
campaign_id=campaign.id,
name=f"{product_data['name']} - Ad Group"
)
# Step 5: Create responsive search ad with AI assets
print("Creating responsive search ad...")
ad = self.create_responsive_ad(
ad_group_id=ad_group.id,
headlines=[h['text'] for h in text_assets['headlines'][:15]],
descriptions=[d['text'] for d in text_assets['descriptions'][:4]],
final_url=product_data['url']
)
# Step 6: Add keywords
print("Adding keywords...")
self.add_keywords(
ad_group_id=ad_group.id,
keywords=product_data['keywords']
)
print(f"Campaign created successfully: {campaign.id}")
return {
'campaign_id': campaign.id,
'ad_group_id': ad_group.id,
'ad_id': ad.id
}
def generate_assets(self, final_url, keywords):
"""Generate text assets using AI"""
asset_gen_service = self.client.get_service("AssetGenerationService")
request = self.client.get_type("GenerateTextAssetsRequest")
request.customer_id = self.customer_id
request.final_url = final_url
request.keywords.extend(keywords)
request.number_of_headlines = 15
request.number_of_descriptions = 4
response = asset_gen_service.generate_text_assets(request=request)
return {
'headlines': [
{'text': h.text, 'confidence': h.confidence_score}
for h in response.headlines
],
'descriptions': [
{'text': d.text, 'confidence': d.confidence_score}
for d in response.descriptions
]
}
def generate_images(self, final_url):
"""Generate image assets using AI"""
asset_gen_service = self.client.get_service("AssetGenerationService")
request = self.client.get_type("GenerateImageAssetsRequest")
request.customer_id = self.customer_id
request.final_url = final_url
request.number_of_images = 5
request.aspect_ratio = "SQUARE"
response = asset_gen_service.generate_image_assets(request=request)
return [
{
'url': img.url,
'asset_id': img.asset_id,
'dimensions': f"{img.width}x{img.height}"
}
for img in response.images
]
def create_campaign(self, name, budget):
"""Create campaign with standard settings"""
campaign_service = self.client.get_service("CampaignService")
# Create budget
budget_resource = self.create_budget(budget)
# Create campaign operation
campaign_operation = self.client.get_type("CampaignOperation")
campaign = campaign_operation.create
campaign.name = name
campaign.advertising_channel_type = (
self.client.enums.AdvertisingChannelTypeEnum.SEARCH
)
campaign.status = self.client.enums.CampaignStatusEnum.PAUSED
campaign.campaign_budget = budget_resource
campaign.network_settings.target_google_search = True
campaign.network_settings.target_search_network = True
# Set bidding strategy
campaign.manual_cpc.enhanced_cpc_enabled = True
response = campaign_service.mutate_campaigns(
customer_id=self.customer_id,
operations=[campaign_operation]
)
return response.results[0]
def create_budget(self, amount_micros):
"""Create campaign budget"""
budget_service = self.client.get_service("CampaignBudgetService")
budget_operation = self.client.get_type("CampaignBudgetOperation")
budget = budget_operation.create
budget.name = f"Budget {amount_micros}"
budget.delivery_method = (
self.client.enums.BudgetDeliveryMethodEnum.STANDARD
)
budget.amount_micros = amount_micros
response = budget_service.mutate_campaign_budgets(
customer_id=self.customer_id,
operations=[budget_operation]
)
return response.results[0].resource_name
def create_ad_group(self, campaign_id, name):
"""Create ad group"""
ad_group_service = self.client.get_service("AdGroupService")
ad_group_operation = self.client.get_type("AdGroupOperation")
ad_group = ad_group_operation.create
ad_group.name = name
ad_group.status = self.client.enums.AdGroupStatusEnum.ENABLED
ad_group.campaign = f"customers/{self.customer_id}/campaigns/{campaign_id}"
ad_group.cpc_bid_micros = 1000000 # $1.00
response = ad_group_service.mutate_ad_groups(
customer_id=self.customer_id,
operations=[ad_group_operation]
)
return response.results[0]
def create_responsive_ad(self, ad_group_id, headlines, descriptions, final_url):
"""Create responsive search ad"""
ad_group_ad_service = self.client.get_service("AdGroupAdService")
ad_group_ad_operation = self.client.get_type("AdGroupAdOperation")
ad_group_ad = ad_group_ad_operation.create
ad_group_ad.ad_group = (
f"customers/{self.customer_id}/adGroups/{ad_group_id}"
)
ad_group_ad.status = self.client.enums.AdGroupAdStatusEnum.ENABLED
# Set ad details
ad_group_ad.ad.final_urls.append(final_url)
# Add headlines (up to 15)
for headline in headlines[:15]:
headline_asset = self.client.get_type("AdTextAsset")
headline_asset.text = headline
ad_group_ad.ad.responsive_search_ad.headlines.append(headline_asset)
# Add descriptions (up to 4)
for description in descriptions[:4]:
desc_asset = self.client.get_type("AdTextAsset")
desc_asset.text = description
ad_group_ad.ad.responsive_search_ad.descriptions.append(desc_asset)
response = ad_group_ad_service.mutate_ad_group_ads(
customer_id=self.customer_id,
operations=[ad_group_ad_operation]
)
return response.results[0]
def add_keywords(self, ad_group_id, keywords):
"""Add keywords to ad group"""
ad_group_criterion_service = self.client.get_service(
"AdGroupCriterionService"
)
operations = []
for keyword in keywords:
operation = self.client.get_type("AdGroupCriterionOperation")
criterion = operation.create
criterion.ad_group = (
f"customers/{self.customer_id}/adGroups/{ad_group_id}"
)
criterion.status = self.client.enums.AdGroupCriterionStatusEnum.ENABLED
criterion.keyword.text = keyword
criterion.keyword.match_type = (
self.client.enums.KeywordMatchTypeEnum.BROAD
)
operations.append(operation)
response = ad_group_criterion_service.mutate_ad_group_criteria(
customer_id=self.customer_id,
operations=operations
)
return response.results
# Usage
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
automator = CampaignAutomator(client, "YOUR_CUSTOMER_ID")
# Create campaign with AI-generated assets
result = automator.create_campaign_with_ai_assets({
'name': 'AI-Powered Campaign - Winter Sale',
'url': 'https://example.com/winter-sale',
'keywords': ['winter jackets', 'warm coats', 'outerwear sale'],
'budget': 50_000_000 # $50/day
})
print(f"Campaign ID: {result['campaign_id']}")
print(f"Ad Group ID: {result['ad_group_id']}")
print(f"Ad ID: {result['ad_id']}")Best Practices & API Limits
Follow these best practices to ensure optimal performance and avoid common pitfalls when working with Google Ads API v22:
Rate Limits & Quotas
- • Daily operations: 15,000 (Standard), 10,000 (Basic)
- • Batch size: Maximum 5,000 operations per request
- • Requests per second: Throttle to 10-20 RPS
- • Asset generation: Beta limits may apply
- • Concurrent requests: Limit to 10 parallel
Optimization Tips
- • Use search_stream() for large datasets
- • Batch mutations to reduce API calls
- • Cache AI-generated assets for reuse
- • Implement exponential backoff for retries
- • Monitor API quota usage proactively
Common Pitfalls with v22 Features
- •AI Asset Generation: Always review generated assets before deployment; confidence scores don't guarantee brand alignment
- •View-Based Conversions: Don't include in Smart Bidding until you have sufficient data (30+ days)
- •Targetless Bidding: Monitor closely during first 2 weeks; costs can spike during learning phase
- •AI Max Reporting: Data may be sampled for high-traffic campaigns; use date ranges wisely
Migration Guide: Upgrading to API v22
If you're currently using an earlier version of the Google Ads API, here's how to migrate to v22 and take advantage of the new features:
Step 1: Update Client Libraries
Python:
pip install --upgrade google-ads==22.0.0Node.js:
npm install google-ads-api@22.0.0Step 2: Update API Version in Requests
# Python: Update to v22
from google.ads.googleads.client import GoogleAdsClient
# Configuration will automatically use the correct version
# based on your installed library version
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
# Verify version
print(f"Using Google Ads API version: {client.get_service('GoogleAdsService')._version}")Step 3: Test New Features Incrementally
- Week 1: Test AI asset generation on non-critical campaigns
- Week 2: Enable view-based conversions tracking and monitor
- Week 3: Implement AI Max reporting queries
- Week 4: Roll out to production campaigns
Breaking Changes & Deprecations
While v22 maintains backward compatibility with most features, be aware of these changes:
- • Some older campaign types may have limited support for new features
- • AssetGenerationService is beta; API surface may change
- • View-based conversions require updated conversion tracking tags
- • AI Max reporting requires AI Max for Search campaigns (not all accounts)
Real-World Use Cases
See how businesses are leveraging Google Ads API v22 features to drive exceptional results:
Case Study: E-commerce Retailer - AI Asset Automation
A fashion retailer with 5,000+ SKUs automated asset creation using the AssetGenerationService:
Challenge
Creating unique ad copy for thousands of products manually
Solution
AI-generated headlines and descriptions from product pages
Results
85% time savings, 23% higher CTR vs manual ads
Case Study: Mobile App - Targetless Bidding Success
A gaming app used targetless bidding to rapidly scale user acquisition:
Challenge
Insufficient conversion data for target-based bidding
Solution
OPTIMIZE_IN_APP_CONVERSIONS_WITHOUT_TARGET_CPA
Results
3x install volume in 14 days, 18% lower CPI
Case Study: B2B SaaS - View-Based Conversion Tracking
A SaaS company improved attribution for their video campaigns:
Challenge
Undervaluing YouTube campaigns due to click-only attribution
Solution
Enabled view-based conversions with 7-day window
Results
42% increase in attributed conversions, 2.1x ROAS
Ready to Implement Google Ads API v22?
Let our PPC automation experts help you leverage AI-powered features, view-based conversions, and advanced reporting to maximize your advertising ROI.
Essential Resources
Frequently Asked Questions
Related Articles
Explore more PPC automation strategies and API integration guides