Brand Page APIs

Enrutamiento de URL

Cuando un usuario navega a la URL de una página de marca, la aplicación extrae el urlSlug de la ruta y lo envía a la API de publicación de anuncios.

Estructura de la URL: <https://{your-domain}/{prefix}/{urlSlug}>

SegmentoFuenteEjemplo
your-domainSu sitiowww.retailer.com
prefixConfigurado durante la incorporación (por ejemplo marcas, páginas)brands
urlSlugExtraído en tiempo de ejecución desde la ruta de URLadidas

Ejemplo

Cuando un usuario visita: <https://www.retailer.com/brands/adidas:>

  1. Su aplicación coincide con la ruta /brands/*.
  2. Extrae adidascomo el urlSlug.
  3. Llama POST /ads/v3/brand-pages en su host de anuncios asignado con "urlSlug": "adidas" y su catalogId.
  4. Renderiza los módulos de contenido devueltos en la página.

Reglas de validación de slug

Las marcas crean slugs siguiendo estas restricciones:

  • 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).
📘

En este momento, la unicidad del slug no tiene en cuenta los intervalos de fechas de las campañas.

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

Almacenamiento en caché

  • No guarde en caché las respuestas de la API de publicación de anuncios. Envíe siempre las solicitudes directamente a la API de Epsilon para garantizar que:
    • Se publica la campaña correcta de la página de marca (las campañas se pueden pausar, actualizar o cambiar).
    • Las URL de seguimiento incluyen identificadores nuevos por solicitud para una atribución precisa.
    • Los recuentos de impresiones siguen siendo precisos y no se ven afectados por respuestas en caché obsoletas.

Consideración de SEO: Los minoristas pueden optar por permitir que los motores de búsqueda indexen las páginas de sus marcas. Indexar el contenido de las páginas de marca puede mejorar la visibilidad en las búsquedas orgánicas, ya que los motores de búsqueda pueden detectar todo el texto de la página.

Configuración de proxy inverso

Por qué necesita un proxy inverso

El problema: Los bloqueadores de anuncios y las herramientas de privacidad suelen bloquear las solicitudes de seguimiento enviadas directamente a los dominios publicitarios.

La solución: Dirigir todas las solicitudes de seguimiento a través de su propio dominio para que aparezcan como tráfico propio.

❌ Blocked: user-browser → [third-party-tracking-domain]  
✅ Works:   user-browser → yoursite.com/[custom-path] → [third-party-tracking-domain]
  • Sustituya [third-party-tracking-domain] por el endpoint real de seguimiento de Epsilon proporcionado durante el proceso de incorporación.
  • Reemplace [custom-path] por una ruta neutral y única (por ejemplo, /media-proxy, /assets-endpoint o cualquier término no publicitario).

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

Configuración

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.

Comportamiento:

  • Aceptar solicitudes bajo /epsilon/
  • Forward to https://[region]-tracking.rmn.dotomi.com/ (see Ad Serving API for [region])
  • Conservar el sufijo de la ruta del archivo
  • Reenviar los encabezados HTTP requeridos
  • Aplicar HTTPS (TLS 1.2 o superior)

Encabezados obligatorios

EncabezadoDescripción
RP-HostSu nombre de host que recibe la solicitud de seguimiento.
X-Forwarded-ForDirección IP real del cliente.
X-Forwarded-Request-PathRuta del prefijo del proxy (por ejemplo, /epsilon).
RefererLa página donde se activó el píxel.

Ejemplo de 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/"

Ejemplo de 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 publicación de anuncios

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.

Endpoint

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

Carga útil de la solicitud

{
  "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).

En entornos de producción:

  • Establezca gdprde acuerdo con sus normas geográficas y legales.
  • Pase la cadena TC en vivo desde su CMP (por ejemplo, a través de _ _tcfapi getTCDatatcString).

Para solicitudes no relacionadas con el RGPD, use "gdpr": 0 y omita consent, o use "".

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.

Definiciones de los campos de solicitud

CampotipoObligatorioDescripción
idCadenaIdentificador de solicitud único (generado por el minorista)
catalogIdCadenaID del catálogo de productos del minorista (proporcionado por Epsilon)
urlSlugCadenaSlug de la URL de la página de marca (por ejemplo, adidas)
site
site.domainCadenaDominio del sitio web del minorista
site.pageCadenaNoURL completa en la que se renderiza la página de marca
site.refCadenaNoURL de referencia (desde donde se dirigió el usuario)
dispositivo
device.uaCadenaCadena del agente de usuario
device.ipCadenaNoDirección IP del cliente
device.languageCadenaNoLenguaje del navegador (por ejemplo, en-US)
device.devicetypeenteroNo1 = móvil, 2 = PC, 4 = teléfono, 5 = tablet
device.osCadenaNoSistema operativo
device.geo.countryCadenaNoCódigo de país ISO 3166-1 alfa-3 (p. ej. EE.UU., GBR)
device.geo.regionCadenaNoEstado o región
device.geo.cityCadenaNoCiudad
device.geo.zipCadenaNoCódigo postal
Usuario
user.sessionIdCadenaNoIdentificador de sesión del minorista (no PII)
user.customerIdCadenaNoIdentificador de cliente minorista (sin información de identificación personal)
user.dtmIdCadenaNoIdentificador de seguimiento
regs
regs.gdprenteroNo0 = GDPR does not apply, 1 = GDPR applies (per OpenRTB-style signaling)
regs.consentCadenaNoIAB TCF v2 consent string (tcString from the CMP). Use only when gdpr is 1 and you have a valid string; otherwise omit or""
❗️

Importante

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

Carga útil de respuesta

{
  "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)
    }
  ]
}

Definiciones de los campos de respuesta

CampotipoDescripción
realizedAdIdCadenaIdentificador publicitario único para esta página de marca. Se utiliza en todas las rutas de plantillas de seguimiento.
brandPageTemplateIdCadenaID de plantilla utilizado para esta página de marca
catalogIdCadenaID del catálogo del minorista (reflejado de la solicitud)
urlSlugCadenaSlug de la URL de la página de marca (obtenida de la solicitud)
themeobjetoAlways 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)
trackersobjetoPage-level tracking container. trackers.impression holds the page impression slot: type: "impression" and params including at least ts: "{TS}" and iabConsentString.
trackingTypesobjetoMap 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.clientobjetoRelative URL paths and query strings for browser (C2S) tracking - prepend your reverse-proxy base URL (BASEURL).
trackingTemplates.serverobjetoAbsolute URL templates on the Epsilon tracking host for S2S.
contentData[]matrizMatriz ordenada de módulos de contenido por renderizar
contentData[].idCadenaID de instancia del módulo
contentData[].brandPageModuleTemplateIdCadenaID de plantilla de módulo
contentData[].contentTypeCadenaTipo de módulo: HERO, TEXT, FILTER_MENU, PRODUCT_GRID, IMAGE, IMAGE_GALLERY, SPLIT_LAYOUT
contentData[].orderenteroOrden de renderizado (ascendente)
contentData[].tagsmatriz de cadenasOptional. 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[].trackersobjetoWhen 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).

PathDescripción
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"
    }
  }
}

paramspor nodo (claves típicas)

ParámetroCuando se utilizaDescripción
modIdLos nodos más interactivosMódulo de contenido o identificador de fila.
rurllink / productClickwhen a redirect is neededURL-encoded destination
tsLa mayoría de los eventosCache-busting timestamp; substitute "{TS}"at fire time.
iabConsentStringAll tracker slotsLiteral TC string, or {TCF} macro to substitute at fire time
productCodeproductClick / productAddToCartIdentificador de producto.
sellerIdproductClick / productAddToCart (marketplace)Identificador del vendedor.
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:

PatternSignificadoSuggested 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

Ejemplos de tipos de módulos comunes

Cuadrícula de productos:

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}"
      }
    }
  }
}

Principal:

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}"
      }
    }
  }
}

Galería de imágenes:

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}"
          }
        }
      }
    }
  ]
}

Texto:

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."
}

Imagen:

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}"
  }
}