Skip to main content

Retail Media Network Integration

This guide consolidates how to onboard a Retail Media Network (RMN) as a publisher or network in Collective Audience: inventory setup, passing page context for better campaign matching, and using dynamic carousels with your product catalog.


What is a Retail Media Network (RMN) in Collective Audience?#

In our model, an RMN is:

  • Inventory owner: you operate one or more sites or apps (e.g. retailer site, marketplace) where ads or sponsored content can be displayed.
  • Context provider: you have first-party signals (search query, category, product, basket) that improve campaign matchingβ€”i.e. which creatives or product recommendations we show.
  • Revenue: you monetize via sponsored content and/or product carousels. We match campaigns to context and return assets (creatives) or items (catalog products) to render.

Terminology:

TermMeaning
InventoryAd space (placements) on your pages.
Placement / slotA specific location (e.g. below search, sidebar) where a widget appears.
KeywordsStrings sent with the page request to improve targeting (e.g. category, brand).
ContextPage-type and metadata (SRP, PLP, PDP, search query, category, product_id, etc.).
Campaign matchingOur logic that selects which campaign/creative to serve based on context and keywords.
AssetsCreatives (images, videos, links) returned by the content server.
ItemsCatalog products returned for dynamic carousels (e.g. product cards).
CatalogueProduct feed you provide; we host it and filter/sort for carousels.

Monetization works at a high level: when a user visits a page, we receive context and keywords, run campaign matching, and return the most relevant ad or product set. You display it in your placement; revenue is attributed to your account (or network partner).


Integration paths (choose one)#

Pick Path A if the RMN is a single site/app (one account). Pick Path B if the RMN aggregates multiple sites or apps and needs reporting per property.

CriteriaPath A: Standard SDKPath B: Network SDK
ModelOne site = one publisher accountOne network account, multiple sites/placements
Use whenSingle retailer site or appMultiple storefronts, white-labels, or distinct placements
Init parameteraccount: "YOUR_ACCOUNT_ID"network: "YOUR_NETWORK_ID", optional networkPartnerID, optional networkPublisherID
ReportingPer accountPer account; per-site possible via networkPartnerID

Step-by-step: Install and initialize#

Step 1: Install the script#

Use the same script for both paths; only the init config changes.

Path A (publisher):

<script>
window.beOpAsyncInit = function () {
BeOpSDK.init({
account: "YOUR_ACCOUNT_ID",
});
BeOpSDK.watch();
};
</script>
<script async src="https://widget.collectiveaudience.co/sdk.js"></script>

Path B (network):

<script>
window.beOpAsyncInit = function () {
BeOpSDK.init({
network: "YOUR_NETWORK_ID",
networkPartnerID: "OPTIONAL_SITE_OR_PLACEMENT_ID",
// networkPublisherID: "OPTIONAL_PUBLISHER_ID", // per-slot override if needed
});
BeOpSDK.watch();
};
</script>
<script async src="https://widget.collectiveaudience.co/sdk.js"></script>

Replace YOUR_ACCOUNT_ID / YOUR_NETWORK_ID with the IDs provided by Collective Audience. Use networkPartnerID in Path B for per-site or per-placement reporting; networkPublisherID is optional for per-slot publisher override (see Network SDK).

Step 2: Create placements (slots)#

Declare where widgets appear using a named slot so we can track and fill consistently:

<div class="BeOpWidget" data-name="below-search"></div>
<div class="BeOpWidget" data-name="sidebar-plp"></div>
<div class="BeOpWidget" data-name="pdp-recommendations"></div>

Slots can accept both editorial and sponsored content by default. To allow only your own editorial content in a slot, use data-my-content="1". See SDK – Declaring slots.

Step 3: Verify integration#

  1. Diagnostics: Use the Collective Audience Diagnostics bookmarklet on your page. Green checkmarks mean the SDK and slots are detected.
  2. Console: Ensure no script errors; the SDK loads from https://widget.collectiveaudience.co/sdk.js.
  3. Network: In DevTools, check requests to the Collective Audience content server when the page loads or when context is updated (e.g. after navigation in an SPA).
info

If you use Path B and Prebid, you can also use the BeOp Prebid adapter with networkId and networkPartnerId for header bidding.


Passing context to maximize performance#

The more accurate the page context and keywords you send, the better our campaign matching and the more relevant the ads or product carousels.

