> [!NOTE]
> **Note:** This guide assumes that you are familiar with the Google Ads access model. If you aren't, we recommend reading the [Google Ads access
> model](https://developers.google.com/google-ads/api/docs/oauth/access-model) guide to familiarize yourself with the concepts. You should also configure your OAuth credentials using the same Google Cloud project where you have [enabled the
> Google Ads API](https://developers.google.com/google-ads/api/docs/oauth/cloud-project#enable-api) and requested an appropriate [API access level](https://developers.google.com/google-ads/api/docs/api-policy/access-levels) for the Google Ads API to work correctly.

In the multi-user authentication workflow, you build your own OAuth flow to
authenticate your users. There are multiple app types discussed as part of the
[Google Identity documentation](https://developers.google.com/identity/protocols/oauth2), along with the
Google API Console project configuration you need to support each app type. All
these app types are supported by Google Ads API. The additional technical details to
keep in mind are:

- Configure your application to request the following OAuth 2.0 scope:

      https://www.googleapis.com/auth/adwords

- Your app may have to make API calls on behalf of the user while they are
  offline. A common scenario is to download account metrics offline to
  generate reports and perform account analytics. For this reason, we
  recommend requesting [OAuth offline access](https://developers.google.com/identity/protocols/oauth2/web-server#offline).

- Complete the [OAuth App verification process](https://support.google.com/cloud/answer/13461325) to get your
  app verified.

## Workflow overview

Implementing a multi-user authentication workflow involves three main steps:

1. **Direct users to the OAuth consent screen:** Redirect each user to Google's OAuth 2.0 authorization endpoint requesting the `https://www.googleapis.com/auth/adwords` scope and offline access. Users must authenticate with a [passkey](https://developers.google.com/google-ads/api/docs/oauth/security-requirements#passkey-requirements) to complete the authorization flow and generate a refresh token.
2. **Exchange the authorization code for tokens:** After the user grants permission, capture the returned authorization code and exchange it for an access token and a refresh token.
3. **Store tokens and initialize the client at runtime:** Securely store each user's refresh token in your datastore and pass the user's credentials when initializing your `GoogleAdsClient` instance at runtime.

## Client library configuration

After you authorize the user and obtain OAuth 2.0 credentials, you can configure
the client library by following the instructions on the tab corresponding to
your programming language.

### Java

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    UserCredentials credentials =
        UserCredentials.newBuilder()
            .setClientId("INSERT_OAUTH2_CLIENT_ID_HERE")
            .setClientSecret("INSERT_OAUTH2_CLIENT_SECRET_HERE")
            .setRefreshToken("INSERT_OAUTH2_REFRESH_TOKEN_HERE")
            .build();

    // Creates a GoogleAdsClient with the provided credentials.
    GoogleAdsClient client =
        GoogleAdsClient.newBuilder()
            // Sets the OAuth credentials which provide Google Ads account
            // access.
            .setCredentials(credentials)
            // Optional: sets the login customer ID.
            .setLoginCustomerId(Long.valueOf("INSERT_LOGIN_CUSTOMER_ID_HERE"))
            .build();

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/java/config-file) for additional options.

### .NET

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    GoogleAdsConfig config = new GoogleAdsConfig()
    {
        OAuth2Mode = OAuth2Flow.APPLICATION,
        OAuth2ClientId = "INSERT_OAUTH2_CLIENT_ID_HERE",
        OAuth2ClientSecret = "INSERT_OAUTH2_CLIENT_SECRET_HERE",
        OAuth2RefreshToken = "INSERT_OAUTH2_REFRESH_TOKEN_HERE",
        LoginCustomerId = "INSERT_LOGIN_CUSTOMER_ID_HERE",
    };

    GoogleAdsClient client = new GoogleAdsClient(config);

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/dotnet/configuration) for additional options.

### Python

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    from google.ads.googleads.client import GoogleAdsClient

    credentials = {
        "login_customer_id": "INSERT_LOGIN_CUSTOMER_ID_HERE",
        "refresh_token": "INSERT_OAUTH2_REFRESH_TOKEN_HERE",
        "client_id": "INSERT_OAUTH2_CLIENT_ID_HERE",
        "client_secret": "INSERT_OAUTH2_CLIENT_SECRET_HERE",
        "use_proto_plus": True,
    }

    client = GoogleAdsClient.load_from_dict(credentials)

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/python/configuration) for additional options.

### PHP

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    $oAuth2Credential = (new OAuth2TokenBuilder())
        ->withClientId('INSERT_OAUTH2_CLIENT_ID_HERE')
        ->withClientSecret('INSERT_OAUTH2_CLIENT_SECRET_HERE')
        ->withRefreshToken('INSERT_OAUTH2_REFRESH_TOKEN_HERE')
        ->build();

    $googleAdsClient = (new GoogleAdsClientBuilder())
        ->withOAuth2Credential($oAuth2Credential)
        ->withLoginCustomerId('INSERT_LOGIN_CUSTOMER_ID_HERE')
        ->build();

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/php/configuration) for additional options.

### Ruby

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    client = Google::Ads::GoogleAds::GoogleAdsClient.new do |config|
      config.client_id = 'INSERT_OAUTH2_CLIENT_ID_HERE'
      config.client_secret = 'INSERT_OAUTH2_CLIENT_SECRET_HERE'
      config.refresh_token = 'INSERT_OAUTH2_REFRESH_TOKEN_HERE'
      config.login_customer_id = 'INSERT_LOGIN_CUSTOMER_ID_HERE'
    end

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/ruby/configuration) for additional options.

### Perl

You can initialize your `GoogleAdsClient` instance at runtime, using the
credentials you have obtained from the user whose accounts you are making
API calls to.

    my $api_client = Google::Ads::GoogleAds::Client->new({
      login_customer_id => "INSERT_LOGIN_CUSTOMER_ID_HERE"
    });

    my $oauth2_handler = $api_client->get_oauth2_applications_handler();
    $oauth2_handler->set_client_id("INSERT_OAUTH2_CLIENT_ID_HERE");
    $oauth2_handler->set_client_secret("INSERT_OAUTH2_CLIENT_SECRET_HERE");
    $oauth2_handler->set_refresh_token("INSERT_OAUTH2_REFRESH_TOKEN_HERE");

See the [configuration guide](https://developers.google.com/google-ads/api/docs/client-libs/perl/configuration) for additional options.

### curl

Start by using an HTTP client to fetch an OAuth 2.0 access token. This guide
uses the `curl` command.

    curl \
      --data "grant_type=refresh_token" \
      --data "client_id=CLIENT_ID" \
      --data "client_secret=CLIENT_SECRET" \
      --data "refresh_token=REFRESH_TOKEN" \
      https://oauth2.googleapis.com/token

You can use the access token in your API calls. The following example
shows how to run a campaign report using the
[`GoogleAdsService.SearchStream`](https://developers.google.com/google-ads/api/reference/rpc/v26/GoogleAdsService/SearchStream) method to retrieve
the campaigns in your account. This guide doesn't cover the details of
[reporting](https://developers.google.com/google-ads/api/docs/reporting/overview).

    curl -i -X POST \
      https://googleads.googleapis.com/v26/customers/CUSTOMER_ID/googleAds:searchStream \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer ACCESS_TOKEN" \
      -H "login-customer-id: LOGIN_CUSTOMER_ID" \
      --data-binary "@query.json"

The contents of `query.json` are as follows:

    {
      "query": "SELECT campaign.id, campaign.name, campaign.network_settings.target_content_network FROM campaign ORDER BY campaign.id"
    }