> ## Documentation Index
> Fetch the complete documentation index at: https://docs.markifact.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Google Cloud App

> Create your own Google Cloud OAuth client and mint a refresh token so any Google connection in Markifact runs under your app (white-label).

Every Google connection in Markifact (Google Ads, Google Analytics 4, Search Console, Merchant Center, Business Profile, Tag Manager, Display & Video 360, BigQuery, YouTube and Data Manager) can run under **your own Google Cloud app** instead of Markifact's. You create the app once, mint a refresh token for each channel (or one token that covers several), and paste three values into Markifact.

<Note>
  Custom app connections are available on the **Team** plan. See [White-label Connections](/core-concepts/white-label-connections) for the overview.
</Note>

***

## What Every Google Channel Needs

Three values from your own Google Cloud project:

| Value             | Where it comes from                                                                                                       |
| :---------------- | :------------------------------------------------------------------------------------------------------------------------ |
| **Client ID**     | An OAuth 2.0 client in your Cloud project                                                                                 |
| **Client Secret** | The same OAuth client                                                                                                     |
| **Refresh Token** | Minted against that client with the channel's scope, by a Google account that has access to the assets you want to manage |

Google no longer requires a developer token for Google Ads, so these three values are everything any Google connection needs.

<Note>
  **Already have your own OAuth flow?** If your systems already authorize users against your Google Cloud app, skip to the channel page and paste the refresh token you already hold. Make sure it was minted with `access_type=offline`, `prompt=consent`, and the scope for that channel.
</Note>

***

## Scopes and APIs per Channel

Enable the APIs for every channel you plan to connect, and request the matching scope when you mint the token. You can request several scopes in one go and reuse that single refresh token across channels.

| Channel             | Scope to request                                                                                                                                                                                                                                   | APIs to enable in your project                                                                                                                                                         | Setup page                                                                         |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |
| Google Ads          | `https://www.googleapis.com/auth/adwords`                                                                                                                                                                                                          | Google Ads API                                                                                                                                                                         | [Custom Google Ads App](/nodes/gads/gads_custom_app)                               |
| Google Analytics 4  | `https://www.googleapis.com/auth/analytics.readonly`                                                                                                                                                                                               | Google Analytics Admin API, Google Analytics Data API                                                                                                                                  | [Custom GA4 App](/nodes/ga4/ga4_custom_app)                                        |
| Search Console      | `https://www.googleapis.com/auth/webmasters`                                                                                                                                                                                                       | Google Search Console API                                                                                                                                                              | [Custom Search Console App](/nodes/gsc/gsc_custom_app)                             |
| Merchant Center     | `https://www.googleapis.com/auth/content`                                                                                                                                                                                                          | Merchant API                                                                                                                                                                           | [Custom Merchant Center App](/nodes/gmc/gmc_custom_app)                            |
| Business Profile    | `https://www.googleapis.com/auth/business.manage`                                                                                                                                                                                                  | My Business Account Management API, My Business Business Information API, Business Profile Performance API, Google My Business API. **Requires Google approval**, see the channel page | [Custom Business Profile App](/nodes/business_profile/business_profile_custom_app) |
| Tag Manager         | `https://www.googleapis.com/auth/tagmanager.edit.containers` `https://www.googleapis.com/auth/tagmanager.manage.accounts` `https://www.googleapis.com/auth/tagmanager.edit.containerversions` `https://www.googleapis.com/auth/tagmanager.publish` | Tag Manager API                                                                                                                                                                        | [Custom Tag Manager App](/nodes/gtm/gtm_custom_app)                                |
| Display & Video 360 | `https://www.googleapis.com/auth/display-video` `https://www.googleapis.com/auth/doubleclickbidmanager`                                                                                                                                            | Display & Video 360 API, DoubleClick Bid Manager API                                                                                                                                   | [Custom DV360 App](/nodes/dv360/dv360_custom_app)                                  |
| BigQuery            | `https://www.googleapis.com/auth/bigquery`                                                                                                                                                                                                         | BigQuery API                                                                                                                                                                           | [Custom BigQuery App](/nodes/bigquery/bigquery_custom_app)                         |
| YouTube             | `https://www.googleapis.com/auth/yt-analytics.readonly`                                                                                                                                                                                            | YouTube Analytics API                                                                                                                                                                  | [Custom YouTube App](/nodes/youtube/youtube_custom_app)                            |
| Data Manager        | `https://www.googleapis.com/auth/datamanager`                                                                                                                                                                                                      | Data Manager API                                                                                                                                                                       | [Custom Data Manager App](/nodes/data_manager/data_manager_custom_app)             |

