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

# Google Ad Manager

> Integrate with Google Ad Manager for targeting and campaign optimization

export const NoBadge = () => {
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.5rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: '#F7D0E2',
    color: '#1A1A1A',
    fontWeight: '500'
  }}>
      No
    </span>;
};

export const YesBadge = () => {
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.5rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: '#C7E8F9',
    color: '#1A1A1A',
    fontWeight: '500'
  }}>
      Yes
    </span>;
};

export const BadgeRowCenter = ({label, children}) => {
  return <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '0.5rem'
  }}>
      <span style={{
    fontSize: '0.625rem',
    color: '#6b7280',
    textTransform: 'uppercase',
    fontWeight: '500',
    letterSpacing: '0.05em'
  }}>
        {label}
      </span>
      {children}
    </div>;
};

export const BadgeRow = ({label, children}) => {
  return <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    marginBottom: '0.5rem'
  }}>
      <span style={{
    fontSize: '0.625rem',
    color: '#6b7280',
    textTransform: 'uppercase',
    fontWeight: '500',
    letterSpacing: '0.05em'
  }}>
        {label}
      </span>
      {children}
    </div>;
};

export const BadgeContainer = ({children}) => {
  return <div style={{
    display: 'flex',
    gap: '0.25rem',
    flexWrap: 'wrap',
    justifyContent: 'flex-end',
    minWidth: '0',
    flex: '1'
  }}>
      {children}
    </div>;
};

