Anatomie d'une bid request OpenRTB

La bid request est le cœur du programmatique. C'est le JSON que chaque SSP envoie à chaque DSP, des milliers de fois par seconde. Comprendre sa structure, c'est comprendre comment fonctionne vraiment le RTB.

🔍 Analyser une bid request 📋 Voir la structure

Ce que c'est, et pourquoi ça compte

Dans une enchère programmatique en temps réel (RTB), tout commence par une bid request. Quand un utilisateur charge une page web, le SSP (Supply-Side Platform) de l'éditeur a moins de 100 millisecondes pour assembler un objet JSON décrivant l'inventaire disponible et l'envoyer à des dizaines de DSP simultanément. Chaque DSP lit ce JSON, décide s'il veut enchérir et à quel prix, et répond avec une bid response. Tout ça avant que la page finisse de s'afficher.

Le standard qui définit la structure de ce JSON s'appelle OpenRTB, maintenu par l'IAB Tech Lab. La version 2.5 est encore la plus répandue en production ; la 2.6 commence à s'imposer notamment pour le support natif du supply chain et des nouvelles réglementations.

Pourquoi lire cet article ? Si vous êtes ad ops, trafficker, développeur intégrant un DSP, ou chef de projet adtech, la bid request est le document de référence qui explique pourquoi une campagne ne délivre pas, pourquoi un DSP n'enchérit pas, et comment circule le consentement RGPD dans la chaîne programmatique.

La structure globale

Une bid request OpenRTB 2.x est un objet JSON avec quelques champs racine et des objets imbriqués. La spec distingue les champs requis, recommandés et optionnels. En pratique, les SSP envoient beaucoup plus que le minimum — c'est ce qui permet aux DSP de cibler finement.

Structure de haut niveau — OpenRTB 2.5JSON
"id": "e3d9a3f2-7b1c-4e2a...",  // identifiant unique de cette request
"at": 1,                         // type d'enchère : 1=premier prix, 2=deuxième prix
"tmax": 350,                     // délai max de réponse en ms
"cur": ["EUR"],                  // devises acceptées
"imp": [...],                    // tableau des impressions disponibles
"site": {...},                   // contexte éditeur (OU "app")
"device": {...},                 // équipement de l'utilisateur
"user": {...},                   // données utilisateur + consentement
"regs": {...},                   // cadre réglementaire (RGPD, CCPA, GPP)
"source": {...},                 // origine de l'inventaire + schain
"ext": {...}                     // extensions propriétaires SSP
ObjetObligatoire ?Rôle
imp[]Oui (min. 1)Description de l'emplacement publicitaire à vendre
site OU appOui (un des deux)Contexte éditeur — site web ou application mobile
idOuiIdentifiant unique de la request (pour le rapprochement logs)
deviceRecommandéÉquipement, OS, IP, géolocalisation
userRecommandéIdentité utilisateur, consentement TCF, EIDs
regsRecommandéIndicateurs réglementaires (GDPR, COPPA, US Privacy)
atOptionnelType d'enchère (défaut = 2, second prix)
tmaxOptionnelTimeout en ms (défaut non défini — le DSP applique le sien)

L'objet imp — le cœur de l'enchère

L'objet imp (impression) décrit précisément ce que le SSP vend. Une bid request peut contenir plusieurs impressions (par exemple toutes les zones publicitaires d'une page), mais en pratique la majorité des requests n'en contiennent qu'une.

Objet imp — banner + deal PMPJSON
{
  "id": "1",
  "banner": {
    "format": [
      {"w":300,"h":250},
      {"w":320,"h":50}
    ],
    "pos": 1,    // 1 = above the fold
    "api": [3, 5]  // MRAID-1 et MRAID-2 supportés
  },
  "bidfloor": 1.80,       // CPM plancher en EUR
  "bidfloorcur": "EUR",
  "secure": 1,            // HTTPS obligatoire pour le créatif
  "tagid": "slot_hp_sidebar",
  "pmp": {
    "private_auction": 0, // 0 = open + deals, 1 = deals only
    "deals": [{
      "id": "DEAL-PREMIUM-007",
      "bidfloor": 4.50,     // floor spécifique au deal
      "at": 1,              // premier prix pour ce deal
      "wseat": ["dsp-seat-42"] // acheteur autorisé
    }]
  }
}

