Brand Page APIs

Routage d'URL

Lorsqu’un utilisateur navigue vers une URL de page de marque, votre application extrait urlSlug du chemin et l’envoie à l’API de diffusion d'annonces.

Structure de l’URL : <https://{your-domain}/{prefix}/{urlSlug}>

SegmentSourceExemple
your-domainVotre sitewww.retailer.com
prefixConfiguré lors de l’intégration (par exemple, marques, pages)brands
urlSlugExtrait du chemin de l'URL au moment de l'exécutionadidas

Exemple

Lorsqu’un utilisateur visite : <https://www.retailer.com/brands/adidas:>

  1. Votre application correspond à la route /brands/*.
  2. Extrait adidasen tant que slug d'URL.
  3. Appelle POST /ads/v3/brand-pages sur votre hôte de publicités attribué avec "urlSlug": "adidas" et votre catalogId.
  4. Affiche les modules de contenu retournés sur la page.

Règles de validation du slug

Les marques créent des slugs en fonction des contraintes suivantes :

  • Characters: Lowercase letters (a–z), numbers (0–9), hyphens (-), and underscores (_).
  • Length: Minimum 3 characters, maximum 100 characters.
  • Uniqueness: Must be unique within the retailer’s catalog (catalogId).
📘

Pour le moment, l'unicité des slugs ne prend pas en compte les plages de dates des campagnes.

  • Immutability: Cannot be changed after the brand page campaign is live.
  • Format: No leading or trailing hyphens (for example, -adidasor adidas- are not allowed).

Mise en cache

  • Ne mettez pas en cache les réponses de l'API de diffusion d'annonces. Envoyez toujours les requêtes directement à l’API Epsilon pour garantir :
    • La campagne de la page de marque correcte est diffusée (les campagnes peuvent être interrompues, mises à jour ou permutées).
    • Les URL de suivi incluent des identifiants uniques par requête, pour une attribution précise.
    • Les nombres d’impressions restent exacts et ne sont pas affectés par des réponses de mise en cache obsolètes.

Considérations relatives au référencement : les détaillants peuvent choisir d'autoriser l'indexation des pages de marque par les moteurs de recherche. L'indexation du contenu des pages de marque peut améliorer la visibilité dans les moteurs de recherche organiques, car tout le texte de la page peut être détecté par les moteurs de recherche.

Configuration du proxy inversé

Pourquoi avez-vous besoin d’un proxy inversé ?

Problème : les bloqueurs de publicité et les outils de protection de la vie privée bloquent souvent les demandes de suivi envoyées directement aux domaines publicitaires.

Solution : acheminez toutes les demandes de suivi via votre propre domaine afin qu'elles apparaissent comme du trafic propriétaire.

❌ Blocked: user-browser → [third-party-tracking-domain]  
✅ Works:   user-browser → yoursite.com/[custom-path] → [third-party-tracking-domain]
  • Remplacez [third-party-tracking-domain] par le point de terminaison de suivi Epsilon fourni lors de l'intégration.
  • Remplacez [custom-path] par un chemin neutre et unique (par exemple, /media-proxy, /assets-endpoint ou tout autre terme non publicitaire).

A reverse proxy is required for C2S (browser) tracking. It does not apply to S2S calls, which must be sent directly to the Epsilon tracking host (see Tracking – Server-to-Server (S2S)).

Configuration

Your site must host a reverse proxy under a path such as https://www.retailer.com/{proxyPath}/. Browser (C2S) tracking requests to your domain on that path are forwarded to your regional tracking host (see Ad Serving API). Server-to-server tracking must not use this proxy.

Comportement :

  • Accepter les demandes sous /epsilon/
  • Forward to https://[region]-tracking.rmn.dotomi.com/ (see Ad Serving API for [region])
  • Conserver le suffixe du chemin d'accès au fichier
  • Transmettre les en-têtes HTTP requis
  • Appliquer HTTPS (TLS 1.2+)

En-têtes obligatoires

En-têteDescription
RP-HostVotre nom d'hôte recevant la demande de suivi.
X-Forwarded-ForAdresse IP réelle du client.
X-Forwarded-Request-PathChemin du préfixe proxy (par exemple /epsilon).
RefererLa page où le pixel a été déclenché.

Exemple Apache

LoadModule ssl_module modules/mod_ssl.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
SSLProxyEngine on
RequestHeader add "X-Forwarded-Request-Path" "/epsilon"
RequestHeader add "RP-Host" "%{HTTP_HOST}s"
RequestHeader add "Referer" "%{HTTP_REFERER}s"
ProxyPass "/epsilon" "https://[region]-tracking.rmn.dotomi.com"
ProxyPassReverse "/epsilon" "https://[region]-tracking.rmn.dotomi.com/"

Exemple NGINX

server {
    server_name www.retailer.com;
    location /epsilon/ {
        proxy_ssl_server_name on;
        rewrite ^/epsilon/(.*) /$1 break;
        proxy_pass https://[region]-tracking.rmn.dotomi.com;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $server_name;
        proxy_set_header RP-Host $host;
        proxy_set_header X-Forwarded-Request-Path "/epsilon";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Referer $http_referer;
    }
}

API de diffusion d'annonces

Epsilon serves brand pages from RMN hosts on *.rmn.dotomi.com. Substitute [region] with the segment Epsilon assigns for your deployment.

The ads API uses https://[region]-ads.rmn.dotomi.com; while tracking endpoints (impression pixels, click redirects, and S2S notification URLs) uses https://[region]-tracking.rmn.dotomi.com with the same [region] value.

In some setups, the base hostnames ads.rmn.dotomi.com and tracking.rmn.dotomi.com may be used. Epsilon will confirm the appropriate hostnames for your environment.

Point de terminaison

POST https://[region]-ads.rmn.dotomi.com/ads/v3/brand-pages
Content-Type: application/json
Authorization: Basic <existing_api_key>

Charge utile de la requête

{
  "id": "req-adidas-12345",
  "catalogId": "test-catalog-adidas",
  "urlSlug": "adidas",
  "site": {
    "domain": "www.retailer.com",
    "page": "https://www.retailer.com/brand/adidas",
    "ref": "https://www.retailer.com/search?q=shoes"
  },
  "device": {
    "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ...",
    "ip": "192.168.1.100",
    "language": "en-US",
    "devicetype": 2,
    "os": "macOS",
    "geo": {
      "country": "USA",
      "region": "CA",
      "city": "San Francisco",
      "zip": "94105"
    }
  },
  "user": {
    "sessionId": "sess-abc123xyz",
    "customerId": "cust-789012",
    "dtmId": "dtm-456def"
  },
  "regs": {
    "gdpr": 1,
    "consent": "COwJqZAOwJqZAOAAAAENAXCAAAAAAAAAAAAAABpoAIAAAEpgAIAAAg1AAAICAIAAAEA"
  }
}

The regs values above illustrate the GDPR-applicable traffic:
gdpr is 1, and consentis a synthetic IAB TCF v2 consent string (correct shape and charset only).

Environnements de production :

  • Définissez gdpr à partir de votre géolocalisation et de vos réglementations.
  • Transmettez la chaîne TC en direct de votre CMP (par exemple, via _ _tcfapi getTCDatatcString).

Pour les demandes ne relevant pas du RGPD, utilisez "gdpr": 0 et omettez consent, ou utilisez ""

iabConsentString on tracking events: Every populated tracker slot (trackers.impression, trackers.click, trackers.addToCart) includes params.iabConsentString. When you provide regs.consent on the request, this value is the literal TC string.

When you omitted regs.consent, this value is the {TCF} macro placeholder - substitute the current TCF v2 string from your CMP (for example via __tcfapi getTCDatatcString) at fire time before sending any tracking request.

Définitions des champs de requête

ChamptypeObligatoireDescription
idChaîneOuiIdentifiant de demande unique (généré par le détaillant)
catalogIdChaîneOuiID du catalogue de produits du détaillant (fourni par Epsilon)
urlSlugChaîneOuiURL de la page de marque (par exemple, adidas)
site
site.domainChaîneOuiDomaine du site Web du détaillant
site.pageChaîneNonURL complète où la page de marque est affichée
site.refChaîneNonURL de référence (d'où l'utilisateur a navigué)
appareil
device.uaChaîneOuiChaîne d'identification de l'agent
device.ipChaîneNonAdresse IP du client
device.languageChaîneNonLangue du navigateur (par exemple, en-US)
device.devicetypenombre entierNon1=mobile, 2=PC, 4=téléphone, 5=tablette
device.osChaîneNonSystème d'exploitation
device.geo.countryChaîneNonCode pays ISO 3166-1 alpha-3 (par exemple, USA, GBR)
device.geo.regionChaîneNonÉtat ou région
device.geo.cityChaîneNonVille
device.geo.zipChaîneNonCode postal
Utilisateur
user.sessionIdChaîneNonIdentifiant de session du détaillant (non-PII)
user.customerIdChaîneNonIdentifiant client du détaillant (non-PII)
user.dtmIdChaîneNonIdentifiant de suivi
regs
regs.gdprnombre entierNon0 = GDPR does not apply, 1 = GDPR applies (per OpenRTB-style signaling)
regs.consentChaîneNonIAB TCF v2 consent string (tcString from the CMP). Use only when gdpr is 1 and you have a valid string; otherwise omit or""
❗️

Important

The JSON below is a representative and fairly complete example. Live responses are often sparser for contentData modules. Do not generate fixed structures that assume every key shown here is always present for every contentType or brand page.
The theme is different: on a successful response, it is always present and uses the nested structure described in the Theme Object section (colorsand buttons fully populated - required hex6 strings for every path; no nulls inside theme).

Charge utile de la réponse

{
  "realizedAdId": "brandpage_djogXfHSYGZOZnnkzEKunWvdNYEKABIAGgwIwIPjzAYQ3byasAE=",
  "brandPageTemplateId": "6e9690ef-81d1-4fad-b2ce-749e22cceb10",
  "catalogId": "test-catalog-adidas",
  "urlSlug": "adidas",
  "theme": {
    "colors": {
      "background": "#F5F5F5",
      "text": {
        "heading": "#1a1a1a",
        "subheading": "#333333",
        "body": "#5f6368",
        "caption": "#9aa0a6",
        "link": "#1a73e8",
        "tagline": "#5f6368",
        "lines": "#e0e0e0"
      }
    },
    "buttons": {
      "primary": {
        "background": "#ff6600",
        "text": "#FFFFFF"
      },
      "secondary": {
        "background": "#FFFFFF",
        "text": "#ff6600"
      }
    }
  },
  "trackers": {
    "impression": {
      "type": "impression",
      "params": { "ts": "{TS}", "iabConsentString": "{TCF}" }
    }
  },
  "trackingTypes": {
    "impression":      ["client.impressionPixelUrls", "server.impressionEvent"],
    "productClick":    ["client.clickRedirect", "client.clickEvent", "server.clickEvent"],
    "productAddToCart": ["client.addToCartEvent", "server.addToCartEvent"],
    "link":            ["client.clickRedirect", "client.clickEvent", "server.clickEvent"],
    "interaction":     ["client.clickEvent", "server.clickEvent"]
  },
  "trackingTemplates": {
    "client": {
      "clickRedirect":       "/tracking/v3/click/redirect/brandpage_djog...?catalogId=test-catalog-adidas&...",
      "clickEvent":          "/tracking/v3/event/click/brandpage_djog...?catalogId=test-catalog-adidas&...",
      "addToCartEvent":      "/tracking/v3/event/add-to-cart/brandpage_djog...?catalogId=test-catalog-adidas&...",
      "impressionPixelUrls": [
        "/tracking/v3/impression/pixel/brandpage_djog...?catalogId=test-catalog-adidas&..."
      ]
    },
    "server": {
      "clickEvent":          "https://[region]-tracking.rmn.dotomi.com/tracking/v3/event/click/brandpage_djog...?...",
      "addToCartEvent":      "https://[region]-tracking.rmn.dotomi.com/tracking/v3/event/add-to-cart/brandpage_djog...?...",
      "impressionEvent":     "https://[region]-tracking.rmn.dotomi.com/tracking/v3/event/impression/brandpage_djog...?..."
    }
  },
  "contentData": [
    {
      "id": "hero-1",
      "brandPageModuleTemplateId": "hero-template-1",
      "contentType": "HERO",
      "order": 1,
      "tags": ["header"],
      "mediaUrl": "https://example.com/images/adidas-hero.jpg",
      "headline": "Impossible Is Nothing",
      "subheadline": "Spring Collection",
      "ctaText": "Explore",
      "ctaLink": "https://example.com/adidas/explore",
      "trackers": {
        "click": {
          "type": "link",
          "params": {
            "modId": "hero-1",
            "rurl": "https%3A%2F%2Fexample.com%2Fadidas%2Fexplore",
            "ts": "{TS}",
            "iabConsentString": "{TCF}"
          }
        }
      }
    },
    {
      "id": "text-1",
      "brandPageModuleTemplateId": "text-template-1",
      "contentType": "TEXT",
      "order": 2,
      "text": "Discover the latest Adidas collection featuring innovative designs and sustainable materials."
      // (No trackers for TEXT module, as it has no interactive elements)
    }
  ]
}

Définitions des champs de réponse

ChamptypeDescription
realizedAdIdChaîneIdentifiant publicitaire unique pour cette page de marque. Utilisé dans tous les chemins de modèle de suivi.
brandPageTemplateIdChaîneID du modèle utilisé pour cette page de marque
catalogIdChaîneIdentifiant du catalogue du détaillant (repris dans la requête)
urlSlugChaîneURL slug de la page de marque (repris dans la requête)
themeobjetAlways present on success. Page-level styling from the brand: nested colors (background + text roles) and buttons(primary/ secondary, each with backgroundand text). See Theme Object section.
The response body is returned as serialized by the ad server (no intermediate reshaping of theme)
trackersobjetPage-level tracking container. trackers.impression holds the page impression slot: type: "impression" and params including at least ts: "{TS}" and iabConsentString.
trackingTypesobjetMap of tracking type to applicable template keys. Types: impression, productClick, productAddToCart, link, interaction. Each value is an array of client.*/ server.* keys from trackingTemplates. (see How to Compose a Tracking URL).
trackingTemplates.clientobjetRelative URL paths and query strings for browser (C2S) tracking - prepend your reverse-proxy base URL (BASEURL).
trackingTemplates.serverobjetAbsolute URL templates on the Epsilon tracking host for S2S.
contentData[]tableauTableau ordonné de modules de contenu à afficher
contentData[].idChaîneIdentifiant d'instance de module
contentData[].brandPageModuleTemplateIdChaîneID du modèle de module
contentData[].contentTypeChaîneType de module : HERO, TEXT, FILTER_MENU, PRODUCT_GRID, IMAGE, IMAGE_GALLERY, SPLIT_LAYOUT
contentData[].ordernombre entierOrdre de rendu (croissant)
contentData[].tagstableau de chaînes de caractèresOptional. Module tags set by the retailer in the template. Omitted entirely when no tags are set - treat missing as "no tags". Also present on nested modules within SPLIT_LAYOUT.
contentData[].trackersobjetWhen present, per-node tracking container. trackers.click for link/interaction/product click events; trackers.addToCart for product add-to-cart (includes {QTY} and {CONVERSION_VALUE} macros). May be omitted when there is nothing to track.

