PMax : Google dévoile enfin les placements dans le rapport Where Ads Showed

Pendant trois ans, Performance Max a été une boîte noire. Vous injectiez du budget, Google décidait où diffuser — Search, Shopping, Display, YouTube, Discover, Gmail, Maps — et vous n'aviez aucune visibilité granulaire sur les placements réels. Cette époque est terminée. Google vient d'intégrer les données de placement PMax dans le rapport "Where ads showed", et les implications pour l'optimisation croisée SEO/SEA sont considérables.

Ce que le rapport "Where ads showed" expose réellement pour PMax

Avant cette mise à jour, le rapport "Where ads showed" (anciennement "Placements") ne couvrait que les campagnes Display et Video classiques. Pour PMax, vous n'aviez accès qu'à des métriques agrégées par groupe d'assets, sans savoir si vos impressions venaient de youtube.com, d'un site partenaire Display de niche, ou de Gmail.

Google expose désormais, pour chaque campagne PMax :

  • Les domaines et apps où vos annonces ont été diffusées sur le réseau Display et les partenaires de recherche
  • Les chaînes YouTube et vidéos spécifiques sur lesquelles vos annonces ont été diffusées
  • Les emplacements Gmail, Discover et Maps (avec un niveau de détail variable selon le canal)

Le niveau de granularité n'est pas identique à celui d'une campagne Display manuelle. Vous n'obtiendrez pas le détail URL par URL de chaque page Display. Mais vous obtenez les domaines, ce qui permet enfin d'exclure les placements toxiques et de comprendre la répartition budgétaire réelle.

Comment accéder aux données

Dans l'interface Google Ads :

  1. Sélectionnez votre campagne PMax
  2. Allez dans Insights and Reports > Where ads showed
  3. Filtrez par type de placement (Websites, YouTube channels, YouTube videos, Apps, etc.)

Via l'API Google Ads (v17+), la ressource campaign_placement_view est désormais alimentée pour les campagnes de type PERFORMANCE_MAX. Voici un exemple de requête GAQL :

SELECT
  campaign.name,
  campaign_placement_view.resource_name,
  campaign_placement_view.placement,
  campaign_placement_view.placement_type,
  metrics.impressions,
  metrics.clicks,
  metrics.cost_micros,
  metrics.conversions
FROM campaign_placement_view
WHERE campaign.advertising_channel_type = 'PERFORMANCE_MAX'
  AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.impressions DESC
LIMIT 500

Cette requête retourne les 500 placements les plus impressionnés de vos campagnes PMax sur les 30 derniers jours. Le champ placement_type vous indique s'il s'agit d'un site web, d'une chaîne YouTube, d'une app mobile ou d'un autre type d'emplacement.

Pourquoi les données de placement PMax changent l'optimisation SEO/SEA

La transparence des placements PMax n'est pas juste une feature "nice to have" pour les media buyers. Elle ouvre des angles d'optimisation concrets pour les équipes qui gèrent simultanément SEO et SEA.

Identifier la cannibalisation Search/PMax

Un reproche récurrent contre PMax : les campagnes captent du trafic Search brandé qui aurait converti organiquement. Sans données de placement, impossible de prouver le phénomène. Avec le rapport "Where ads showed", vous pouvez maintenant quantifier la part d'impressions PMax sur google.com (Search) versus les autres canaux.

Prenons un scénario concret. Un e-commerce spécialisé en mobilier outdoor (12 000 pages produit, 3 500 pages catégorie) dépense 45 000 €/mois en PMax répartis sur 6 asset groups. Après activation du rapport, l'équipe constate que :

  • 62% des impressions PMax proviennent du réseau Search (google.com)
  • 23% proviennent de YouTube
  • 11% du réseau Display (dont 4% sur des sites à faible qualité)
  • 4% de Discover/Gmail

Sur les 62% Search, une analyse croisée avec les données Search Console révèle que 38% des requêtes captées par PMax sur Search correspondent à des mots-clés où le site est déjà positionné en top 3 organique. C'est du budget brûlé. La visibilité organique suffirait à capter ce trafic.

Script d'extraction croisée Search Console / Google Ads