***

## Setting Up Your Google Cloud App

<Steps>
  <Step title="Enable the APIs">
    1. Open [Google Cloud Console](https://console.cloud.google.com/) and select (or create) the project you want to use
    2. Go to **APIs & Services** > **Library**
    3. Search for each API from the table above and click **Enable**
  </Step>

  <Step title="Configure the OAuth Consent Screen">
    1. Go to **APIs & Services** > **OAuth consent screen**
    2. Choose **External** (or **Internal** if everyone who will authorize is in your Google Workspace organization)
    3. Enter your app name, support email, and logo. This is the branding your users see when they authorize
    4. Under **Scopes**, add the scopes for the channels you plan to connect
    5. **Publish the app** (Publishing status: **In production**)

    <Warning>
      Do not leave the app in **Testing** status. Google issues refresh tokens that expire after 7 days to apps in Testing, so your Markifact connections would stop working after a week. Publishing with sensitive scopes may show an "unverified app" screen to users who authorize; that is fine when only your own team authorizes.
    </Warning>
  </Step>

  <Step title="Create an OAuth Client">
    1. Go to **APIs & Services** > **Credentials**
    2. Click **Create credentials** > **OAuth client ID**
    3. Application type: **Web application**
    4. Under **Authorized redirect URIs**, add:

    ```bash theme={"dark"}
    https://developers.google.com/oauthplayground
    ```

    5. Click **Create** and copy the **Client ID** and **Client secret**
  </Step>

  <Step title="Mint a Refresh Token">
    1. Open the [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/)
    2. Click the gear icon (top right), tick **Use your own OAuth credentials**, and paste your Client ID and Client secret
    3. In **Step 1**, enter the scope(s) for your channel in the input box (separate several scopes with a space) and click **Authorize APIs**
    4. Sign in with the Google account that has access to the assets you want to manage
    5. In **Step 2**, click **Exchange authorization code for tokens**
    6. Copy the **Refresh token**

    > **Important:** Keep this token secure. Anyone holding it, together with your client ID and secret, can act on everything the Google account can access within the granted scopes.
  </Step>

  <Step title="Connect in Markifact">
    Open the channel's setup page from the table above, or go straight to [Connections](https://app.markifact.com/connections), click **Connect** on the channel, select the **Custom App (White-label)** tab, name the connection and paste the three values. Markifact verifies them with one API call before saving anything.
  </Step>
</Steps>

***

## Rotating or Replacing a Token

Add the connection again with the **same connection name** and the new refresh token. Markifact replaces the stored credentials in place, so workflows and agents bound to the connection keep working.

***

## Troubleshooting

<Accordion title="Google rejected the client ID or client secret (invalid_client)">
  Check both values under **APIs & Services** > **Credentials**. A client secret that was reset in Google Cloud invalidates the old one.
</Accordion>

<Accordion title="Google rejected the refresh token (invalid_grant)">
  The most common causes:

  * The token was minted with a different client ID than the one you pasted
  * The OAuth consent screen is still in **Testing** status, so the token expired after 7 days
  * The user revoked access under [Google account permissions](https://myaccount.google.com/connections)
  * The token was minted without `prompt=consent`, so Google returned no refresh token at all

  Mint a new refresh token and add the connection again with the same name.
</Accordion>

<Accordion title="The refresh token does not include the scope">
  Repeat the Playground step with the channel's scope entered in Step 1 before clicking **Authorize APIs**. Several scopes can be entered at once, separated by a space.
</Accordion>

<Accordion title="The API is not enabled on the Cloud project">
  Enable the APIs listed for the channel under **APIs & Services** > **Library** in the project that owns your client ID, then try again. It can take a minute to propagate.
</Accordion>

***

## Related

<CardGroup cols={2}>
  <Card title="White-label Connections" icon="tag" href="/core-concepts/white-label-connections">
    Overview of custom app connections across channels
  </Card>

  <Card title="Connections" icon="plug" href="/core-concepts/connections">
    How connections, sharing, and privacy work
  </Card>
</CardGroup>
