Like other Google APIs, the Google Ads API uses the OAuth 2.0 protocol for
authentication and authorization. OAuth 2.0 enables your Google Ads API client
application to access a user's Google Ads account without having to handle or
store the user's login info.

## Understand the Google Ads access model

To work effectively with the Google Ads API, understand how the Google Ads access model
works. Refer to the [Google Ads access model guide](https://developers.google.com/google-ads/api/docs/oauth/access-model.md.txt).

## OAuth workflows

There are three common workflows used when working with the Google Ads API.

### Service account flow

This is the recommended workflow if your workflow doesn't require any human
interaction. This workflow requires a configuration step, where the user adds a
[service account](https://developers.google.com/identity/protocols/OAuth2#serviceaccount) to their Google Ads
account. The app can then use the service account's credentials to manage the
user's Google Ads account. The Python library is configured as follows:

- If using a `google-ads.yaml` file or YAML string, add the following to your
  configuration to set the path to the private key JSON file in your local
  environment (along with optional `impersonated_email` if using domain-wide
  delegation):

  ```yaml
  json_key_file_path: JSON_KEY_FILE_PATH
  # Optional: only set if using Google Workspace domain-wide delegation:
  # impersonated_email: IMPERSONATED_EMAIL
  ```

  Then call the `load_from_storage` or `load_from_string` methods:

  ```python
  from google.ads.googleads.client import GoogleAdsClient

  client = GoogleAdsClient.load_from_storage()
  ```
- If you're using a `dict` to configure the library, include the following
  key-value pair and call the `load_from_dict` method, passing in the
  configuration `dict`:

  ```python
  from google.ads.googleads.client import GoogleAdsClient

  configuration = {
      # ...
      "json_key_file_path": JSON_KEY_FILE_PATH,
      # ...
  }

  client = GoogleAdsClient.load_from_dict(configuration)
  ```
- If you're using environment variables, add the following to your `bash`
  configuration or environment:

  ```bash
  export GOOGLE_ADS_JSON_KEY_FILE_PATH=JSON_KEY_FILE_PATH
  ```

  Then call the `load_from_env` method:

  ```python
  from google.ads.googleads.client import GoogleAdsClient

  client = GoogleAdsClient.load_from_env()
  ```

If the `json_key_file_path` configuration option is present in any of these
configuration methods, the `use_application_default_credentials` option is
`False` or unset, and the OAuth user credential keys (`client_id`,
`client_secret`, and `refresh_token`) are unset or commented out, the library
automatically authorizes using the service account flow.

Refer to the [service account workflow guide](https://developers.google.com/google-ads/api/docs/oauth/service-accounts.md.txt) to
learn more.

### Single-user authentication flow

This workflow may be used if you cannot use service accounts. This workflow
requires two configuration steps:

1. Give a single user access to all the accounts to be managed using the
   Google Ads API. A common approach is to give the user access to a Google Ads API manager
   account, and link all the Google Ads accounts under that manager account.

2. The user runs a tool such as the
   [gcloud CLI](https://cloud.google.com/sdk/gcloud) or the
   [`generate_user_credentials` code example](https://github.com/googleads/google-ads-python/blob/HEAD/examples/authentication/generate_user_credentials.py) to
   authorize your app to manage all their Google Ads accounts on their behalf.

The library can be initialized using the user's OAuth 2.0 credentials as
follows:

#### If using the gcloud CLI tool (recommended)

> [!NOTE]
> **Note:** Authenticating with `use_application_default_credentials` requires `google-ads` **`v28.3.0` or later**.

1. Follow the [Generate credentials](https://developers.google.com/google-ads/api/docs/oauth/single-user-authentication.md.txt#generate_credentials) documentation to set
   up application default credentials (ADC) in your local environment.

2. Add the following configuration to your `google-ads.yaml` or YAML string:

   ```yaml
   use_application_default_credentials: true
   ```

   Then call either the `load_from_storage` or `load_from_string` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   client = GoogleAdsClient.load_from_storage()
   ```

   If you use a `dict` to configure the library, include the following
   key-value pair and call the `load_from_dict` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   configuration = {
       # ...
       "use_application_default_credentials": True,
       # ...
   }

   client = GoogleAdsClient.load_from_dict(configuration)
   ```

   If you're using environment variables, add the following to your `bash`
   configuration or environment:

   ```bash
   export GOOGLE_ADS_USE_APPLICATION_DEFAULT_CREDENTIALS=true
   ```

   Then call the `load_from_env` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   client = GoogleAdsClient.load_from_env()
   ```

#### If handling OAuth tokens directly

1. Follow the steps to [set up a console project](https://developers.google.com/google-ads/api/docs/oauth/cloud-project.md.txt?authpath=user_authentication) and
   download the JSON file that includes your project's client ID and client
   secret.

2. Clone the Python client library to your machine and change into its
   directory:

   ```bash
   git clone https://github.com/googleads/google-ads-python.git
   cd google-ads-python
   ```
3. Execute the example, providing an absolute path to the JSON file downloaded
   in step 1:

   ```bash
   python examples/authentication/generate_user_credentials.py \
       -c PATH_TO_CREDENTIALS_JSON
   ```

   Once complete, a refresh token prints to your console. Copy it and save it
   for the next step.
4. Configure the library by adding the following settings to your configuration
   of choice:

   Add the following configuration to your `google-ads.yaml` or YAML string:

   ```yaml
   client_id: INSERT_OAUTH2_CLIENT_ID_HERE
   client_secret: INSERT_OAUTH2_CLIENT_SECRET_HERE
   refresh_token: INSERT_REFRESH_TOKEN_HERE
   ```

   Then call either the `load_from_storage` or `load_from_string` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   client = GoogleAdsClient.load_from_storage()
   ```

   If you're using a `dict` to configure the library, include the following
   key-value pairs and call the `load_from_dict` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   configuration = {
       # ...
       "client_id": INSERT_OAUTH2_CLIENT_ID_HERE,
       "client_secret": (
           INSERT_OAUTH2_CLIENT_SECRET_HERE
       ),
       "refresh_token": INSERT_REFRESH_TOKEN_HERE,
       # ...
   }

   client = GoogleAdsClient.load_from_dict(configuration)
   ```

   If you're using environment variables, add the following to your `bash`
   configuration or environment:

   ```bash
   export GOOGLE_ADS_CLIENT_ID=\
   INSERT_OAUTH2_CLIENT_ID_HERE
   export GOOGLE_ADS_CLIENT_SECRET=\
   INSERT_OAUTH2_CLIENT_SECRET_HERE
   export GOOGLE_ADS_REFRESH_TOKEN=\
   INSERT_REFRESH_TOKEN_HERE
   ```

   Then call the `load_from_env` method:

   ```python
   from google.ads.googleads.client import GoogleAdsClient

   client = GoogleAdsClient.load_from_env()
   ```

Refer to the [single-user authentication workflow guide](https://developers.google.com/google-ads/api/docs/oauth/single-user-authentication.md.txt) to
learn more.

### Multi-user authentication flow

This is the recommended workflow if your app allows users to sign in and
authorize your app to manage their Google Ads accounts on their behalf. Your app
builds and manages the OAuth 2.0 user credentials. The library can be
initialized using the user's credentials as follows, which assumes that your
application obtains credentials at runtime, either by executing an authorization
flow or by loading them from a datastore:

A `dict` is the simplest configuration mechanism to use when obtaining
credentials at runtime:

```python
from google.ads.googleads.client import GoogleAdsClient

configuration = {
    # ...
    "client_id": client_id,
    "client_secret": client_secret,
    "refresh_token": refresh_token,
    # ...
}

client = GoogleAdsClient.load_from_dict(configuration)
```

Refer to the [multi-user authentication workflow guide](https://developers.google.com/google-ads/api/docs/oauth/multi-user-authentication.md.txt) to
learn more.

### Manual authentication

You can generate auth credentials with any approach and provide them to the
`GoogleAdsClient` manually by instantiating the client class directly. Assuming
the credentials object you create is an instance of
`google.auth.credentials.Credentials`, you can pass it in as follows:

```python
from google.ads.googleads.client import GoogleAdsClient
from google.auth import default

# This line retrieves ADCs from the environment. You can use any authentication
# approach as long as the `credentials` variable is an instance of
# `google.auth.credentials.Credentials`.
credentials, _ = default(scopes=["https://www.googleapis.com/auth/adwords"])

client = GoogleAdsClient(
    credentials=credentials,
    use_proto_plus=True,
)
```

## Manage multiple accounts

It is common for a user to manage more than one Google Ads account, either through
direct access to accounts, or through a Google Ads manager account. The Python
client library provides the following code examples that illustrate how to
handle such cases:

1. The [`get_account_hierarchy`](https://github.com/googleads/google-ads-python/blob/HEAD/examples/account_management/get_account_hierarchy.py) code example shows how to retrieve the list of all accounts under a Google Ads manager account.
2. The [`list_accessible_customers`](https://github.com/googleads/google-ads-python/blob/HEAD/examples/account_management/list_accessible_customers.py) code example shows how to retrieve the list of all accounts that a user has direct access to. These accounts can then be used as valid values for the `login_customer_id` setting.