Pour automatiser cette détection de cannibalisation, vous pouvez croiser les données de la Search Console API avec les termes de recherche PMax (disponibles dans le rapport "Search terms" de PMax, qui s'est aussi amélioré en parallèle) :

import json
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

# Extraction des requêtes organiques top 3 via Search Console API
def get_organic_top3_queries(site_url: str, creds: Credentials) -> set:
    service = build('searchconsole', 'v1', credentials=creds)
    response = service.searchanalytics().query(
        siteUrl=site_url,
        body={
            'startDate': '2026-01-20',
            'endDate': '2026-02-19',
            'dimensions': ['query'],
            'rowLimit': 25000,
            'dimensionFilterGroups': [{
                'filters': [{
                    'dimension': 'page',
                    'operator': 'contains',
                    'expression': site_url
                }]
            }]
        }
    ).execute()

    top3_queries = set()
    for row in response.get('rows', []):
        if row['position'] <= 3.0 and row['impressions'] > 50:
            top3_queries.add(row['keys'][0].lower())

    return top3_queries

# Comparaison avec les termes de recherche PMax exportés en CSV
def find_cannibalized_queries(
    organic_queries: set,
    pmax_search_terms_file: str
) -> list:
    cannibalized = []
    with open(pmax_search_terms_file, 'r') as f:
        import csv
        reader = csv.DictReader(f)
        for row in reader:
            term = row['Search term'].lower().strip()
            if term in organic_queries:
                cannibalized.append({
                    'query': term,
                    'pmax_impressions': int(row['Impressions']),
                    'pmax_clicks': int(row['Clicks']),
                    'pmax_cost': float(row['Cost']),
                    'pmax_conversions': float(row['Conversions'])
                })

    # Trier par coût décroissant pour prioriser
    cannibalized.sort(key=lambda x: x['pmax_cost'], reverse=True)
    return cannibalized

# Usage
organic = get_organic_top3_queries('https://www.mobilier-outdoor.fr', creds)
waste = find_cannibalized_queries(organic, 'pmax_search_terms_export.csv')

total_wasted = sum(item['pmax_cost'] for item in waste)
print(f"Budget potentiellement gaspillé sur des requêtes top 3 organique : {total_wasted:.2f} €")
print(f"Nombre de requêtes cannibalisées : {len(waste)}")
for item in waste[:20]:
    print(f"  {item['query']}{item['pmax_cost']:.2f} € — {item['pmax_conversions']} conv.")

Dans notre scénario mobilier outdoor, ce script a identifié 847 requêtes cannibalisées représentant 11 200 €/mois de dépense PMax sur des positions déjà dominées en organique. En ajoutant ces termes en négatifs au niveau campagne (désormais possible sur PMax depuis les brand exclusions élargies), l'équipe a réalloué ce budget vers des asset groups ciblant des requêtes mid-funnel où la visibilité organique était faible.

Nettoyer les placements Display toxiques de PMax

L'un des angles morts les plus coûteux de PMax a toujours été la diffusion Display non contrôlée. Google optimise pour les conversions, mais l'algorithme n'a aucune notion de brand safety avancée. Vos annonces pour du mobilier premium peuvent se retrouver sur des sites de jeux gratuits avec un taux de clic accidentel de 12% et un taux de conversion de 0,01%.

Exporter et analyser les placements Display

Avec les nouvelles données, vous pouvez enfin scripter l'extraction et l'exclusion automatique :

// Google Ads Script — à exécuter dans l'éditeur de scripts Google Ads
function analyzePMaxDisplayPlacements() {
  const CAMPAIGN_NAME = 'PMax - Mobilier Outdoor';
  const MIN_IMPRESSIONS = 100;
  const MAX_CTR_THRESHOLD = 0.08; // CTR > 8% = suspect (clics accidentels)
  const MIN_COST_THRESHOLD = 5.0; // Au moins 5€ dépensés

  const report = AdsApp.report(
    `SELECT
       CampaignName,
       DisplayName,
       Domain,
       Impressions,
       Clicks,
       Cost,
       Conversions,
       Ctr
     FROM CAMPAIGN_PLACEMENT_PERFORMANCE_REPORT
     WHERE CampaignName = '${CAMPAIGN_NAME}'
       AND Impressions > ${MIN_IMPRESSIONS}
     DURING LAST_30_DAYS`
  );

  const rows = report.rows();
  const suspiciousPlacements = [];
  const lowQualityPlacements = [];

  while (rows.hasNext()) {
    const row = rows.next();
    const ctr = parseFloat(row['Ctr'].replace('%', '')) / 100;
    const conversions = parseFloat(row['Conversions']);
    const cost = parseFloat(row['Cost'].replace(/[^0-9.]/g, ''));
    const impressions = parseInt(row['Impressions'].replace(/,/g, ''));
    const domain = row['Domain'];

    // CTR anormalement élevé + zéro conversion = placement toxique
    if (ctr > MAX_CTR_THRESHOLD && conversions === 0 && cost > MIN_COST_THRESHOLD) {
      suspiciousPlacements.push({
        domain: domain,
        impressions: impressions,
        ctr: ctr,
        cost: cost,
        conversions: conversions
      });
    }

    // Beaucoup d'impressions, aucun clic utile
    if (impressions > 1000 && conversions === 0 && cost > 10) {
      lowQualityPlacements.push({
        domain: domain,
        impressions: impressions,
        cost: cost
      });
    }
  }

  // Logging pour review avant exclusion
  Logger.log(`=== PLACEMENTS SUSPECTS (CTR > ${MAX_CTR_THRESHOLD * 100}%, 0 conv) ===`);
  suspiciousPlacements.forEach(p => {
    Logger.log(`${p.domain} | ${p.impressions} imp | CTR: ${(p.ctr*100).toFixed(1)}% | ${p.cost}€ | 0 conv`);
  });

  Logger.log(`\n=== PLACEMENTS LOW QUALITY (>1000 imp, 0 conv) ===`);
  lowQualityPlacements.forEach(p => {
    Logger.log(`${p.domain} | ${p.impressions} imp | ${p.cost}€ | 0 conv`);
  });

  Logger.log(`\nTotal suspect: ${suspiciousPlacements.length} placements`);
  Logger.log(`Total low quality: ${lowQualityPlacements.length} placements`);
  Logger.log(`Budget récupérable estimé: ${
    [...suspiciousPlacements, ...lowQualityPlacements]
      .reduce((sum, p) => sum + p.cost, 0)
      .toFixed(2)
  }€`);
}

Limites des exclusions PMax

Un trade-off majeur : PMax ne supporte toujours pas les exclusions de placement au niveau du groupe d'assets. Vous pouvez exclure des placements au niveau du compte via les listes d'exclusion de placements (Placement exclusion lists), mais pas au niveau de la campagne individuelle. Si vous gérez plusieurs campagnes PMax avec des stratégies différentes (une pour la prospection Display, une pour le retargeting), les exclusions s'appliquent uniformément.

La documentation Google Ads confirme cette limitation : les exclusions de placement au niveau compte s'appliquent à toutes les campagnes, y compris PMax (support Google Ads).

Pour les comptes gérant 5+ campagnes PMax avec des objectifs divergents, c'est un problème structurel non résolu par cette mise à jour.

Impact sur la stratégie de contenu et le SEO technique

Les données de placement PMax ne servent pas qu'au media buying. Elles révèlent des informations exploitables pour votre stratégie de contenu organique.

Découverte de requêtes et d'audiences

Si vos asset groups PMax performent fortement sur YouTube avec des termes de recherche spécifiques, c'est un signal que votre audience consomme du contenu vidéo sur ces thématiques. L'implication SEO : créer du contenu vidéo optimisé pour ces requêtes sur votre propre chaîne YouTube et l'embarquer dans les pages de destination concernées.

Sur notre exemple mobilier outdoor, les données PMax ont révélé que la requête "comment protéger salon de jardin hiver" générait des conversions significatives via YouTube, alors qu'aucun contenu organique n'existait sur le site pour cette intention informationnelle. La création d'un guide détaillé avec vidéo embarquée a capté 2 400 sessions organiques/mois supplémentaires en 8 semaines.

Cohérence entre landing pages PMax et pages organiques

Un problème technique fréquent : PMax sélectionne automatiquement les pages de destination via les "final URL expansion". Si votre site souffre de problèmes de rendu — par exemple un SPA React dont le SSR est mal configuré — Google peut envoyer du trafic payant vers des pages que Googlebot voit différemment de ce que l'utilisateur voit.

Ce décalage entre le rendu client et le rendu serveur est exactement le type de problème décrit dans notre analyse des SPA et pages blanches. Si PMax envoie du trafic vers une page dont le contenu principal dépend d'un hydration côté client, et que cette hydration échoue pour une fraction des utilisateurs, votre taux de conversion payant chute sans explication visible dans Google Ads.

Les erreurs d'hydration mismatch sont particulièrement vicieuses dans ce contexte : la page semble fonctionner, les métriques de vitesse sont correctes, mais le contenu affiché ne correspond pas à ce que l'utilisateur attend, ce qui détruit le Quality Score implicite de PMax.

La recommandation : auditez systématiquement les pages de destination que PMax sélectionne via le rapport "Landing pages" croisé avec un crawl Screaming Frog en mode JavaScript rendering. Comparez le HTML statique (mode Googlebot) avec le DOM rendu :

# Crawl des landing pages PMax en mode rendu JavaScript avec Screaming Frog CLI
# Exportez d'abord la liste des landing pages PMax depuis Google Ads
screaming-frog-cli \
  --crawl-list pmax_landing_pages.txt \
  --render-js \
  --js-rendering-wait 5000 \
  --export-tabs "Internal:HTML" \
  --output-folder ./pmax-audit/ \
  --headless

# Comparer avec un crawl sans JS pour détecter les divergences
screaming-frog-cli \
  --crawl-list pmax_landing_pages.txt \
  --render-js false \
  --export-tabs "Internal:HTML" \
  --output-folder ./pmax-audit-nojs/ \
  --headless

# Diff rapide sur les titles et H1 entre les deux exports
paste -d'|' \
  <(csvcut -c "Address","Title 1","H1-1" ./pmax-audit/internal_html.csv) \
  <(csvcut -c "Title 1","H1-1" ./pmax-audit-nojs/internal_html.csv) \
| awk -F'|' '$2 != $4 || $3 != $5 {print "DIVERGENCE:", $0}'

Toute divergence entre le crawl JS et le crawl statique signale une page dont le rendu serveur est incomplet. Si PMax envoie du trafic payant vers ces pages, vous payez pour du trafic qui arrive sur un contenu potentiellement cassé. L'article sur SSR vs CSR et leur impact SEO réel détaille les patterns d'implémentation à suivre pour éviter cette situation.

Ce que Google ne montre toujours pas (et les workarounds)

La transparence a ses limites. Plusieurs zones d'ombre persistent malgré cette mise à jour.

Pas de données au niveau de la requête Search par placement

Vous savez que PMax diffuse sur google.com, mais vous ne pouvez pas croiser un terme de recherche spécifique avec le fait qu'il a été diffusé en Search vs Shopping vs un autre format. Le rapport "Search terms" et le rapport "Where ads showed" sont deux vues séparées non joinables dans l'interface.

Workaround partiel : utilisez les segments "Network" dans les rapports de performance PMax via l'API. Le champ segments.ad_network_type distingue SEARCH, SEARCH_PARTNERS, CONTENT (Display), YOUTUBE_SEARCH, YOUTUBE_WATCH, etc. En croisant ce segment avec les métriques de conversion, vous obtenez une vue réseau par réseau, même si le croisement avec les termes de recherche reste impossible.

Pas de breakdown créatif par placement

Vous ne savez pas quel asset (quelle image, quel titre, quelle description) a été diffusé sur quel placement. L'asset report vous donne une performance par asset, le placement report vous donne une performance par domaine, mais la matrice croisée n'existe pas.

C'est une limitation fondamentale pour l'optimisation créative. Si une image performe bien en Display mais mal en Discover, vous n'avez aucun moyen de le savoir — et donc aucun moyen de créer des asset groups spécialisés par canal de manière informée.

Délai de reporting

Les données de placement PMax ne sont pas en temps réel. Comptez 24 à 48h de latence, similaire aux autres rapports Google Ads. Pour les comptes à fort volume qui ont besoin de réactivité (lancements produit, événements saisonniers), ce délai peut coûter cher si un placement toxique capte du budget.

Mise en place d'un monitoring continu des placements PMax

Attendre une revue manuelle hebdomadaire des placements n'est pas viable sur un compte qui dépense plus de 20 000 €/mois en PMax. Il faut automatiser la surveillance.

Alertes automatiques via Google Ads Scripts

Configurez un script qui s'exécute quotidiennement et vous alerte par email lorsqu'un nouveau placement dépasse un seuil de dépense sans conversion :

// Google Ads Script — Alerte quotidienne placements PMax
function dailyPMaxPlacementAlert() {
  const COST_THRESHOLD = 20.0; // Alerte si > 20€ dépensés sans conversion
  const EMAIL = '[email protected]';

  const query = `
    SELECT
      campaign.name,
      campaign_placement_view.placement,
      campaign_placement_view.placement_type,
      metrics.cost_micros,
      metrics.conversions,
      metrics.impressions,
      metrics.clicks
    FROM campaign_placement_view
    WHERE campaign.advertising_channel_type = 'PERFORMANCE_MAX'
      AND segments.date DURING LAST_7_DAYS
      AND metrics.conversions < 1
      AND metrics.cost_micros > ${COST_THRESHOLD * 1000000}
    ORDER BY metrics.cost_micros DESC
    LIMIT 50
  `;

  // Note : en Google Ads Scripts, utilisez AdsApp.report() avec la syntaxe AWQL
  // ou migrez vers l'API REST pour GAQL natif
  const results = AdsApp.search(query);
  let alertBody = 'Placements PMax sans conversion (7 derniers jours) :\n\n';
  let alertCount = 0;

  while (results.hasNext()) {
    const row = results.next();
    const cost = row.metrics.costMicros / 1000000;
    const placement = row.campaignPlacementView.placement;
    const campaign = row.campaign.name;

    alertBody += `${campaign} | ${placement} | ${cost.toFixed(2)}€ | ` +
                 `${row.metrics.impressions} imp | ${row.metrics.clicks} clics | 0 conv\n`;
    alertCount++;
  }

  if (alertCount > 0) {
    alertBody += `\n--- ${alertCount} placements à reviewer ---`;
    MailApp.sendEmail(EMAIL, `[PMax Alert] ${alertCount} placements sans conversion`, alertBody);
  }
}

Ce type de monitoring automatisé est essentiel pour les comptes à fort volume. Côté organique, le même principe s'applique : un outil de monitoring comme SEOGard détecte en moins de 24h les régressions techniques (meta disparues, erreurs de rendu SSR, backlinks perdus) qui peuvent impacter simultanément vos performances payantes et organiques. Quand PMax envoie du trafic vers une page dont le canonical a été accidentellement modifié lors d'un déploiement, la détection rapide évite des jours de budget gaspillé.

Implications stratégiques : vers la fin du "trust the algorithm" aveugle

Cette mise à jour de Google marque un tournant dans la relation entre annonceurs et automatisation. Pendant trois ans, Google a demandé aux annonceurs de faire confiance à l'algorithme PMax sans fournir les données nécessaires pour vérifier cette confiance. La pression réglementaire (le Digital Markets Act européen exige plus de transparence des plateformes publicitaires) et la pression concurrentielle (Microsoft Ads propose depuis longtemps des données de placement granulaires) ont probablement accéléré cette ouverture.

Pour les équipes SEO/SEA intégrées, c'est une opportunité de construire une boucle de feedback bidirectionnelle :

  1. Les données de placement PMax révèlent quels canaux et quels types de contenu convertissent
  2. Ces insights alimentent la stratégie de contenu organique (création de contenus vidéo, optimisation des pages catégorie, etc.)
  3. L'amélioration du contenu organique améliore le Quality Score implicite des pages de destination PMax
  4. PMax performe mieux, ce qui génère plus de données, ce qui alimente le cycle

Les équipes qui traitent encore SEO et SEA en silos passent à côté de cette boucle. Les données sont là — il faut les exploiter.

La transparence des placements PMax est une avancée significative, mais elle ne résout qu'une partie du problème de la boîte noire. Les exclusions au niveau campagne, le croisement créatif/placement, et la latence du reporting restent des limites concrètes. Exploitez les données disponibles via l'API et les scripts automatisés, croisez-les avec vos données organiques Search Console, et construisez le monitoring qui vous permettra de reprendre le contrôle sur la machine.

Articles connexes

Actualités SEO28 mars 2026

Core Update Mars 2026 : analyse technique et plan d'action

Google déploie la March 2026 Core Update. Analyse technique, scénarios d'impact concrets et méthodologie de diagnostic pour les équipes SEO.

Actualités SEO27 mars 2026

Page Speed : transformer un site lent en machine de course

Guide technique avancé pour optimiser la vitesse de chargement : poids, puissance serveur, navigation du critical path. Code, configs et scénarios réels.

Actualités SEO26 mars 2026

Écrire pour l'IA search : playbook technique du contenu machine-readable

Structurez votre contenu pour que les LLMs l'extraient et le citent. Code, schémas, configs et scénarios concrets pour l'AI search.