Les formats d'impression

L'objet imp ne contient pas un mais un seul sous-objet de format à la fois — banner, video, audio ou native. Les DSP spécialisés vidéo filtrent les requests sans objet video dès la réception, avant même de lire les autres champs.

FormatChamps clésParticularité
bannerformat[], pos, apiPlusieurs tailles possibles dans format
videoprotocols[], minduration, maxduration, placementprotocols liste les standards VAST supportés
audioprotocols[], minduration, maxdurationBasé sur DAAST — peu répandu hors podcast/radio
nativerequest (JSON dans une string)Spec native IAB 1.2 encodée en string JSON

Le bidfloor et les deals PMP

Le bidfloor est le CPM minimum que le SSP accepte. Toute enchère en dessous est automatiquement rejetée. Si bidfloorcur est absent, la devise assumée est USD — source de confusion fréquente quand le DSP enchérit en EUR.

L'objet pmp (Private Marketplace) permet de définir des deals négociés entre un éditeur et un acheteur spécifique. Quand private_auction = 1, seuls les acheteurs listés dans les deals peuvent participer. Quand il vaut 0, les deals coexistent avec l'open auction — un acheteur autorisé peut enchérir sur le deal (floor à 4,50 EUR) ou en open (floor à 1,80 EUR).

Device et User — ciblage et vie privée

Ce sont les deux objets les plus scrutés par les DSP pour prendre leur décision d'achat. Et les plus sensibles du point de vue RGPD.

L'objet device

Il décrit l'équipement qui affiche la publicité. Le champ ifa (Identifier for Advertising) est l'IDFA sur iOS ou le GAID sur Android — c'est l'identifiant publicitaire mobile qui permet le retargeting et la mesure de conversion. Depuis iOS 14.5, sa collecte nécessite un consentement ATT explicite de l'utilisateur.

IP et conformité RGPD L'adresse IP (device.ip) est une donnée personnelle au sens du RGPD. De nombreux SSP la tronquent à 3 octets avant envoi (92.184.xxx.0) ou la hashent. Les DSP qui utilisent l'IP pour l'inférence géographique doivent s'assurer que le traitement est couvert par la consent string TCF.

L'objet user et la consent string TCF

C'est ici que circule le consentement de l'utilisateur. Le champ user.consent contient la consent string TCF 2.x encodée en Base64url — une chaîne qui résume les choix de l'utilisateur sur la bannière de cookies de l'éditeur.

Objet user avec TCF et Extended IDsJSON
{
  "id": "u_8f3a2e1d9c7b",        // ID exchange-specific
  "buyeruid": "dsp_uid_4499xk",  // ID mappé côté DSP (cookie sync)
  "consent": "CPziCYAP...",       // consent string TCF 2.x
  "eids": [
    {
      "source": "uidapi.com",     // UID 2.0 (The Trade Desk)
      "uids": [{ "id": "AgAAAAVacu7...", "atype": 3 }]
    },
    {
      "source": "liveramp.com",   // RampID
      "uids": [{ "id": "XY7mRIqaqBz...", "atype": 3 }]
    }
  ]
}

Les Extended IDs (eids) sont la réponse de l'industrie à la fin des cookies tiers. Ils permettent de transporter des identifiants alternatifs standardisés — UID 2.0, RampID de LiveRamp, ID5, PubCommonID — directement dans la bid request, sans dépendre des cookies.

L'objet regs — le droit dans le JSON

C'est le champ réglementaire. Un DSP qui ne le lit pas correctement risque de traiter des données sans base légale — une exposition juridique majeure en Europe.

Objet regs — GDPR + CCPA + GPPJSON
{
  "gdpr": 1,            // 1 = soumis au RGPD
  "ext": {
    "us_privacy": "1---", // chaîne CCPA (1=applicable, ---=pas d'opt-out)
    "gpp": "DBAA",         // Global Privacy Platform string
    "gpp_sid": [2]         // section GPP applicable (2=CPRA Californie)
  }
}
GDPR = 1 sans consent string = problème Si regs.gdpr = 1 et que user.consent est absent, le DSP ne peut pas déterminer les finalités consenties. La plupart des DSP RGPD-compliant n'enchériront pas dans ce cas, ou enchériront uniquement en contextuel sans utiliser de données utilisateur. C'est une cause fréquente de fill rate bas sur le trafic européen.