export const ProductRequiredBadge = ({product}) => {
  const getBadgeStyle = product => {
    switch (product) {
      case 'Core Platform':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      case 'Routing':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      case 'Contextual':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(product);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {product}
    </span>;
};

export const SdkRequiredBadge = ({required}) => {
  const getBadgeStyle = required => {
    switch (required) {
      case 'Yes':
        return {
          background: '#C7E8F9',
          color: '#1A1A1A'
        };
        --blue;
      case 'No':
        return {
          background: '#F7D0E2',
          color: '#1A1A1A'
        };
        --pink;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(required);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {required}
    </span>;
};

export const CapabilityBadge = ({capability}) => {
  const getBadgeStyle = capability => {
    switch (capability) {
      case 'Event Collection':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Cohort Activation':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Campaign Optimization':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Identity Signal':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Contextual Signal':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Connectivity':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Routing':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Data Collaboration':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(capability);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
      {capability}
    </span>;
};

export const EnvironmentBadge = ({environment}) => {
  const getBadgeStyle = environment => {
    switch (environment) {
      case 'Web':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'iOS':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'Android':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'CTV':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'API Direct':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(environment);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
      {environment}
    </span>;
};

export const DirectionBadge = ({direction}) => {
  const getBadgeStyle = direction => {
    switch (direction) {
      case 'Bidirectional':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      case 'Destination':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      case 'Source':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(direction);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {direction}
    </span>;
};

<Card title="">
  <div style={{ display: 'flex', alignItems: 'center', marginBottom: '1rem' }}>
    <div style={{ width: '32px', height: '32px', marginRight: '0.75rem', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
      <img src="https://mintcdn.com/permutive/pNhz39ducTVcQczh/images/integrations/logos/google-ad-manager.svg?fit=max&auto=format&n=pNhz39ducTVcQczh&q=85&s=0af7359c310585ef11d412ee1dbc0e04" alt="Google Ad Manager" style={{ maxWidth: '32px', maxHeight: '32px', display: 'block' }} width="2454" height="2454" data-path="images/integrations/logos/google-ad-manager.svg" />
    </div>

    <h3 style={{ margin: 0, fontSize: '1.125rem', fontWeight: '600' }}>Google Ad Manager</h3>
  </div>

  <div style={{ marginBottom: '1rem' }}>
    <BadgeRowCenter label="Direction">
      <DirectionBadge direction="Bidirectional" />
    </BadgeRowCenter>

    <BadgeRowCenter label="Environment">
      <BadgeContainer>
        <EnvironmentBadge environment="Web" />

        <EnvironmentBadge environment="iOS" />

        <EnvironmentBadge environment="Android" />

        <EnvironmentBadge environment="CTV" />

        <EnvironmentBadge environment="API Direct" />
      </BadgeContainer>
    </BadgeRowCenter>

    <BadgeRowCenter label="Capability">
      <BadgeContainer>
        <CapabilityBadge capability="Event Collection" />

        <CapabilityBadge capability="Cohort Activation" />

        <CapabilityBadge capability="Campaign Optimization" />
      </BadgeContainer>
    </BadgeRowCenter>

    <BadgeRowCenter label="SDK Required">
      <SdkRequiredBadge required="Yes" />
    </BadgeRowCenter>

    <BadgeRowCenter label="Product(s) Required">
      <ProductRequiredBadge product="Core Platform" />
    </BadgeRowCenter>
  </div>

  <p style={{ margin: 0, fontSize: '0.875rem', color: '#6b7280', lineHeight: '1.5' }}>
    Google Ad Manager is a comprehensive ad management platform that helps publishers sell, deliver, and optimize ads across web, app, and video content.
  </p>
</Card>

<CardGroup cols={2}>
  <Card title="Setup" href="#setup" icon="gear" />

  <Card title="Troubleshooting" href="#troubleshooting" icon="wrench" />
</CardGroup>

## Overview

Google Ad Manager (GAM) is Google's comprehensive ad serving platform that helps publishers manage their advertising inventory and maximize revenue. Our integration with Google Ad Manager (GAM) primarily enables you to target your advertising campaigns with Permutive cohorts. Additionally, this integration can be used to ingest ad impressions and clicks into Permutive.

This integration is both a Source and Destination:

* **Source:** Permutive is able to ingest ad impressions and clicks.
* **Destination:** Permutive is able to activate your cohorts in GAM.

Use cases include:

* Send Permutive cohorts to your ad server so that they can be used for decisioning and targeting in real-time.
* Track ad impressions and clicks in Permutive, for insights, retargeting or modeling.
* **(Advanced) Ad Logs:** Capture every ad click in Permutive through Ad Logs in GAM 360.
* **(Advanced) Campaign Optimization:** Optimize your GAM campaigns with Permutive's AI.

## Environment Compatibility

| Environment    | Supported    | Notes                                                                                                                                 |
| -------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Web**        | <YesBadge /> | --                                                                                                                                    |
| **iOS**        | <YesBadge /> | Cohort targeting and ad impression events are supported. Advanced event collection (SlotViewable, SlotClicked, etc.) requires Ad Logs |
| **Android**    | <YesBadge /> | Cohort targeting and ad impression events are supported. Advanced event collection (SlotViewable, SlotClicked, etc.) requires Ad Logs |
| **CTV**        | <YesBadge /> | Supported via Permutive CTV SDKs                                                                                                      |
| **API Direct** | <YesBadge /> | For environments where SDK deployment is not possible                                                                                 |

## Prerequisites

* **Network Code** - You must provide your Network Code, which is displayed in your [GAM dashboard](https://support.google.com/admanager/answer/7674889?hl=en).
* **Permissions** - You must grant Permutive permission to *create targeting keys and values* in your GAM account. This allows Permutive to programmatically create targeting key-values when you configure cohorts for activation into GAM. To do this, assign [*dfp@permutive.com*](mailto:dfp@permutive.com) a custom role with the following permissions:
  * View ad units, placements and key-values
  * Edit ad units, placements and key-values
  * Edit key-values values
  * Access to Inventory tab

<Expandable title="Advanced: Ad Logs">
  #### Ad Logs Prerequisites

  For more comprehensive ad click tracking, Permutive is able to ingest GAM Data Transfer Files for customers using Google Ad Manager 360.

  * You must be using Google Ad Manager 360.
  * You should have a Data Transfer storage bucket setup, as described [here](https://support.google.com/admanager/answer/1733127).
  * You must be an Administrator of your GAM network, and able to grant access to your Data Transfer storage bucket.
</Expandable>

<Expandable title="Advanced: Campaign Optimization">
  #### Campaign Optimization Prerequisites

  To utilize Permutive's [Optimization product](/products/workflows-insights/optimization) with your GAM campaigns, there are additional prerequisites:

  * **Permissions** - Additional GAM permissions are required to enable Campaign Optimization. See the [GAM API Usage Guide](/guides/platform-guides/gam-api-usage) for the complete list of required permissions. Your CSM will work with you to ensure the custom role for [*dfp@permutive.com*](mailto:dfp@permutive.com) includes all necessary permissions.
  * **AI Opt-in** - You must opt in to Permutive's AI product development principles to access AI-based recommendations.
  * **Cohorts** - At least 100 cohorts activated to GAM is recommended for consistent AI recommendations.
</Expandable>

## Setup

<Tabs>
  <Tab title="Primary Setup Steps">
    <Steps>
      <Step title="Enable in Permutive Dashboard">
        You must enable the Google Ad Manager integration in the Permutive dashboard, if this has not already be done. Please ensure you’ve already granted permissions in GAM appropriately (see prerequisites).
        In the Permutive dashboard, navigate to your workspace's integrations page. Click *Add Integration* and select *Google Ad Manager*.
        You will be asked to enter your *Network Code* at this stage.
      </Step>

      <Step title="Check Key-Values in GAM">
        In your GAM dashboard, head to "Inventory" => *Key-Values* and search for `permutive`. You should find that a targeting key has been created for *permutive*, with the Reportable attribute set to *On*. If the *Reportable* attribute is *Off*, click on *permutive* and select *include values in reporting*. Hit *Save*. If you cannot find the targeting key-value, please reach out to Permutive Support.
      </Step>

      <Step title="Verify Setup">
        In the Permutive Dashboard, navigate to one of your cohorts. Check that the Google Ad Manager activation sync is visible. You can try toggling this to *On*. After doing this, in your GAM dashboard you should see a new targeting value created under the *permutive* targeting key, with the value corresponding your cohort's ID. This verifies your integration setup is successful.
      </Step>
    </Steps>

    <Expandable title="Advanced: Ad Logs">
      ### Ad Logs Setup

      <Steps>
        <Step title="Enable in Permutive Dashboard">
          You must first enable the GAM Logs integration in your Permutive Dashboard.
        </Step>

        <Step title="Grant Storage Bucket Access">
          Grant read access to your Ad Manager storage bucket to the user shown in the integration configuration page in the dashboard. For more information please see the "Manage access to your Ad Manager storage buckets" section of the GAM [Data Transfer Files documentation](https://support.google.com/admanager/answer/1733127).
        </Step>

        <Step title="Create Targeting Keys in GAM">
          In your GAM dashboard, under *Inventory* => *Key-Values*, create the following keys:

          * puid
          * prmtvvid
          * prmtvsid
          * prmtvwid

          The value type for all keys must be set as *dynamic* and reporting should be *disabled*.
        </Step>

        <Step title="Verify Setup">
          You should see a new event, called *GamLogSlotClicked* on the Events page in your Permutive Dashboard.
          Check back in 24 hours -- you should see on the Events page that Permutive is ingesting these events from your Ad Logs (check under *Recent Events*).
        </Step>
      </Steps>

      <Note>In order for the integration to track impressions and clicks from Mobile Apps, you must first configure our GAM integration for Android and/or iOS.</Note>
    </Expandable>

    <Expandable title="Advanced: Optimization Configuration">
      ### Campaign Optimization Setup

      <Note>Please speak to your CSM to enable this feature.</Note>
    </Expandable>
  </Tab>

  <Tab title="Web">
    ### Deploy GAM specific JavaScript

    You'll need to deploy a small piece of additional JavaScript on-site, alongside the standard Permutive tag. This script ensures that we are always able to target users with cohort membership data from their previous pages views or browsing sessions. We recommend deploying this script immediately above the Permutive tag.
    <Note>In many cases, this step will have been carried out as part of your initial Permutive deployment.</Note>

    ```javascript theme={"dark"}
    window.googletag = window.googletag || {};
    window.googletag.cmd = window.googletag.cmd || [];
    window.googletag.cmd.push(function () {
      if (window.googletag.pubads().getTargeting('permutive').length === 0) {
        var kvs = window.localStorage.getItem('_pdfps');
        window.googletag.pubads().setTargeting('permutive', kvs ? JSON.parse(kvs) : []);
      }
    });
    ```
  </Tab>

  <Tab title="iOS">
    ### Integrate Permutive with Google Mobile Ads on iOS

    You'll need to update your iOS apps to include the Permutive iOS SDK to target your GAM ads in-app.

    Our SDK offers a `googleCustomTargeting` function to return a dictionary of current targeting data. This is able to be added to the `customTargeting` of `GAMRequest` instances to include current Permutive information for ad targeting. The returned dictionary contains Permutive targeting data for the user. If the ad request is for a "page" being tracked through a `PageTracker`, the `googleCustomTargeting` function can accept an optional active `PageTracker` instance parameter, if available, to improve targeting information. If you are already setting `customTargeting` property on your `GAMRequest`, you will need to merge the returned dictionary with your existing values.

    The returned dictionary from calling `googleCustomTargeting` will contain the following keys and their associated values:

    ```json theme={"dark"}
    [
    "permutive": ["Cohort1", "Cohort2"],
    "puid": "permutiveID",
    "ptime": timestamp,
    "prmtvwid": randomUUID,
    "prmtvsid": sessionId, // if available
    "prmtvvid": viewID // if available (will be added if using a PageTracker)
    ]
    ```

    To use this method, simply call `Permutive.shared.googleCustomTargeting`. You can optionally pass in a `PageTracker` instance if you wish to populate the prmtvvid field as shown in the example below.

    <CodeGroup>
      ```swift Swift theme={"dark"}
      let banner = GAMBannerView(adSize: kGADAdSizeBanner)

      let adRequest = GAMRequest()

      adRequest.customTargeting = Permutive.shared.googleCustomTargeting(adTargetable: pageTracker) /* if using pagetracker, otherwise can be nil*/

      banner.load(request)
      ```

      ```objective-c Objective-C theme={"dark"}
      GAMRequest *adRequest = [GAMRequest request];

      NSDictionary<NSString *, NSString*> *customTargeting = [Permutive.shared googleCustomTargetingWithAdTargetable:nil];

      request.customTargeting = customTargeting;

      [bannerView loadRequest:adRequest];
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Android">
    ### Integrate Permutive with Google Mobile Ads on Android

    You'll need to integrate your Android apps to include the Permutive Android SDK to target your ads in-app.

    Alongside our Android SDK, you must add our google-ads dependency to your Gradle build:

    <CodeGroup>
      ```kotlin Kotlin theme={"dark"}
      implementation("com.permutive.android:google-ads:2.2.0")
      ```

      ```groovy Groovy theme={"dark"}
      implementation "com.permutive.android:google-ads:2.2.0"
      ```
    </CodeGroup>

    Our Android SDK then provides an easy way to add Permutive targeting data to your Ad Manager ad requests:

    <CodeGroup>
      ```kotlin Kotlin theme={"dark"}
      // To add custom targeting:
      val adRequest1 = 
          AdManagerAdRequest.Builder()
              .addPermutiveTargeting(permutive)
              .build()

      // Or simply without the build call:
      val adRequest2 = 
          AdManagerAdRequest.Builder()
              .buildWithPermutiveTargeting(permutive)
      ```

      ```java Java theme={"dark"}
      // To add custom targeting:
      AdManagerAdRequest adRequest = new AdManagerAdRequest.Builder()
          .addPermutiveTargeting(permutive)
          .build();
      ```
    </CodeGroup>
  </Tab>

  <Tab title="API Direct">
    ### Cohort Activation via API Direct

    In environments where it is not possible to deploy a Permutive SDK, you can use Permutive's CCS (Custom Cohort Segmentation) API for event tracking and segmentation instead.

    Access to this API requires customer-specific authorization. You will need a dedicated API key from Permutive.

    #### How it Works

    The CCS API can be used to:

    1. Track events for a specific user (optional)
    2. Retrieve cohort IDs for activation

    <Note>
      The `events` array in the request is optional. If you only need to retrieve cohort memberships without tracking a new event, you can pass an empty array.
    </Note>

    **Example Request:**

    ```bash theme={"dark"}
    curl --request POST \
         --url 'https://api.permutive.app/ccs/v1/segmentation?activations=true&synchronous-validation=false&k=PERMUTIVE_API_KEY' \
         --header 'accept: application/json' \
         --header 'content-type: application/json' \
         --data '
    {
      "alias": {
        "tag": "user_id",
        "id": "12345"
      },
      "events": [
        {
          "name": "Pageview",
          "time": "2025-10-02T09:40:43.179Z",
          "properties": {}
        }
      ]
    }
    '
    ```

    The API accepts a user identity passed in the `alias` object. Permutive then either links this identity to an existing Permutive user ID or creates a new Permutive user ID if the identity hasn't been seen before.

    For cross-environment segmentation and targeting, the identity provided should be consistent with identities used in your other environments (web, app).

    **Example Response:**

    ```json theme={"dark"}
    {
      "user_id": "2008c38f-dece-4570-976d-87593ed001c3",
      "cohorts": ["12345", "23456", "34567"],
      "activations": {
        "target_dfp": ["12345"]
      }
    }
    ```

    The API response includes cohort IDs for GAM activation under the `target_dfp` key within the `activations` object. These can then be passed to GAM as key-values for targeting.

    **Important Notes:**

    * Replace `PERMUTIVE_API_KEY` with your actual Permutive API key
    * The `activations=true` query parameter is required to receive activation data in the response
  </Tab>
</Tabs>

## Usage

* [Activate Contextual Cohorts in GAM](/guides/signals/cohorts/contextual/deploying-to-google-ad-manager) — target ads based on page content without the Permutive SDK
* [Optimize your campaigns with Campaign Optimization](/products/workflows-insights/optimization)

## Data Types

With your GAM integration setup, you'll see the following additional event types collected in Permutive:

<AccordionGroup>
  <Accordion title="SlotViewable">
    Tracks for every ad impression that becomes viewable. Based on Google Publisher Tag's [ImpressionViewableEvent](https://developers.google.com/publisher-tag/reference#googletag.events.ImpressionViewableEvent).

    <ResponseField name="advertiser_id" type="number">
      The Advertiser ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="line_item_id" type="number">
      The Line Item ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="campaign_id" type="number">
      The Campaign ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="creative_id" type="number">
      The Creative ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="service_name" type="string">
      The service name, from GAM.
    </ResponseField>

    <ResponseField name="slot.ad_unit_path" type="string">
      The ad unit path, from GAM.
    </ResponseField>

    <ResponseField name="slot.slot_element_id" type="string">
      The slot element ID, from GAM.
    </ResponseField>
  </Accordion>

  <Accordion title="SlotClicked">
    Tracks a subset of your ad clicks.

    <ResponseField name="advertiser_id" type="number">
      The Advertiser ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="line_item_id" type="number">
      The Line Item ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="campaign_id" type="number">
      The Campaign ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="creative_id" type="number">
      The Creative ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="service_name" type="string">
      The service name, from GAM.
    </ResponseField>

    <ResponseField name="slot.ad_unit_path" type="string">
      The ad unit path, from GAM.
    </ResponseField>

    <ResponseField name="slot.slot_element_id" type="string">
      The slot element ID, from GAM.
    </ResponseField>

    <ResponseField name="is_empty" type="boolean">
      Indicates whether an empty creative was served.
    </ResponseField>

    <ResponseField name="width" type="number">
      The width of the creative served.
    </ResponseField>

    <ResponseField name="height" type="number">
      The height of the creative served.
    </ResponseField>
  </Accordion>
</AccordionGroup>

<Expandable title="Advanced: Ad Logs">
  ### Ad Logs Data Types

  <Accordion title="GamLogSlotClicked">
    Tracks your ad clicks comprehensively, based on GAM's [Data Transfer Files](https://support.google.com/admanager/answer/1733124?hl=en#zippy=%2Cabout-the-data-contained-in-data-transfer-files%2Cdownload-a-sample-file%2Chow-files-are-delivered%2Cfile-names%2Cdata-transfer-files-in-the-ad-request-process%2Cstore-files-locally%2Clearn-about-the-bigquery-data-transfer-service%2Cmake-large-data-transfer-files-easier-to-process).

    <ResponseField name="advertiser_id" type="number">
      The Advertiser ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="line_item_id" type="number">
      The Line Item ID for this impression, from GAM.
    </ResponseField>

    <ResponseField name="slot.targeting_keys" type="list[object]">
      List of targeting keys present on the impression.
    </ResponseField>

    <ResponseField name="slot.targeting_keys.key" type="string">
      Represents a GAM targeting key.
    </ResponseField>

    <ResponseField name="slot.targeting_keys.values" type="list[string]">
      Represents GAM targeting values.
    </ResponseField>
  </Accordion>
</Expandable>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Unable to enable Google Ad Manager integration in Permutive Dashboard">
    If you see an error when enabling the Google Ad Manager integration, check that you have granted the correct permissions to *[dfp@permutive.com](mailto:dfp@permutive.com)* (see Prerequisites).
  </Accordion>

  <Accordion title="The `permutive` targeting key was not created">
    Double check that you have granted the correct permissions to *[dfp@permutive.com](mailto:dfp@permutive.com)* (see Prerequisites).
    In rare cases, you may have reached GAMs limit of 200 active targeting keys. In this case, you must remove an old/inactive key to enable Permutive.
  </Accordion>

  <Accordion title="Permutive targeting values not appearing in ad requests">
    If Permutive cohorts are not being passed to GAM, check the following:

    * **Timing Issue**: Open your browser console and append `?googfc` to your site URL to access the GAM console. Look for the "permutive" targeting key in the **Page Request** tab. If Permutive values appear **after** "Calling fillslot", the targeting is being set too late. To fix this, ensure the Permutive tag loads as early as possible in the page `<head>`, ideally before `googletag.enableServices()` is called.
    * **Missing Cached Segments**: Deploy the GAM-specific JavaScript snippet (shown in the Web setup tab) to ensure cached cohorts from previous sessions are always available for targeting.
    * **First Pageview Targeting**: If first-pageview targeting is critical, consider implementing a timeout that waits for Permutive to load before enabling GAM services.
  </Accordion>

  <Accordion title="Mobile app not passing Permutive segments to GAM">
    For iOS and Android apps, verify the following:

    * **iOS**: Confirm you're calling `Permutive.shared.googleCustomTargeting()` and passing the result to your `GAMRequest.customTargeting` property. If using a PageTracker, pass it as a parameter to include the `prmtvvid` field.
    * **Android**: Ensure you've added the `com.permutive.android:google-ads` dependency and are using `.addPermutiveTargeting(permutive)` or `.buildWithPermutiveTargeting(permutive)` on your `AdManagerAdRequest.Builder`.
    * **AAID/IDFA**: Use a proxy tool (like mitmproxy) to verify the Permutive SDK is tracking the AAID (Android) or IDFA (iOS) identifier. On Android, this requires explicit implementation as outlined in the developer documentation.
    * **Event Validation**: Check that Permutive events are being accepted (HTTP 200 response) and not rejected (4xx response). Enable debug mode on Android with `setDeveloperMode(true)` to see detailed logs.
  </Accordion>

  <Accordion title="Low targetable impression volume">
    If your targetable impression volume is lower than expected:

    * Ensure the Permutive tag loads early in the page lifecycle, preferably in the `<head>` tag rather than through a tag manager.
    * Implement the GAM-specific JavaScript snippet to read cached cohorts from local storage, ensuring returning visitors are immediately targetable.
    * Review the timing of when `googletag.enableServices()` is called relative to Permutive initialization. Consider adding a configurable timeout (e.g., 2 seconds) to wait for Permutive before enabling GAM services.
  </Accordion>
</AccordionGroup>

## Changelog

### June 2025

* Enhanced support for activating Contextual Cohorts via GAM

<Info>
  For detailed changelog information, visit our [Changelog](https://changelog.permutive.com/).
</Info>