Theme Object

Every successful Brand Page API response includes a theme object: page-level colors and button styles configured for the brand. Apply these values when rendering (for example, map them to CSS custom properties or your design tokens). The JSON is produced by the ad server and delivered as returned - there is no separate step that rewrites the theme.

Color format: Theme color values follow the platform contract from upstream (campaign/configuration): each value is a # followed by six hexadecimal digits (hex6), for example, #ff6600. Do not expect other formats (short hex3, eight-digit hex, rgb(), hsl(), or named colors). The ad server does not revalidate color format at serve time; upstream supplies hex6 for every theme field.

Structure and semantics

  • theme contains colors and buttons - both are required whenever theme is present.
  • colors.background - page or canvas background (required hex6).
  • colors.text - seven required roles: heading, subheading, body, caption, link, tagline, lines (lines/dividers). Each value is a hex6 string.
  • buttons.primary and buttons.secondary - each requires background and text (button fill and label colors), each a hex6 string.
  • Every path in the field reference table below is required. There are no optional color slots and no null values inside theme. (Sparse or omitted fields apply elsewhere, for example in contentData modules.)
  • The theme is page-level -all modules on the Brand Page share the same theme.

Field reference

All paths in this table are required (non-null hex6 strings).

PathDescription
theme.colors.backgroundPage/canvas background
theme.colors.text.headingHeading text
theme.colors.text.subheadingSubheading text
theme.colors.text.bodyBody/paragraph text
theme.colors.text.captionCaption/secondary text
theme.colors.text.linkLink text
theme.colors.text.taglineTagline text
theme.colors.text.linesLines and dividers
theme.buttons.primary.backgroundPrimary CTA button fill
theme.buttons.primary.textPrimary CTA button label
theme.buttons.secondary.backgroundSecondary button fill
theme.buttons.secondary.textSecondary button label

