Retail Media¶
List a website's Retail Media campaigns, read one in full, check the banner placement sizes the website is configured for, create product and banner campaigns for review, and see how they are performing.
Retail Media campaigns are advertiser-funded placements shown among a website's own products. A campaign either shows banners or promotes products, picked by id, by a filter over product fields, or both. Either way the placements appear inside Search, Recommendations, Pages and Newsletter Content, in the slots the website's settings allow.
Tips & tricks¶
Pick the card that matches what you're doing. Each prompt is ready to paste into your assistant.
List first, then read one
retailMedia_listCampaigns gives the id, type, lifecycle status, goal and CPM of every campaign. retailMedia_getCampaign adds what it actually promotes: the product selection and filter, or the banners and their artwork. Archived campaigns are a separate list, so ask for them with archived=true.
Ids, a filter, or both
A product campaign promotes products you name by id, products matched by a filter over product fields, or both together. The filter is an OR of AND-groups: a product is promoted when every condition in any one group holds. Use productData_search to turn a name into an id, and productData_getFieldValues to see the values a field really holds before you filter on it.
Read the sizes, then export at 2x
retailMedia_getSettings lists the placement sizes the website is configured for, and every banner needs one image per size, named exactly as listed. Export each at twice those dimensions: banners are served at 2x for high-density screens, so artwork at the listed size gets upscaled and re-encoded, which softens it.
Nothing here publishes a campaign
Both create tools leave the campaign in REVIEW, and no tool makes one live. A live campaign spends an advertiser's budget at the CPM it was created with, so that step stays a deliberate one in My Hello Retail. Expect to review what was created before you publish it.
One tool, three questions
retailMedia_getAnalytics answers whichever question you asked. Without a campaign id it returns one row per campaign, so you can see which are working. With one it returns that campaign's totals plus a breakdown per promoted product or per banner. Ask for breakdown=DAILY to get a day-by-day series instead of that breakdown.
Two numbers that mean what they say
estimatedSpend prices the window's views at the campaign's CPM. It is an estimate to reason with, not a billed figure. goalProgress deliberately counts the campaign's whole lifetime rather than the window you asked about, because the lifetime count is what decides when the campaign auto-concludes.
retailMedia_listCampaigns¶
List a website's Retail Media campaigns, newest first. Returns one summary per campaign with its type, lifecycle status, goal, CPM and item counts. Archived campaigns are kept out of the normal list and returned only when you ask for them.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
archived | boolean | No | Return archived campaigns instead of current ones. Defaults to false. |
campaignType | string | No | Only campaigns of this type: PRODUCT or BANNER. Omit for both. |
skip | integer | No | Number of campaigns to skip, for paging. Defaults to 0. |
limit | integer | No | Maximum number of campaigns to return. Default 100, maximum 500. |
status is where the campaign sits in its lifecycle, derived from its state, dates and archive flag:
REVIEW: created but not published, so it is not being shown to anyone.SCHEDULED: published, with a start date still in the future.ACTIVE: published and within its dates.ENDED: past its end date.CONCLUDED: stopped early because it reached its goal.ARCHIVED: archived, whatever it was doing before.
Example request & response
{
"campaigns": [
{
"id": "<string>",
"name": "Autumn brand takeover",
"campaignType": "BANNER",
"state": "LIVE",
"archived": false,
"status": "ACTIVE",
"startAt": "2026-09-01",
"endAt": "2026-09-30",
"concludedAt": null,
"goal": { "type": "VIEWS", "limit": 500000 },
"cpm": 15.0,
"productCount": 0,
"bannerCount": 1,
"createdAt": "2026-08-28T09:12:44Z",
"updatedAt": "2026-08-28T09:12:44Z"
}
],
"totalCount": 1,
"hasMore": false
}
retailMedia_getCampaign¶
Read one campaign in full: its product selection or banners, the filter picking which products it promotes, the emails notified when it concludes, and the placement settings it overrides. Use retailMedia_listCampaigns to find the id.
For banner campaigns this is also where you check the artwork. sizesReady says whether every banner has an image at every configured placement size, missingSizes lists the sizes still missing, and obsoleteSizes lists sizes the images carry that the website's settings no longer ask for. A campaign created with retailMedia_createBannerCampaign is ready as soon as that call returns; one whose banners were generated by AI in the dashboard becomes ready as that rendering finishes, and an image with a generationError has failed for good and will never be ready.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
campaignId | string | Yes | The id of the campaign, from retailMedia_listCampaigns. |
Example request & response
{
"campaign": {
"id": "<string>",
"name": "Autumn brand takeover",
"campaignType": "BANNER",
"state": "REVIEW",
"archived": false,
"status": "REVIEW",
"startAt": "2026-09-01",
"endAt": "2026-09-30",
"concludedAt": null,
"goal": null,
"cpm": 15.0,
"productCount": 0,
"bannerCount": 1,
"createdAt": "2026-08-28T09:12:44Z",
"updatedAt": "2026-08-28T09:12:44Z"
},
"filter": null,
"productIds": null,
"banners": [
{
"id": "<string>",
"title": "Autumn",
"description": "New arrivals",
"destinationUrl": "https://example.com/autumn",
"relevanceType": "ALWAYS",
"labels": [],
"contextProductIds": [],
"fieldConditions": [],
"images": [
{
"id": "<string>",
"altText": null,
"url": null,
"generationError": null,
"sizes": [
{
"name": "leaderboard",
"width": 728,
"height": 90,
"url": "<string>",
"ready": true
}
]
}
]
}
],
"sizesReady": true,
"missingSizes": [],
"obsoleteSizes": [],
"notifyEmails": ["ads@example.com"],
"featureSettings": [],
"featureSettingsMobile": []
}
retailMedia_getSettings¶
Read a website's Retail Media settings: the banner placement sizes its banners must be supplied in, and where campaigns may appear on desktop and mobile. Read this before retailMedia_createBannerCampaign, which wants one image per configured size, named exactly as listed here.
Sizes and placements are configured in My Hello Retail, not through these tools. A website with no sizes configured cannot take banner campaigns yet.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
featureSettings and featureSettingsMobile say where campaigns may appear. Each entry names a solution (SEARCH, PRODUCT_RECOMMENDATION, PAGES, or EMAIL_CAMPAIGN for Newsletter Content) and the positions in that solution's result list, counted from 0, that a campaign may take.
Example request & response
{
"bannerSizes": [
{ "name": "leaderboard", "width": 728, "height": 90 },
{ "name": "square", "width": 300, "height": 300 }
],
"featureSettings": [
{ "featureType": "SEARCH", "positions": [0, 2, 6] },
{ "featureType": "PRODUCT_RECOMMENDATION", "positions": [0, 4] }
],
"featureSettingsMobile": [
{ "featureType": "SEARCH", "positions": [0, 2, 6] }
]
}
retailMedia_createProductCampaign¶
Create a campaign that promotes products, chosen by explicit product ids, by a filter over product fields, or by both. At least one of the two is required, since a product campaign with neither promotes nothing.
The filter is an OR of AND-groups: a product is promoted when every condition in any one group holds. Only fields the website indexes for search can be filtered on, and an unrecognised field would quietly match no products at all, so the tool rejects one and lists what is available. Use productData_getFieldValues to see a field's real values before filtering on it.
Every argument here is a commercial decision the customer owns: which products run, at what CPM, over which dates, and whether the campaign stops on a goal.
Write operation
This tool creates a campaign in REVIEW. Publishing it to live requires My Hello Retail. Your assistant will ask for confirmation before this runs.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
name | string | Yes | Campaign name, as shown in the dashboard. |
startAt | string | Yes | First day the campaign may run, as YYYY-MM-DD. |
endAt | string | No | Last day the campaign may run, as YYYY-MM-DD. Omit to run until concluded manually or by its goal. |
cpm | number | Yes | Price per thousand views the advertiser pays. Must be greater than 0. |
goal | object | No | Auto-conclude the campaign once it reaches this many views or clicks: {"type": "VIEWS" or "CLICKS", "limit": <integer>}. Counted over the campaign's lifetime. Omit to run to the end date. |
productIds | array | No | Ids of products to promote. At least one of productIds or filter is required. Use productData_search to turn a product name into an id. |
filter | array of objects | No | Groups of conditions selecting products to promote, OR-ed with each other. Per entry: conditions, an array of {"field": "<product field>", "operator": "EQUALS" | "NOT_EQUALS" | "LESS_THAN" | "GREATER_THAN", "value": "<string>"} objects, AND-ed with each other. |
notifyEmails | array | No | Email addresses notified when the campaign concludes. |
The response wraps the created campaign in the same shape retailMedia_getCampaign returns, alongside a nextSteps line naming what is left to do.
Example request & response
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "retailMedia_createProductCampaign",
"arguments": {
"websiteUuid": "<string>",
"name": "Nike autumn push",
"startAt": "2026-09-01",
"endAt": "2026-09-30",
"cpm": 15,
"goal": { "type": "VIEWS", "limit": 500000 },
"filter": [
{
"conditions": [
{ "field": "brand", "operator": "EQUALS", "value": "Nike" }
]
}
],
"notifyEmails": ["ads@example.com"]
}
}
}
{
"campaign": {
"campaign": {
"id": "<string>",
"name": "Nike autumn push",
"campaignType": "PRODUCT",
"state": "REVIEW",
"status": "REVIEW",
"startAt": "2026-09-01",
"endAt": "2026-09-30",
"cpm": 15.0,
"productCount": 0,
"bannerCount": 0
},
"filter": [
{
"conditions": [
{ "field": "brand", "operator": "EQUALS", "value": "Nike" }
]
}
],
"productIds": null,
"banners": null,
"sizesReady": null,
"notifyEmails": ["ads@example.com"]
},
"nextSteps": "The campaign was created in REVIEW. Publish it from the Hello Retail dashboard when it looks right."
}
retailMedia_createBannerCampaign¶
Create a campaign that shows banners. The customer supplies finished artwork at every placement size the website is configured for: call retailMedia_getSettings for those sizes, then give each banner one image per size, naming the size exactly as listed.
Supply each image at twice the listed dimensions, so a 728x90 placement wants 1456x180 artwork, because banners are served at 2x for high-density screens. Artwork already at 2x is stored exactly as given; artwork at the listed size is upscaled and re-encoded to JPEG, which softens it. An image is the picture's own bytes, base64-encoded, either bare or as a data: URI; a link to an image is not accepted, because the artwork is stored in Hello Retail rather than hotlinked. PNG, JPEG and WebP are accepted.
This tool does not generate or resize imagery. AI banner generation is a dashboard feature.
relevanceType decides where a banner may appear:
ALWAYS: anywhere the website's placement settings allow.PRODUCTS: only alongside products similar to the ones named incontextProductIds.FIELDS: only where a product field matches, given as exactly one condition onhierarchiesorbrand.
A banner carries the data of its chosen type only. Context products on an ALWAYS banner, or field conditions on a PRODUCTS one, are rejected rather than silently dropped.
Write operation
This tool creates a campaign in REVIEW and stores the artwork you supply as soon as it runs. Publishing the campaign to live requires My Hello Retail. Your assistant will ask for confirmation before this runs.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
name | string | Yes | Campaign name, as shown in the dashboard. |
startAt | string | Yes | First day the campaign may run, as YYYY-MM-DD. |
endAt | string | No | Last day the campaign may run, as YYYY-MM-DD. Omit to run until concluded manually or by its goal. |
cpm | number | Yes | Price per thousand views the advertiser pays. Must be greater than 0. |
goal | object | No | Auto-conclude the campaign once it reaches this many views or clicks: {"type": "VIEWS" or "CLICKS", "limit": <integer>}. Counted over the campaign's lifetime. Omit to run to the end date. |
banners | array of objects | Yes | The banners to show, at least one. Per entry: title (required), description, destinationUrl, relevanceType (ALWAYS, PRODUCTS or FIELDS), and images, an array of {"sizeName": "<name from retailMedia_getSettings>", "image": "<base64>"} covering every configured size. PRODUCTS banners add contextProductIds; FIELDS banners add fieldConditions, an array holding exactly one {"field": "hierarchies" | "brand", "values": ["<value>"]}. |
notifyEmails | array | No | Email addresses notified when the campaign concludes. |
Example request & response
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "retailMedia_createBannerCampaign",
"arguments": {
"websiteUuid": "<string>",
"name": "Autumn brand takeover",
"startAt": "2026-09-01",
"endAt": "2026-09-30",
"cpm": 15,
"banners": [
{
"title": "Autumn",
"description": "New arrivals",
"destinationUrl": "https://example.com/autumn",
"relevanceType": "ALWAYS",
"images": [
{ "sizeName": "leaderboard", "image": "<base64>" },
{ "sizeName": "square", "image": "data:image/png;base64,<base64>" }
]
}
]
}
}
}
{
"campaign": {
"campaign": {
"id": "<string>",
"name": "Autumn brand takeover",
"campaignType": "BANNER",
"state": "REVIEW",
"status": "REVIEW",
"cpm": 15.0,
"bannerCount": 1
},
"banners": [
{
"id": "<string>",
"title": "Autumn",
"relevanceType": "ALWAYS",
"images": [
{
"id": "<string>",
"generationError": null,
"sizes": [
{ "name": "leaderboard", "width": 728, "height": 90, "url": "<string>", "ready": true },
{ "name": "square", "width": 300, "height": 300, "url": "<string>", "ready": true }
]
}
]
}
],
"sizesReady": true,
"missingSizes": [],
"obsoleteSizes": []
},
"nextSteps": "The artwork is stored at every configured placement size. Review it with retailMedia_getCampaign, then publish the campaign from the Hello Retail dashboard."
}
retailMedia_getAnalytics¶
Report how a website's Retail Media campaigns are performing. The answer takes one of three shapes:
- Without
campaignId: one row per campaign, with views, clicks, conversions and revenue. Use it to see which campaigns are working. - With
campaignId: that campaign's totals, plus a breakdown per promoted product or per banner, plusgoalProgresstoward its auto-conclude limit. - With
campaignIdandbreakdown=DAILY: that campaign's totals and a day-by-day series instead of the per-item breakdown. Days with no activity are included as zeroes.
The window defaults to the last 30 days ending today, and cannot span more than 13 months.
| Name | Type | Required | Description |
|---|---|---|---|
websiteUuid | string | Yes | The UUID of the customer's website in Hello Retail. Use website_getInfo to look up available websites, or find it in my.helloretail.com under Settings → Website Settings → Website Unique Id. |
campaignId | string | No | The id of one campaign, from retailMedia_listCampaigns. Omit for one row per campaign. |
startDate | string | No | Start of the window, inclusive, as YYYY-MM-DD. Defaults to a 30-day window ending on endDate. |
endDate | string | No | End of the window, inclusive, as YYYY-MM-DD. Defaults to today. |
breakdown | string | No | With campaignId, what to break the numbers down by: ITEMS (per promoted product or banner) or DAILY (a time series). Defaults to ITEMS. |
featureType | string | No | Only count placements in this solution: SEARCH, PRODUCT_RECOMMENDATION, PAGES or EMAIL_CAMPAIGN for Newsletter Content. Omit for all of them. |
limit | integer | No | Maximum number of breakdown rows to return. Default 20, maximum 100. |
Every metrics block carries the same fields: views, clicks and clickThroughRate; conversions, revenue and conversionRate for purchases attributed to a click on the placement; and productConversions and productRevenue for the promoted products themselves.
Two numbers need reading carefully. estimatedSpend prices the window's views at the campaign's CPM, which makes it an estimate rather than a billed figure. goalProgress counts the campaign's whole lifetime rather than the window you asked about, because the lifetime count is what decides when the campaign concludes.
Example request & response
{
"startDate": "2026-09-01",
"endDate": "2026-09-30",
"campaigns": null,
"campaign": {
"campaign": {
"id": "<string>",
"name": "Nike autumn push",
"campaignType": "PRODUCT",
"status": "ACTIVE",
"cpm": 15.0
},
"totals": {
"views": 412000,
"clicks": 5300,
"conversions": 210,
"revenue": 184000.0,
"productConversions": 340,
"productRevenue": 291000.0,
"clickThroughRate": 1.29,
"conversionRate": 3.96
},
"items": [
{
"id": "<string>",
"title": "Nike Air Max",
"metrics": {
"views": 96000,
"clicks": 1450,
"conversions": 62,
"revenue": 54000.0,
"productConversions": 88,
"productRevenue": 77000.0,
"clickThroughRate": 1.51,
"conversionRate": 4.28
}
}
],
"series": null,
"goalProgress": {
"type": "VIEWS",
"limit": 500000,
"current": 412000,
"pct": 82.4,
"reached": false
},
"estimatedSpend": 6180.0
}
}