How we use context and keywords#

  • Keywords: Short strings (e.g. category, brand, product type) used for targeting. We use them in campaign rules and for filtering dynamic carousels (e.g. show only β€œhair” or β€œbeauty”).
  • Page context: Structured metadata (page type, search query, category, product_id, etc.) that we use together with keywords for matching and filtering.

Our SDK reads keywords from a global variable set before the SDK initializes. You can also override or extend this with a structured context object if your integration supports it (see placeholder below and Identify pages – Page keywords).

Setting keywords (all RMN pages)#

Set an array of strings before the SDK runs. The SDK reads window.beOpKeywords when it builds the serve request (and falls back to <meta name="keywords"> if unset). See Identify pages – Page keywords.

// Before SDK init (e.g. in <head> or first script)
window.beOpKeywords = ["beauty", "skincare", "brand-x"];

Keywords are sent in every content request as kwds and used for campaign matching and broaden diffusion.

Context examples by page type (keywords only)#

The SDK currently accepts keywords only (array of strings). Use the examples below to set window.beOpKeywords for each page type. Richer structured context (e.g. pageType, productId) may be supported in a future API; for now, encode context as keyword tokens.

1) Search results page (SRP)

// User searched "shampoo for dry hair", category filter: Hair
window.beOpKeywords = ["srp", "hair", "shampoo", "dry-hair"];

2) Product listing page (PLP)

// Category: Beauty > Skincare; brand facets visible
window.beOpKeywords = ["plp", "beauty", "skincare", "moisturizer", "brand-a"];

3) Product detail page (PDP)

// Single product: brand, category, product type (no PII; use buckets for price)
window.beOpKeywords = ["pdp", "beauty", "skincare", "brand-a", "serum"];
caution

Do not send PII (emails, names, exact prices, etc.). Use category/brand/product-type tokens only. See Data sharing & privacy.

Updating context on navigation (SPA)#

On single-page apps, update keywords whenever the page context changes, then call BeOpSDK.watch() so the SDK refetches content for the new context.

function onRouteChange(keywords) {
window.beOpKeywords = keywords; // array of strings
if (window.BeOpSDK && typeof BeOpSDK.watch === "function") {
BeOpSDK.watch();
}
}
// Example: after router navigates to a PDP
onRouteChange(["pdp", "beauty", "skincare", "brand-a"]);
note

The SDK uses the page URL (or canonical meta / beop:id) to identify the page. For SPAs, ensure the URL or beop:id reflects the current view. See Identify pages.


Contextual ad delivery: campaign matching β†’ assets/items#

Flow in short:

  1. Page load or context update β†’ Your site sets keywords (and optional context).
  2. Request β†’ SDK sends a request to our content server with page URL, slot names, keywords, and any context we support.
  3. Matching β†’ We select campaigns (and optionally catalog items) that match context and targeting rules.
  4. Response β†’ We return assets (creatives: image, video, link) and/or items (catalog products for carousels).
  5. Render β†’ The SDK (or your code) renders the creative or dynamic carousel in the slot.

Assets = creatives (banners, native cards, video). Items = rows from your product catalog (e.g. for a β€œRecommended for you” or β€œSimilar products” carousel).

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Your page │────▢│ SDK request │────▢│ Campaign │────▢│ Response β”‚
β”‚ + context β”‚ β”‚ + keywords β”‚ β”‚ matching + β”‚ β”‚ assets / β”‚
β”‚ + keywords β”‚ β”‚ + slot names β”‚ β”‚ catalog filter β”‚ β”‚ items β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Render in β”‚
β”‚ BeOpWidget β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dynamic Carousel and product catalog (RMN use cases)#

RMNs often show product carousels (e.g. β€œMore like this”, β€œHair products”, β€œBeauty deals”). Collective Audience hosts your catalog and can filter items by the same keywords/context you send with the page.

Catalog hosting#

  • You do not host the live catalog on your side for our carousels. You provide a feed (CSV/XML); we import and store it. See Import your catalog.
  • We use that catalog to fill dynamic carousels and filter by category or other attributes.

Two ways to drive carousel content#

  1. Filtered by page context (automatic)
    We use the keywords (and context) of the current page to filter the catalog. Example: on a β€œHair” page you send keywords: ["hair", "shampoo"]; the carousel shows only items that match (e.g. category=hair or relevant tags).

  2. Search refinement (user search inside carousel)
    The carousel can show a search box. The user types (e.g. β€œdry hair”); we refine the visible items using that query. Configure this in the Dynamic carousel (Search section) in the Audience Desk.