Example - (themeobject only):

"theme": {
  "colors": {
    "background": "#F5F5F5",
    "text": {
      "heading": "#1a1a1a",
      "subheading": "#333333",
      "body": "#5f6368",
      "caption": "#9aa0a6",
      "link": "#1a73e8",
      "tagline": "#5f6368",
      "lines": "#e0e0e0"
    }
  },
  "buttons": {
    "primary": {
      "background": "#ff6600",
      "text": "#FFFFFF"
    },
    "secondary": {
      "background": "#FFFFFF",
      "text": "#ff6600"
    }
  }
}

Par nœud params(clés typiques)

ParamètresLorsqu'il est utiliséDescription
modIdLes nœuds les plus interactifsModule de contenu ou identifiant de ligne.
rurllink / productClickwhen a redirect is neededURL-encoded destination
tsLa plupart des événementsCache-busting timestamp; substitute "{TS}"at fire time.
iabConsentStringAll tracker slotsLiteral TC string, or {TCF} macro to substitute at fire time
productCodeproductClick / productAddToCartIdentifiant du produit.
sellerIdproductClick / productAddToCart (marketplace)Identifiant du vendeur.
qtyproductAddToCartAbsolute quantity of this SKU in the cart at the time the event fires (not a delta). Substitute {QTY} macro at fire time
conValproductAddToCartAbsolute monetary value of those items: quantity × unit price, minus any applied discounts. Substitute {CONVERSION_VALUE} macro at fire time

