Performance Max campaigns with pay-per-lead goals empower local businesses to
reach customers. These campaigns serve Local Services Ads, and are therefore
also referred to as Local Services Performance Max campaigns and configured
using local_services_* fields and services in the Google Ads API. With this setup,
your marketing spend is focused on direct customer connections. You're charged
only when a potential customer contacts your business directly through your ad,
rather than when they click on your ad.
Before you begin, ensure you have an active developer token with standard access. For more information, see the Get started guide.
Campaign creation workflow
The steps for creating a Performance Max for pay-per-lead goals campaign are as follows:
- Complete account-level prerequisites
- Retrieve the Google Business Profile listing and location asset
- Create campaign resources atomically (
GoogleAdsService.Mutate) - Enable the campaign and complete business verification
Complete account-level prerequisites
If you are creating campaigns for an existing Google Ads account, complete the following prerequisites in the account before creating the campaign. If you are creating a new Google Ads account at the same time, complete these steps before the campaign creation operation is executed:
- Accept Terms of Service (Google Ads UI only): You must accept the Local
Services Terms of Service in the Google Ads Account Settings page. This
agreement cannot be accepted programmatically through the API. Creating or
enabling a campaign without accepting the agreement returns
CampaignError.LOCAL_SERVICES_AGREEMENT_REQUIRED. - Google Business Profile link (Google Ads UI or API): Link the business
profile to the Google Ads account (in the Google Ads UI under Data Manager >
Linked Accounts, or programmatically using a
LOCATION_SYNCtypedAssetSet). Note that creating aLOCATION_SYNCAssetSetalone does not activate location syncing for the account; you must also attach it to the customer usingCustomerAssetSet(CustomerAssetSetService.MutateCustomerAssetSets) and supply an OAuth 2.0http_authorization_tokenwith thehttps://www.googleapis.com/auth/business.managescope. For more information, see Create a location sync asset set and attach it to the customer. This synchronizes business locations as accountLOCATIONassets into the Google Ads account.
Retrieve the Google Business Profile listing and location asset
Query the asset resource using GoogleAdsService.Search,
relying on the LOCATION assets synced after linking the Google Business
Profile in the preceding Complete account-level prerequisites
section.
The query retrieves the Google Business Profile listing_id required for
campaign settings and the asset.resource_name needed to link to the
campaign's STATIC_LOCATION_GROUP AssetSet using
AssetSetAsset:
SELECT
asset.id,
asset.name,
asset.location_asset.place_id,
asset.location_asset.business_profile_locations
FROM asset
WHERE asset.type = 'LOCATION'
Create campaign resources atomically (GoogleAdsService.Mutate)
Campaigns with pay-per-lead goals use the following set of resources:
- Campaign budget
- Campaign
- Campaign criteria
- Location targeting group (
AssetSetandAssetSetAsset) - Campaign asset set
- Asset groups
- Asset group signals
Given the specific setup requirements for campaigns with pay-per-lead goals,
bundle all operations into a single atomic GoogleAdsService.Mutate
request to prevent incomplete configurations and ensure transactional
integrity.
CampaignBudget (CREATE)
Define your daily campaign budget:
amount_micros: The daily budget amount in micros.delivery_method:STANDARD.explicitly_shared: Must be set tofalse. Performance Max campaigns cannot use shared budgets.
Campaign (CREATE)
Only one non-removed Local Services Performance Max campaign is allowed per
customer account; creating a second returns
CampaignError.LOCAL_SERVICES_MULTIPLE_PERFORMANCE_MAX_CAMPAIGNS_NOT_ALLOWED.
name: Required name for the campaign.campaign_budget: Temporary resource name of theCampaignBudgetcreated in the same request.advertising_channel_type: Must be set toPERFORMANCE_MAX.brand_guidelines_enabled: Must be set tofalse. Unlike standard Performance Max campaigns (which default tobrand_guidelines_enabled = trueand require linkingBUSINESS_NAMEandLOGOCampaignAssetresources), Local Services Performance Max campaigns setbrand_guidelines_enabled = false.pmax_campaign_settings.local_services_enabled: Must be set totrue(immutable boolean; cannot be modified after creation).pmax_campaign_settings.local_services_pmax_campaign_settings:country_code: Required two-letter ISO-3166 country code ('US'). Validated at creation time.listing_id: Required numeric Google Business Profile listing ID representing the provider's location. Validated on campaign creation; an invalid ID returnsCampaignError.INVALID_LOCAL_SERVICES_PERFORMANCE_MAX_LISTING_ID.- Optional:
phone_numbers: RepeatedLocalServicesPhoneNumbermessage specifying dedicated tracking or business phone numbers (phone_number,country_code, andGlsPhoneNumberTypephone_number_type). If omitted, the call number defaults to the phone number on the linked Google Business Profile listing, and is required if the Business Profile listing does not have a phone number. Supportedphone_number_typevalues areDESTINATION_PHONE_NUMBER_FOR_ADS(for call leads) andDESTINATION_PHONE_NUMBER_FOR_SMS_ONLY(optional, for message lead SMS notifications). - Optional:
founding_year: Business establishment year (such as1998). - Optional:
navigational_query_leads_enabled: Boolean indicating whether to receive leads from navigational brand queries.
maximize_conversions: Required bidding strategy message configuringMAXIMIZE_CONVERSIONSbidding (with an optionaltarget_cpa_micros). Target ROAS and manual bidding are not supported.status: Set toPAUSEDon creation until asset groups, signals, and business verifications are finalized.
CampaignCriterion (CREATE)
Define targeting parameters for the campaign by bundling one operation per criterion, linking to the temporary campaign resource name:
- Language targeting (
language): Enforced strictly as English (languageConstants/1000) for US campaigns. Other languages are rejected at mutate time. - Service area location targeting (
location): Local Services Performance Max campaigns must have at least one positive location criterion defining the service area (removing all locations returnsCampaignCriterionError.CANNOT_REMOVE_ALL_LOCATIONS_FROM_LOCAL_SERVICES_PMAX_CAMPAIGN). Both positive inclusions and exclusions are supported at the city, county, postal code, or state level within the campaign's declaredcountry_code(US). Country-level targeting is disallowed and rejected withCampaignCriterionError.CANNOT_TARGET_COUNTRY_FOR_LOCAL_SERVICES_CAMPAIGN. Resolve criterion IDs usingGeoTargetConstantService.SuggestGeoTargetConstants, Google Ads Query Language queryinggeo_target_constant, or the Google Ads Geotargets Reference Table. - Optional: Custom ad schedule (
ad_schedule): Defaults to 24/7 delivery if omitted. Restrict delivery using positivead_schedulecriteria.
Location targeting group (AssetSet and AssetSetAsset) (CREATE)
Create a STATIC_LOCATION_GROUP typed AssetSet with
location_group_parent_asset_set_id set to the ID of the account's active
LOCATION_SYNC AssetSet, and link the specific synced LOCATION asset using
AssetSetAsset.
For more details, see the Location Assets guide.
CampaignAssetSet (CREATE)
Link the campaign to the STATIC_LOCATION_GROUP asset set. Once linked, this
association is immutable and cannot be removed
(AssetSetLinkError.ASSET_SET_LINK_CANNOT_BE_REMOVED).
When partial_failure = false (the default for GoogleAdsService.Mutate), any
validation failure across the bundled operations rolls back the entire
transaction atomically. The following three CampaignAssetSet validation rules
are enforced:
- Only one
STATIC_LOCATION_GROUPAssetSetcan be linked to the campaign (AssetSetLinkError.DUPLICATE_ASSET_SET_LINK). - The
STATIC_LOCATION_GROUPcan contain at most one activeLOCATIONasset. - The linked
LOCATIONasset's listing ID must matchcampaign.pmax_campaign_settings.local_services_pmax_campaign_settings.listing_id(AssetSetLinkError.LOCATION_ASSET_DOES_NOT_MATCH_CAMPAIGN_LISTING_ID).
AssetGroup (CREATE)
Configure the Local Services asset group. Unlike standard Performance Max
campaigns, Local Services Performance Max asset groups do not require
AssetGroupAsset resources (headlines, descriptions, or images) or
final_urls.
name: Required name for the asset group.campaign: Temporary resource name of theCampaigncreated in the same request.status: Must be set toENABLEDon creation.google_local_services_info.category_id: Standardized category ID (such asxcat:service_area_business_plumber). Specifying an unsupported category returnsAssetGroupError.UNSUPPORTED_LOCAL_SERVICES_CATEGORY.- Optional:
google_local_services_info.callouts: RepeatedLocalServicesCalloutmessage (maximum of 6 callouts allowed per asset group) withcallout_id.
AssetGroupSignal (CREATE)
Unlike standard Performance Max campaigns where signals are optional, Local
Services Performance Max campaigns require at least one local_services_id
AssetGroupSignal per asset group (removing all signals returns
AssetGroupSignalError.CANNOT_REMOVE_ALL_SIGNALS).
local_services_id is a LocalServiceIdInfo message
where you populate local_services_id.service_id with a valid job type ID (for
example, {"local_services_id": {"service_id": "install_faucet"}}).
AssetGroupSignal resources are immutable (CREATE and REMOVE only; no
UPDATE).
Example atomic mutate request
The following REST JSON example demonstrates bundling all operations into a
single POST /v26/customers/{customer_id}/googleAds:mutate
request using temporary resource names:
{
"mutateOperations": [
{
"campaignBudgetOperation": {
"create": {
"resourceName": "customers/{customer_id}/campaignBudgets/-1",
"name": "Local Services PMax Budget",
"amountMicros": "50000000",
"deliveryMethod": "STANDARD",
"explicitlyShared": false
}
}
},
{
"campaignOperation": {
"create": {
"resourceName": "customers/{customer_id}/campaigns/-2",
"name": "Local Services PMax Campaign",
"advertisingChannelType": "PERFORMANCE_MAX",
"status": "PAUSED",
"campaignBudget": "customers/{customer_id}/campaignBudgets/-1",
"brandGuidelinesEnabled": false,
"maximizeConversions": {},
"pmaxCampaignSettings": {
"localServicesEnabled": true,
"localServicesPmaxCampaignSettings": {
"countryCode": "US",
"listingId": "123456789",
"phoneNumbers": [
{
"phoneNumber": "+18005550100",
"countryCode": "US",
"phoneNumberType": "DESTINATION_PHONE_NUMBER_FOR_ADS"
}
],
"foundingYear": "1998",
"navigationalQueryLeadsEnabled": true
}
}
}
}
},
{
"campaignCriterionOperation": {
"create": {
"campaign": "customers/{customer_id}/campaigns/-2",
"language": {
"languageConstant": "languageConstants/1000"
}
}
}
},
{
"campaignCriterionOperation": {
"create": {
"campaign": "customers/{customer_id}/campaigns/-2",
"location": {
"geoTargetConstant": "geoTargetConstants/1014221"
}
}
}
},
{
"campaignCriterionOperation": {
"create": {
"campaign": "customers/{customer_id}/campaigns/-2",
"adSchedule": {
"dayOfWeek": "MONDAY",
"startHour": 9,
"startMinute": "ZERO",
"endHour": 17,
"endMinute": "ZERO"
}
}
}
},
{
"assetSetOperation": {
"create": {
"resourceName": "customers/{customer_id}/assetSets/-3",
"name": "Local Services Location Group",
"type": "STATIC_LOCATION_GROUP",
"locationGroupParentAssetSetId": "LOCATION_SYNC_ASSET_SET_ID"
}
}
},
{
"assetSetAssetOperation": {
"create": {
"assetSet": "customers/{customer_id}/assetSets/-3",
"asset": "customers/{customer_id}/assets/LOCATION_ASSET_ID"
}
}
},
{
"campaignAssetSetOperation": {
"create": {
"campaign": "customers/{customer_id}/campaigns/-2",
"assetSet": "customers/{customer_id}/assetSets/-3"
}
}
},
{
"assetGroupOperation": {
"create": {
"resourceName": "customers/{customer_id}/assetGroups/-4",
"campaign": "customers/{customer_id}/campaigns/-2",
"name": "Local Services Plumbing Asset Group",
"status": "ENABLED",
"googleLocalServicesInfo": {
"categoryId": "xcat:service_area_business_plumber",
"callouts": [
{
"calloutId": "family_owned"
}
]
}
}
}
},
{
"assetGroupSignalOperation": {
"create": {
"assetGroup": "customers/{customer_id}/assetGroups/-4",
"localServicesId": {
"serviceId": "install_faucet"
}
}
}
}
]
}
Automated conversion goal provisioning
Conversion goals are automatically provisioned and managed by the backend based on account and partner eligibility; you do not need to pass conversion goal operations during initial atomic campaign creation.
Local Services campaigns are restricted strictly to supported Local Services
lead conversion categories. Attempting to configure other goals returns
CampaignConversionGoalError.GOAL_NOT_ALLOWED_FOR_LOCAL_SERVICES_CAMPAIGN.
Furthermore, Local Services campaigns require campaign-level override goals;
disabling override goals returns
ConversionGoalCampaignConfigError.CANNOT_DISABLE_CAMPAIGN_OVERRIDE_GOALS_FOR_LOCAL_SERVICES_CAMPAIGN.
- Non-coupon campaigns:
PHONE_CALL_LEAD (LOCAL_SERVICES_ADS): Automatically linked as the default active biddable goal (biddable = true) at campaign creation. This goal is required and cannot be set tobiddable = false(doing so returnsCampaignConversionGoalError.CANNOT_UNLINK_LOCAL_SERVICES_GOAL_FROM_LOCAL_SERVICES_CAMPAIGN).MESSAGE_LEAD (LOCAL_SERVICES_ADS): Automatically pre-created at the account level so the conversion action exists, but defaults tobiddable = falseat the campaign level (opted out by default). To opt in to message leads (at creation or later), update the campaign conversion goalcustomers/{customer_id}/campaignConversionGoals/{campaign_id}~MESSAGE_LEAD~LOCAL_SERVICES_ADStobiddable = trueusing aCampaignConversionGoalOperation.BOOK_APPOINTMENT (LOCAL_SERVICES_ADS): Provisioned and linked downstream (biddable = true) asynchronously once an approved Reserve with Google partner is detected on the linked location.
- POS coupon partner campaigns (Clover, Lightspeed, Express Oil):
CONVERTED_LEAD (LOCAL_SERVICES_ADS): Automatically linked (Offline Promotion Redemption) as the active biddable goal upon creation. Coupon partner campaigns exclusively optimize forCONVERTED_LEADand cannot use phone or message lead goals.
Enable the campaign and complete business verification
- Activate campaign: Update the campaign status from
PAUSEDtoENABLEDusingCampaignService.MutateCampaigns. - Complete Trust and Safety verification: Complete business registration, identity verification, licenses, and document submissions through the Google Ads UI (Admin > Policy). Ads will begin serving once verification has cleared.
Management and reporting of Performance Max campaigns with pay-per-lead goals
API feature availability overview
While the API gives partners access to manage campaigns at scale, it is used in complement with the Google Ads UI to fulfill end-to-end account and campaign management. Full API support is offered for select journeys, while UI management is required for others:
| Feature | Surface and availability | Details |
|---|---|---|
| Account and campaign creation | Full API support | Supported through GoogleAdsService.Mutate. |
| Campaign settings | Full API support | Supported through CampaignService.MutateCampaigns. |
| Asset management | Partial API support | Advertiser-uploaded images are a UI-only feature. |
| Asset policy reporting | Full API support | Query policy statuses through asset_group_asset. |
| Lead management and reporting | Full API support | Query leads through local_services_lead and conversations through local_services_lead_conversation. local_services_lead.campaign links lead records back to the Local Services Performance Max campaign. |
| Verifications | UI only | Completing verification tasks and viewing verification statuses are UI-only (Admin > Policy). |
| Budget and bidding | Full API support | Supports MAXIMIZE_CONVERSIONS with optional target_cpa_micros. |
| Location management | Full API support | Supported through STATIC_LOCATION_GROUP asset sets. |
| Billing and terms | UI only | Billing setup and Local Services Product Terms must be completed in the Google Ads UI (Account Settings). |
Data field details
The following table outlines the resources, fields, and capabilities available for Local Services Performance Max campaigns:
| Resource | Field or component | Mutable? | Availability and Local Services rules |
|---|---|---|---|
Campaign |
name |
Yes | Required name for the campaign. |
Campaign |
campaign_budget |
Yes | Resource name of the CampaignBudget associated with the campaign. |
Campaign |
advertising_channel_type |
CREATE ONLY | Must be set to PERFORMANCE_MAX. Cannot be modified after creation. |
Campaign |
pmax_campaign_settings.local_services_enabled |
CREATE ONLY | Immutable boolean. Must be set to true at creation to enable Local Services behavior and features. Existing standard Performance Max campaigns cannot be converted. |
Campaign |
pmax_campaign_settings.local_services_pmax_campaign_settings.country_code |
CREATE ONLY | Required two-letter ISO country code. Enforced strictly as 'US'. Out-of-country values are rejected. |
Campaign |
pmax_campaign_settings.local_services_pmax_campaign_settings.listing_id |
CREATE ONLY | Required numeric Google Business Profile listing ID representing the provider's physical location. Validated at campaign creation against linked location assets. |
Campaign |
pmax_campaign_settings.local_services_pmax_campaign_settings.phone_numbers |
Yes | Business or call-tracking phone numbers associated with the campaign using LocalServicesPhoneNumber. If omitted, the call number defaults to the phone number on the linked Google Business Profile listing, and is required if the Business Profile listing does not have a phone number. Supported GlsPhoneNumberType values are DESTINATION_PHONE_NUMBER_FOR_ADS (for call leads) and DESTINATION_PHONE_NUMBER_FOR_SMS_ONLY (optional, for message lead SMS notifications). |
Campaign |
pmax_campaign_settings.local_services_pmax_campaign_settings.founding_year |
Yes | Optional business establishment year (such as 1998). Displays the "In business since..." trust badge. |
Campaign |
pmax_campaign_settings.local_services_pmax_campaign_settings.navigational_query_leads_enabled |
Yes | Optional boolean indicating whether to receive leads from navigational queries searching specifically for your business brand name. |
Campaign |
brand_guidelines_enabled |
CREATE ONLY | Must be set to false. Unlike standard Performance Max campaigns, Local Services Performance Max campaigns do not use brand guidelines or campaign-level brand assets. |
Campaign |
maximize_conversions |
Yes | Required bidding strategy message. Configures MAXIMIZE_CONVERSIONS (with optional target_cpa_micros). Target ROAS and manual bidding are not supported. |
Campaign |
bidding_strategy_type |
READ ONLY | Output-only field on Campaign automatically populated as MAXIMIZE_CONVERSIONS. |
Campaign |
status |
Yes | Campaign status (PAUSED, ENABLED, REMOVED). Recommended to create as PAUSED until configuration is complete. |
CampaignBudget |
amount_micros |
Yes | Daily campaign budget defined on CampaignBudget. |
CampaignBudget |
delivery_method |
Yes | Must be set to STANDARD. |
CampaignBudget |
explicitly_shared |
CREATE ONLY | Must be set to false. Performance Max campaigns cannot use shared budgets. |
CampaignConversionGoal |
biddable |
Yes | Guardrailed strictly to Local Services lead conversion categories (PHONE_CALL_LEAD, MESSAGE_LEAD, BOOK_APPOINTMENT, and CONVERTED_LEAD for POS coupon partners; other goals return CampaignConversionGoalError.GOAL_NOT_ALLOWED_FOR_LOCAL_SERVICES_CAMPAIGN). For non-coupon campaigns, PHONE_CALL_LEAD is required and cannot be set to biddable = false (CampaignConversionGoalError.CANNOT_UNLINK_LOCAL_SERVICES_GOAL_FROM_LOCAL_SERVICES_CAMPAIGN). Disabling campaign override goals returns ConversionGoalCampaignConfigError.CANNOT_DISABLE_CAMPAIGN_OVERRIDE_GOALS_FOR_LOCAL_SERVICES_CAMPAIGN. |
CampaignCriterion |
Language targeting (language / LANGUAGE) |
Yes | Target language criterion. Enforced strictly as English (languageConstants/1000) for US campaigns. Other languages are rejected at mutate time. |
CampaignCriterion |
Location targeting (location / LOCATION) |
Yes | Sub-national geographic targeting (cities, counties, DMAs, postal codes). Criteria must be inside the campaign's home country (US). Country-level targeting (targeting entire US) is rejected (CampaignCriterionError.CANNOT_TARGET_COUNTRY_FOR_LOCAL_SERVICES_CAMPAIGN). Local Services Performance Max campaigns must retain at least one positive location criterion (CampaignCriterionError.CANNOT_REMOVE_ALL_LOCATIONS_FROM_LOCAL_SERVICES_PMAX_CAMPAIGN). |
CampaignCriterion |
Ad schedule (ad_schedule / AD_SCHEDULE) |
Yes | Personal custom ad delivery schedule (day_of_week, start/end time). Defaults to 24/7 delivery if omitted. |
AssetSet |
type = LOCATION_SYNC |
CREATE ONLY | Account-level asset set synchronizing Google Business Profile locations into Google Ads LOCATION assets. type is immutable after creation. |
AssetSet |
type = STATIC_LOCATION_GROUP |
CREATE ONLY | Asset set grouping the specific synced LOCATION asset to be targeted by the campaign. Requires location_group_parent_asset_set_id set to the LOCATION_SYNC asset set ID (type and location_group_parent_asset_set_id are immutable after creation; AssetSetAsset links are CREATE / REMOVE ONLY). |
CampaignAssetSet |
Location asset set link | CREATE ONLY | Links the STATIC_LOCATION_GROUP to the campaign. Enforces transactional rollback: at most one location group link (AssetSetLinkError.DUPLICATE_ASSET_SET_LINK), at most one active location asset, and linked location asset listing ID must match the campaign's listing_id (AssetSetLinkError.LOCATION_ASSET_DOES_NOT_MATCH_CAMPAIGN_LISTING_ID). Once created, this link cannot be removed (AssetSetLinkError.ASSET_SET_LINK_CANNOT_BE_REMOVED). |
AssetGroup |
name |
Yes | Required name for the asset group. |
AssetGroup |
campaign |
CREATE ONLY | Resource name of the Campaign associated with the asset group. |
AssetGroup |
status |
Yes | Asset group status. Must be set to ENABLED on creation. |
AssetGroup |
google_local_services_info.category_id |
CREATE ONLY | Standardized category identifier (for example, xcat:service_area_business_plumber). Immutable after creation. Validated against the supported vertical allowlist (AssetGroupError.UNSUPPORTED_LOCAL_SERVICES_CATEGORY). |
AssetGroup |
google_local_services_info.callouts |
Yes | Standardized business callout tags using repeated LocalServicesCallout with callout_id. Maximum of 6 callouts allowed per asset group. Must match allowed vertical callouts. |
AssetGroupSignal |
local_services_id.service_id |
CREATE / REMOVE ONLY | Search theme signals representing granular service offerings under the category using LocalServiceIdInfo. At least one signal is required per asset group (AssetGroupSignalError.CANNOT_REMOVE_ALL_SIGNALS). |
LocalServicesLead |
Lead records and metadata | READ ONLY | Queryable lead data received by the provider, including lead type, charge status, credit state, creation timestamp, and local_services_lead.campaign linking leads back to the campaign. |
LocalServicesLeadConversation |
Conversation details and recordings | READ ONLY | Queryable communication records associated with leads (call durations, recording URLs, message text). |
Frequently asked questions
What countries are Performance Max for pay-per-lead campaigns available in?
Only the United States (US) is supported.
How do I find the Google Business Profile (GBP) listing ID?
You can find your listing ID in the Google Business Profile interface or
programmatically by querying LOCATION assets using Google Ads Query Language. For detailed
instructions and query examples, see
Retrieve the Google Business Profile listing and location asset.
How do I activate coupon leads?
Coupon leads are available only for select pilot POS partners (Clover, Lightspeed, Express Oil). Contact your Google representative if you are interested in learning more.
Are message leads enabled or disabled by default?
PHONE_CALL_LEAD (LOCAL_SERVICES_ADS) is enabled by default. MESSAGE_LEAD
(LOCAL_SERVICES_ADS) is created with biddable = false (opted out by default).
To opt in to message leads, update the campaign conversion goal to biddable =
true. For more details, see
Automated conversion goal provisioning.