Supply Chain — tracer l'origine de l'inventaire

Le schain (Supply Chain Object) est l'une des avancées majeures d'OpenRTB 2.6. Il liste chaque intermédiaire qui a touché l'inventaire entre l'éditeur et le DSP — un peu comme un manifeste de cargo qui trace la route d'une marchandise.

schain — 2 nœuds (SSP intermédiaire + éditeur)JSON
{
  "ver": "1.0",
  "complete": 1,         // 1 = chaîne complète de A à Z
  "nodes": [
    {
      "asi": "exchange-premium.com",  // domaine du SSP
      "sid": "pub-4829",             // publisher ID côté ce SSP
      "rid": "req-e3d9",             // request ID
      "hp": 1                        // 1 = autorisé à vendre cet inventaire
    },
    {
      "asi": "monsiteactu.fr",
      "sid": "site_001",
      "hp": 1
    }
  ]
}

Le champ complete = 1 est crucial : il indique que la chaîne est complète depuis le vendeur direct jusqu'au DSP. Un complete = 0 signifie qu'il peut y avoir des intermédiaires non déclarés — signal d'alarme pour la brand safety et la lutte contre la fraude publicitaire.

Les 6 erreurs les plus fréquentes dans une bid request

ErreurImpactSolution
GDPR=1 sans user.consentDSP n'enchérit pas ou enchérit sans ciblageS'assurer que la CMP transmet la consent string avant la bid request
bidfloor sans bidfloorcurAmbiguïté devise, sous-enchère potentielleToujours spécifier bidfloorcur
tmax trop court (<150ms)Timeouts côté DSP, fill rate bas300-500ms est le range standard pour la plupart des SSP
site ET app présentsComportement indéfini côté DSPUn seul des deux objets selon le contexte
IFA transmis sans LMT=0Risque RGPD / ATTVérifier device.lmt avant d'utiliser l'IFA
schain.complete=0DSP brand-safety bloquent l'inventaireDéclarer tous les intermédiaires ou travailler directement avec l'éditeur

Analyser votre bid request

Collez votre JSON OpenRTB pour visualiser chaque champ annoté, détecter les erreurs et décoder la consent string TCF.

Ouvrir l'outil →

Questions fréquentes

Quelle est la différence entre OpenRTB 2.5 et 2.6 ?

OpenRTB 2.6 intègre nativement le schain object (qui était une extension dans le 2.5), ajoute un meilleur support des nouvelles réglementations de confidentialité (GPP), et améliore les objets dooh pour le programmatique extérieur. La 2.5 reste la version la plus déployée en production.

Comment savoir si ma bid request est conforme RGPD ?

Trois vérifications : regs.gdpr doit valoir 1 pour le trafic européen, user.consent doit contenir une consent string TCF 2.x valide, et la consent string doit inclure les finalités nécessaires aux traitements que vous effectuez. Utilisez le TCF Decoder Flownect pour vérifier les finalités consenties.

Qu'est-ce que le at=1 (premier prix) change pour les DSP ?

En first-price auction, le gagnant paye exactement son enchère — pas le deuxième prix + 0,01. Les DSP doivent adapter leur stratégie de bidding : enchérir à la vraie valeur perçue plutôt qu'au-dessus pour « gagner facilement ». Le passage au first price a généralement réduit les CPM moyens car les DSP ont calibré leurs enchères à la baisse.

Que signifie le champ « ext » dans une bid request ?

Le champ ext est une zone d'extension propriétaire — chaque SSP peut y ajouter ses propres champs non définis dans la spec standard. On y trouve typiquement la version de Prebid utilisée, des métadonnées de ciblage supplémentaires, ou des indicateurs de qualité de trafic. Ces champs ne sont pas standardisés et varient d'un SSP à l'autre.