Template-dependent fields in contentData

Aside from core discriminators on each module (id, brandPageModuleTemplateId, contentType, order), property presence is not uniform across Brand Pages. Prefer feature detection - check each property before use - rather than treating every field in examples as mandatory.

The API may represent "no value" in several ways:

PatternSignificationSuggested handling
Key omittedProperty absent from the JSON objectTreat as absent; use optional chaining/defaults
Explicit nullProperty present with null valueSame as omitted, unless your serializer distinguishes them
Empty string"" for text or URL-like fieldsUsually hide or skip rendering that slice of UI

Exemples de types de modules courants

Grille de produits :

Each product row includes a product object (catalogId, productCode, sellerId), an order value, and trackers when the row is trackable. Product rows provide both a click slot (type: "productClick") and an addToCartslot (type: "productAddToCart") when the SKU is attributable.


{
  "product": {
    "catalogId": "550e8400-e29b-41d4-a716-446655440001",
    "productCode": "9221200653341",
    "sellerId": "2ae0aab9-44ce-40a0-b2b9-ae61681ad224"
  },
  "order": 1,
  "trackers": {
    "click": {
      "type": "productClick",
      "params": {
        "modId": "grid-1",
        "productCode": "9221200653341",
        "sellerId": "2ae0aab9-44ce-40a0-b2b9-ae61681ad224",
        "rurl": "{RURL}",
        "ts": "{TS}",
        "iabConsentString": "{TCF}"
      }
    },
    "addToCart": {
      "type": "productAddToCart",
      "params": {
        "modId": "grid-1",
        "productCode": "9221200653341",
        "sellerId": "2ae0aab9-44ce-40a0-b2b9-ae61681ad224",
        "rurl": "{RURL}",
        "ts": "{TS}",
        "qty": "{QTY}",
        "conVal": "{CONVERSION_VALUE}",
        "iabConsentString": "{TCF}"
      }
    }
  }
}