Examples#

  • β€œHair products” page β†’ Set window.beOpKeywords = ["hair", "shampoo", "conditioner"]. Place a dynamic carousel slot; we filter the catalog by those keywords (e.g. category=hair).
  • β€œBeauty” category page β†’ Set window.beOpKeywords = ["beauty", "skincare", "makeup"]. Carousel shows beauty items only.

Carousel integration (concept)#

Slots are the same (BeOpWidget). The creative configured in our back office for that slot can be a dynamic carousel tied to your catalog. No extra client-side API is required beyond passing keywords; filtering is done server-side. For configuration (choices, search, geo, exits), see Create dynamic carousels and Import your catalog.

Filtered mode (auto by page context):
Keywords set on the page are used automatically; ensure the catalog has matching columns (e.g. categories, brand) and that your keywords align with those values.

Search refinement mode:
Enable the search option in the dynamic carousel in the Desk. Users can type in the carousel to narrow results; we search in the columns configured for that creative.

info

Catalog columns (e.g. categories, brand, short_text) are defined at import. Use consistent values in your feed and in the keywords you send so filtering works as expected.


Data sharing and privacy#

  • We expect: Page context and keywords only (no PII). Examples: page type, category, product_id/SKU, brand, price range bucket, search query.
  • We do not want: PII such as emails, names, precise location, or exact basket value. Do not send those in keywords or context.
  • Consent: If your site uses a CMP, add Collective Audience to your TCF vendor list (ID 666). We can run in a consentless mode with limited features. See Consent management.

Go-live checklist#

  • Integration path chosen (Standard SDK vs Network SDK) and init (account or network + networkPartnerID) correct.
  • Placements created and named (data-name) on SRP, PLP, PDP (and others as needed).
  • Context coverage: Keywords (and optional context) set for SRP, PLP, PDP; updated on SPA route change.
  • Catalog imported and columns aligned with keywords/categories you send. See Import your catalog.
  • QA: Test at least one SRP, one PLP, one PDP; verify ads or carousel fill when campaigns/items match.
  • Latency: First request within your acceptable budget; use diagnostics and network tab to confirm no blocking or repeated failures.
  • Monitoring: Check for script errors, failed requests, or empty slots in your usual monitoring/logging.
  • Fallback: Decide what to show when there is no match (empty slot or house creative). We do not force a default; your page can handle empty state.

Troubleshooting#

IssueWhat to check
No ads returnedCorrect account/network ID; slot names present; keywords/context sent; campaigns live and targeting matching your context; diagnostics and network tab for 4xx/5xx or missing request.
Keywords not taken into accountwindow.beOpKeywords set before SDK init (or before BeOpSDK.watch() on SPA); value is an array of strings; no typos in targeting rules.
Carousel emptyCatalog imported and linked to the creative; keywords overlap catalog categories/brand; no filter too narrow (try broader keywords for testing).
SPA navigation not updating contextCall BeOpSDK.watch() after updating beOpKeywords (and context if used); URL or beop:id updated so we don’t serve cached content for the previous page.
CORS or blocked requestsScript loaded from https://widget.collectiveaudience.co/sdk.js; no ad-blockers or CSP blocking our domain in testing.

FAQ (RMN-specific)#

Are you like a DSP?
We do authorize users to buy publishers' inventory, but the placement owner decides: they can open a placement to external demand and incremental revenues, or keep that inventory for their own use only. We match campaigns (and product catalog) to your inventory using context and keywords; the control over who can monetize each slot stays with the publisher or network.

Do we need to host the catalog?
No. You send a feed (CSV/XML); we host and use it for dynamic carousels. See Import your catalog.

How do we send category info?
Via keywords only. Set window.beOpKeywords to an array of strings (e.g. ["beauty", "skincare"]) before the SDK runs and on each meaningful page or route change (then call BeOpSDK.watch()). The SDK sends them as kwds in the serve request. There is no separate structured-context API in the current SDK.

Can we A/B test different placements or context?
A/B testing of creatives and targeting is configured in the Audience Desk. For custom A/B tests (e.g. different context or slot names), use your own experimentation layer and pass different keywords/slots per variant. For dedicated support, contact your account manager or support.


Next steps and contact#