Resolving USER_PERMISSION_DENIED Errors in Google Ads API Using login_customer_id

When authenticating through a Manager Account (MCC), you must provide the 10-digit manager ID via the login_customer_id parameter to resolve USER_PERMISSION_DENIED errors when accessing child accounts.

The USER_PERMISSION_DENIED error in the Google Ads API typically occurs when OAuth credentials belong to a Manager Account but the request targets a client account without proper hierarchy routing. According to the google/skills repository's Google Ads API quickstart guide, adding the login_customer_id configuration establishes the proper authorization chain through the manager hierarchy.

Understanding the USER_PERMISSION_DENIED Error

The Google Ads API returns USER_PERMISSION_DENIED when the authentication flow cannot verify that the authenticated user has permission to act on the target account. As documented in skills/ads/google-ads-api-quickstart/SKILL.md (section 5), this happens because the OAuth token identifies a Google user and the developer token identifies the application, but without the login_customer_id, the API cannot resolve which manager account should vouch for the client account access.

When you omit the manager ID, the API attempts to authenticate directly against the client account. This fails because the OAuth credentials belong to the manager, not the client, triggering a hierarchy mismatch that returns the permission denied response (section 6.1).

How login_customer_id Resolves Permission Denied Errors

The login_customer_id parameter tells the Google Ads API which manager account to use as the authorization proxy. When provided, the API routes the request through the manager hierarchy, verifying that the manager account has access to the target client account before executing the operation.

This three-component authentication model requires:

  • OAuth token to identify the Google user
  • Developer token to identify the application's access level
  • login_customer_id to specify the manager account resolving permissions

Step-by-Step Implementation

Identifying Your Manager Account ID

Locate the 10-digit Manager Account ID (MCC) that owns the client account you are targeting. This ID appears in the Google Ads UI when logged into the manager account, typically in the format XXX-XXX-XXXX (remove dashes for the API).

Configuring login_customer_id in Python

Update your google-ads.yaml configuration file as shown in the skills/ads/google-ads-api-quickstart/references/python.md documentation:


# google-ads.yaml

developer_token: INSERT_DEVELOPER_TOKEN_HERE
client_id: INSERT_OAUTH2_CLIENT_ID_HERE
client_secret: INSERT_OAUTH2_CLIENT_SECRET_HERE
refresh_token: INSERT_OAUTH2_REFRESH_TOKEN_HERE

# Add your 10-digit Manager Account ID here to resolve USER_PERMISSION_DENIED:

login_customer_id: INSERT_LOGIN_CUSTOMER_ID_HERE   # ← manager MCC ID

Then load the configuration in your Python script:


# get_campaigns.py (relevant fragment)

import argparse, os, sys
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException

def main(client, customer_id):
    service = client.get_service("GoogleAdsService")
    query = "SELECT campaign.id, campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
    for response in service.search_stream(customer_id=customer_id, query=query):
        for row in response.results:
            print(f"Campaign ID={row.campaign.id}, Name='{row.campaign.name}', Status={row.campaign.status.name}")

if __name__ == "__main__":
    # Load configuration (prefers local yaml)

    cfg_path = os.path.join(os.getcwd(), "google-ads.yaml")
    client = GoogleAdsClient.load_from_storage(cfg_path) if os.path.exists(cfg_path) else GoogleAdsClient.load_from_env()

    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--customer_id", required=True, help="10-digit client account ID")
    args = parser.parse_args()
    normalized_id = args.customer_id.replace("-", "")
    main(client, normalized_id)

Configuring login_customer_id in Java

For Java applications, set the manager ID in the GoogleAdsClient builder as referenced in skills/ads/google-ads-api-quickstart/references/java.md:

GoogleAdsClient client = GoogleAdsClient.newBuilder()
    .fromPropertiesFile("google-ads.properties")
    .withLoginCustomerId(Long.parseLong("INSERT_LOGIN_CUSTOMER_ID_HERE")) // manager MCC ID
    .build();

Configuring login_customer_id for REST API Calls

When using the REST API directly, append the loginCustomerId as a query parameter to your request URL, as documented in skills/ads/google-ads-api-quickstart/references/rest.md:

GET https://googleads.googleapis.com/v24/customers/1234567890/googleAds:searchStream?loginCustomerId=9876543210

Summary

  • The USER_PERMISSION_DENIED error occurs when authenticating via a Manager Account without specifying the hierarchy path.
  • Adding login_customer_id to your configuration routes the request through the manager account, establishing proper authorization.
  • This parameter is required in google-ads.yaml for Python, GoogleAdsClient.newBuilder() for Java, or as a query parameter for REST calls.
  • The value must be the 10-digit Manager Account ID (MCC) that owns the target client account.

Frequently Asked Questions

What is the difference between login_customer_id and client_customer_id?

The login_customer_id specifies the Manager Account (MCC) used for authentication and authorization routing, while client_customer_id (or the customer_id parameter in API calls) identifies the specific client account where you want to read or write data. You need both when accessing a child account through a manager.

Can I use login_customer_id with individual (non-MCC) accounts?

No. The login_customer_id is specifically designed for Manager Account hierarchies. If you are accessing an individual account directly using credentials from that same account, omit the login_customer_id parameter entirely.

Where does the Google Ads API validate the login_customer_id?

The API validates the login_customer_id against the OAuth credentials during the initial request processing in the Google Ads API servers. As detailed in skills/ads/google-ads-api-quickstart/SKILL.md (section 6.1), the service checks that the authenticated user has access to the specified manager account before attempting to access the client account.

How do I find my Manager Account ID?

Log into the Google Ads UI using your manager account credentials. The 10-digit account ID appears in the top-right corner or account selector, usually formatted as XXX-XXX-XXXX. Remove the dashes when entering the value in login_customer_id configuration fields.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →