> ## 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.

# YouTube

> Integrate with YouTube 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/youtube.svg?fit=max&auto=format&n=pNhz39ducTVcQczh&q=85&s=6e88a7f65b7b4bd42f6c6b9cf8f4ef4b" alt="YouTube" style={{ maxWidth: '32px', maxHeight: '32px', display: 'block' }} width="24" height="24" data-path="images/integrations/logos/youtube.svg" />
    </div>

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

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

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

        <EnvironmentBadge environment="iOS" />

        <EnvironmentBadge environment="Android" />

        <EnvironmentBadge environment="CTV" />
      </BadgeContainer>
    </BadgeRowCenter>

    <BadgeRowCenter label="Capability">
      <BadgeContainer>
        <CapabilityBadge capability="Cohort Activation" />
      </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' }}>
    YouTube is the world's largest video platform, enabling content creators and advertisers to reach global audiences.
  </p>
</Card>

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

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

<Note>
  Looking to target ads on YouTube.com or your YouTube channel instead? See the [YouTube.com Integration](/integrations/social-media/youtube).
</Note>

## Overview

YouTube is the world's largest video platform, enabling publishers to embed and monetize video content through various advertising formats. This integration enables cohort activation for video ads served in YouTube players embedded on your own website or app.

This integration is a Destination:

* **Destination:** Permutive cohorts are passed to YouTube IFrame Player ad requests as key-value parameters for real-time targeting.

Use cases include:

* Target video ads in embedded YouTube players with Permutive cohorts
* Deliver personalized video advertising based on user behavior and interests
* Optimize video ad inventory monetization with audience targeting
* Enable real-time cohort activation for pre-roll, mid-roll, and post-roll video ads

## Environment Compatibility

| Environment    | Supported    | Notes                                           |
| -------------- | ------------ | ----------------------------------------------- |
| **Web**        | <YesBadge /> | Embedded YouTube player with IFrame API         |
| **iOS**        | <YesBadge /> | Custom implementation required—contact your CSM |
| **Android**    | <YesBadge /> | Custom implementation required—contact your CSM |
| **CTV**        | <YesBadge /> | Custom implementation required—contact your CSM |
| **API Direct** | <NoBadge />  | --                                              |

## Prerequisites

* **Google Ad Manager Integration**: The [GAM integration](/integrations/advertising/ad-servers/google-ad-manager) must be enabled in Permutive before setting up YouTube targeting.
* **Permutive SDK**: The Permutive SDK must be installed on your website or app where the YouTube player is embedded.
* **Cohorts with GAM Activation**: Cohorts must have GAM Activation Sync enabled in the Permutive dashboard.
* **YouTube IFrame API** (Web): You must be using the [YouTube IFrame Player API](https://developers.google.com/youtube/iframe_api_reference) to embed videos.
* **Access to Player Configuration**: You need the ability to modify your YouTube player configuration code to pass custom parameters.

## Setup

<Tabs>
  <Tab title="Primary Setup Steps">
    <Steps>
      <Step title="Enable Google Ad Manager Integration">
        Before setting up YouTube targeting, you must enable the Google Ad Manager integration in the Permutive dashboard. See the [Google Ad Manager integration documentation](/integrations/advertising/ad-servers/google-ad-manager) for detailed setup instructions.
      </Step>

      <Step title="Enable GAM Activation Sync for Cohorts">
        Navigate to the cohorts you want to target in embedded YouTube players in the Permutive dashboard. Enable the Google Ad Manager Activation Sync for each cohort. This will make the cohorts available in localStorage for targeting.
      </Step>

      <Step title="Configure Your YouTube Player">
        Follow the environment-specific tab (Web, iOS, Android, or CTV) for detailed implementation steps for your YouTube player. Each platform requires passing Permutive cohort IDs as custom parameters in video ad requests.
      </Step>

      <Step title="Verify Targeting">
        Test your implementation to ensure cohort IDs are being passed correctly in ad requests from the YouTube player. Use your browser's developer tools or platform-specific debugging tools to inspect ad request parameters.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Web">
    ### Embedded YouTube Player Setup (YouTube for Publishers)

    When embedding a YouTube video using the YouTube IFrame API, you can pass Permutive cohorts as custom key-value pairs for ad targeting.

    <Steps>
      <Step title="Retrieve Permutive Cohort IDs">
        Permutive stores cohort IDs in the localStorage variable `_pdfps`. You can retrieve these dynamically when initializing your YouTube player:

        ```javascript theme={"dark"}
        var cohortIds;
        try {
          cohortIds = JSON.parse(window.localStorage._pdfps || '[]')
            .slice(0, 250)
            .toString();
        } catch (e) {
          cohortIds = '';
        }
        ```
      </Step>

      <Step title="Configure YouTube Player with embedConfig">
        When initializing the YouTube IFrame Player, pass cohort IDs through the `embedConfig` object. Use `adsConfig.adTagParameters.cust_params` to pass custom targeting parameters.

        <Note>The `cust_params` value must be URI-encoded as required by Google Ad Manager.</Note>

        ```javascript theme={"dark"}
        var player;
        function onYouTubeIframeAPIReady() {
          // Retrieve cohort IDs
          var cohortIds;
          try {
            cohortIds = JSON.parse(window.localStorage._pdfps || '[]')
              .slice(0, 250)
              .toString();
          } catch (e) {
            cohortIds = '';
          }

          // Initialize player with cohort targeting
          player = new YT.Player('player', {
            height: '390',
            width: '640',
            videoId: 'YOUR_VIDEO_ID',
            events: {
              'onReady': onPlayerReady,
              'onStateChange': onPlayerStateChange
            },
            embedConfig: {
              adsConfig: {
                adTagParameters: {
                  cust_params: encodeURIComponent('permutive=' + cohortIds)
                }
              }
            }
          });
        }
        ```
      </Step>

      <Step title="Verify Targeting">
        Verify that cohort IDs are being passed correctly:

        * Check your browser's network tab for ad requests from the YouTube player
        * Look for the `cust_params` parameter in ad request URLs
        * Confirm the permutive key-values are present and properly encoded
      </Step>
    </Steps>

    <Warning>
      If the YouTube player loads before the Permutive SDK has run on the page, the cohort IDs retrieved from localStorage may not be updated from the previous pageview. Consider delaying player initialization until after Permutive has loaded.
    </Warning>
  </Tab>

  <Tab title="iOS">
    ### Embedded YouTube Player Setup for iOS

    For iOS apps embedding YouTube players with Permutive cohort targeting, the typical approach involves using Google's Interactive Media Ads (IMA) SDK to pass cohort IDs as custom parameters in video ad requests.

    <Info>
      Contact your Permutive Customer Success Manager for guidance on implementing cohort targeting in embedded YouTube players on iOS. They can provide recommendations based on your specific app architecture and ad serving configuration.
    </Info>
  </Tab>

  <Tab title="Android">
    ### Embedded YouTube Player Setup for Android

    For Android apps embedding YouTube players with Permutive cohort targeting, the typical approach involves using Google's Interactive Media Ads (IMA) SDK to pass cohort IDs as custom parameters in video ad requests.

    <Info>
      Contact your Permutive Customer Success Manager for guidance on implementing cohort targeting in embedded YouTube players on Android. They can provide recommendations based on your specific app architecture and ad serving configuration.
    </Info>
  </Tab>

  <Tab title="CTV">
    ### Embedded YouTube Player Setup for CTV

    For CTV applications embedding YouTube players with Permutive cohort targeting, the typical approach involves using Google's Interactive Media Ads (IMA) SDK to pass cohort IDs as custom parameters in video ad requests. Implementation details will vary by platform (e.g., Roku, Fire TV, Apple TV).

    <Info>
      Contact your Permutive Customer Success Manager for guidance on implementing cohort targeting in embedded YouTube players on CTV. They can provide recommendations based on your specific CTV platform and ad serving configuration.
    </Info>
  </Tab>
</Tabs>

## Data Types

Permutive cohorts are passed to YouTube player ad requests as key-value parameters, enabling real-time targeting for video ads in embedded players.

<AccordionGroup>
  <Accordion title="Cohort Activation Data">
    Permutive cohorts are passed to YouTube player ad requests as key-value pairs, enabling real-time targeting based on your audience segments.

    <ResponseField name="permutive" type="string">
      Comma-separated list of Permutive cohort IDs that the user belongs to. Passed via `cust_params` parameter in video ad requests.

      Example: `permutive=abc123,def456,ghi789`
    </ResponseField>

    <ResponseField name="_pdfps" type="array">
      For Web implementations, cohort IDs are retrieved from the localStorage variable `_pdfps` which contains an array of cohort IDs the user belongs to. Updated in real-time as users qualify for cohorts.
    </ResponseField>

    <ResponseField name="cust_params" type="string">
      The custom parameters field in YouTube IFrame API's `adsConfig.adTagParameters` or IMA SDK's ad request. Must be URI-encoded.

      Example: `cust_params=permutive%3Dabc123%2Cdef456%2Cghi789`
    </ResponseField>

    <ResponseField name="embedConfig" type="object">
      For Web implementations using YouTube IFrame API, the configuration object passed to the player that includes ad targeting parameters.
    </ResponseField>
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Cohorts not appearing in ad requests (Embedded Player)">
    If cohort IDs are not being passed to your YouTube player ad requests:

    * **Check localStorage**: Open your browser's developer console and inspect `localStorage._pdfps` to verify cohort IDs are being stored
    * **Verify GAM Activation**: Ensure the cohorts have GAM Activation Sync enabled in the Permutive dashboard
    * **Check timing**: The YouTube player may be loading before Permutive has run. Consider delaying player initialization until after Permutive loads
    * **Verify encoding**: Ensure `cust_params` values are properly URI-encoded using `encodeURIComponent()`
    * **Inspect network requests**: Use your browser's network tab to inspect ad requests and verify the `permutive` key-values are present in `cust_params`
  </Accordion>

  <Accordion title="Cohorts not updating from previous pageview">
    If the YouTube player is showing cohort data from a previous pageview:

    * **Problem**: The video/player loads before Permutive SDK has executed on the current page, so `localStorage._pdfps` contains stale cohort IDs
    * **Solution**: Delay YouTube player initialization until after Permutive has loaded. You can use Permutive's ready callback:

    ```javascript theme={"dark"}
    window.permutive = window.permutive || [];
    window.permutive.push(['ready', function() {
      // Initialize YouTube player here
      onYouTubeIframeAPIReady();
    }]);
    ```
  </Accordion>

  <Accordion title="Cohorts not appearing in mobile/CTV implementations">
    If cohort IDs are not being passed in mobile or CTV implementations:

    * **Verify SDK integration**: Ensure the Permutive SDK is properly integrated on your mobile/CTV platform
    * **Check cohort retrieval**: Verify you're correctly retrieving cohort IDs from the Permutive SDK using the platform-specific method
    * **Verify parameter encoding**: Ensure parameters are properly URI-encoded before including in ad requests
    * **Test with debugging tools**: Use platform-specific debugging tools to inspect ad requests and verify parameters are included
    * **Contact your CSM**: Mobile and CTV implementations can vary significantly—reach out to your Permutive Customer Success Manager for platform-specific guidance
  </Accordion>

  <Accordion title="GAM integration not enabled">
    The YouTube integration requires Google Ad Manager to be set up first:

    * **Prerequisite**: Complete the [Google Ad Manager integration setup](/integrations/advertising/ad-servers/google-ad-manager) before configuring YouTube targeting
    * **Verify GAM connection**: In the Permutive dashboard, check that GAM is listed under Integrations and shows as connected
    * **Check permissions**: Ensure [dfp@permutive.com](mailto:dfp@permutive.com) has the required permissions in your GAM account
  </Accordion>
</AccordionGroup>

## Changelog

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