Performance Max for pay-per-lead goals

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:

  1. Complete account-level prerequisites
  2. Retrieve the Google Business Profile listing and location asset
  3. Create campaign resources atomically (GoogleAdsService.Mutate)
  4. 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:

  1. 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.
  2. 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_SYNC typed AssetSet). Note that creating a LOCATION_SYNC AssetSet alone does not activate location syncing for the account; you must also attach it to the customer using CustomerAssetSet (CustomerAssetSetService.MutateCustomerAssetSets) and supply an OAuth 2.0 http_authorization_token with the https://www.googleapis.com/auth/business.manage scope. For more information, see Create a location sync asset set and attach it to the customer. This synchronizes business locations as account LOCATION assets 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:

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 to false. 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 the CampaignBudget created in the same request.
  • advertising_channel_type: Must be set to PERFORMANCE_MAX.
  • brand_guidelines_enabled: Must be set to false. Unlike standard Performance Max campaigns (which default to brand_guidelines_enabled = true and require linking BUSINESS_NAME and LOGO CampaignAsset resources), Local Services Performance Max campaigns set brand_guidelines_enabled = false.
  • pmax_campaign_settings.local_services_enabled: Must be set to true (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 returns CampaignError.INVALID_LOCAL_SERVICES_PERFORMANCE_MAX_LISTING_ID.
    • Optional: phone_numbers: Repeated LocalServicesPhoneNumber message specifying dedicated tracking or business phone numbers (phone_number, country_code, and GlsPhoneNumberType phone_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. Supported phone_number_type values are DESTINATION_PHONE_NUMBER_FOR_ADS (for call leads) and DESTINATION_PHONE_NUMBER_FOR_SMS_ONLY (optional, for message lead SMS notifications).
    • Optional: founding_year: Business establishment year (such as 1998).
    • Optional: navigational_query_leads_enabled: Boolean indicating whether to receive leads from navigational brand queries.
  • maximize_conversions: Required bidding strategy message configuring MAXIMIZE_CONVERSIONS bidding (with an optional target_cpa_micros). Target ROAS and manual bidding are not supported.
  • status: Set to PAUSED on 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:

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:

  1. Only one STATIC_LOCATION_GROUP AssetSet can be linked to the campaign (AssetSetLinkError.DUPLICATE_ASSET_SET_LINK).
  2. The STATIC_LOCATION_GROUP can contain at most one active LOCATION asset.
  3. The linked LOCATION asset's listing ID must match campaign.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 the Campaign created in the same request.
  • status: Must be set to ENABLED on creation.
  • google_local_services_info.category_id: Standardized category ID (such as xcat:service_area_business_plumber). Specifying an unsupported category returns AssetGroupError.UNSUPPORTED_LOCAL_SERVICES_CATEGORY.
  • Optional: google_local_services_info.callouts: Repeated LocalServicesCallout message (maximum of 6 callouts allowed per asset group) with callout_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 to biddable = false (doing so returns CampaignConversionGoalError.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 to biddable = false at the campaign level (opted out by default). To opt in to message leads (at creation or later), update the campaign conversion goal customers/{customer_id}/campaignConversionGoals/{campaign_id}~MESSAGE_LEAD~LOCAL_SERVICES_ADS to biddable = true using a CampaignConversionGoalOperation.
    • 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 for CONVERTED_LEAD and cannot use phone or message lead goals.

Enable the campaign and complete business verification

  1. Activate campaign: Update the campaign status from PAUSED to ENABLED using CampaignService.MutateCampaigns.
  2. 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.