Hero :

Headline, subheadline, CTA text and link, image, overlay, and trackers.click for the CTA when present.


{
  "contentType": "HERO",
  "tags": [
    "header"
  ],
  "mediaUrl": "https://example.com/images/adidas-hero.jpg",
  "headline": "Impossible Is Nothing",
  "subheadline": "Spring Collection",
  "ctaText": "Explore",
  "ctaLink": "https://example.com/adidas/explore",
  "trackers": {
    "click": {
      "type": "link",
      "params": {
        "modId": "hero-1",
        "rurl": "https%3A%2F%2Fexample.com%2Fadidas%2Fexplore",
        "ts": "{TS}",
        "iabConsentString": "{TCF}"
      }
    }
  }
}

Galerie d'images :

An array of images, each with a URL, alt text, and caption. trackers.click for an image only when that image links out.

{
  "contentType": "IMAGE_GALLERY",
  "galleryImages": [
    {
      "url": "https://example.com/images/recipe-spaghetti-bolognese.jpg",
      "alt": "Spaghetti Bolognese",
      "caption": "Spaghetti Bolognese",
      "trackers": {
        "click": {
          "type": "link",
          "params": {
            "modId": "gallery-1",
            "rurl": "https%3A%2F%2Fexample.com%2Frecipes%2Fspaghetti",
            "ts": "{TS}",
            "iabConsentString": "{TCF}"
          }
        }
      }
    }
  ]
}

Texte :

Headline and body text, with no trackersunless a link is present on a line.

{
  "contentType": "TEXT",
  "text": "Explore our newest arrivals designed for comfort, style, and performance."
}

Image :

Includes an image URL, caption, alt text, optional link and trackers.click details when the image is clickable

{
  "contentType": "IMAGE",
  "imageUrl": "https://example.com/images/model.jpg",
  "caption": "New arrivals now available",
  "alt": "Model wearing summer collection",
  "trackers": { "click": { "type": "link", "params": { "modId": "image-1", "rurl": "https%3A%2F%2Fexample.com%2Fnew-arrivals", "ts": "{TS}", "iabConsentString": "{TCF}"
  }
}