Skip to content

Newsletter Content campaigns

Read, create and tune the campaigns behind Newsletter Content: what decides which products each recipient sees in a newsletter, and how many.

A Newsletter Content setup has two halves, and they are configured separately. A design is the template one product tile is rendered from, covered on the Designs page. A campaign decides which products go into those tiles for each recipient, how many, and how the tiles are wired into the newsletter platform. This page covers the campaign half.

Hello Retail doesn't send the mail. The customer's own email platform does that, and what Hello Retail contributes is a set of image URLs the newsletter embeds, one per product slot, each resolved when the recipient opens the mail. A campaign is what those URLs point at.

docs://newsletter-content/campaigns is the reference document behind these tools. It covers the same ground as this page and is what an assistant should read before creating or editing a campaign.

Tips & tricks

Pick the card that matches what you're doing. Each prompt is ready to paste into your assistant.

Getting started

Pick the type first

The type decides when a recipient's products are re-picked, and it can't be changed afterwards. Most customers who send newsletters regularly want an Auto campaign: set up once, fresh products every send.

Explain the three Newsletter Content campaign types, then tell me which one suits a shop that sends a weekly newsletter from Mailchimp.
Before you save

Preview it twice

Preview for a known recipient and for an unknown one. They take different paths: a known recipient's own browsing history drives the personalized steps, while an unknown one gets the campaign's default products and whatever the catalog-wide steps return. An algorithm that only works for one of them looks fine in the step list.

Preview Newsletter Content campaign <CAMPAIGN ID> for a known recipient and then for an unknown one, and tell me how the two differ.
Strategy

Check an edit before writing it

newsletterContent_previewCampaign takes the same steps and filters as the update tool, so an edit can be seen before it reaches a campaign the customer is already sending with. There's no draft state to fall back on.

Read the algorithm of Newsletter Content campaign <CAMPAIGN ID>, propose a version that leads with recently viewed products, and preview it without saving.
Fixed products

Know which list does what

The three fixed-product lists are not symmetrical. Pinned products go to everyone, default products go only to recipients with no tracked behavior, and excluded products take no slot at all. Mixing up the first two is the usual mistake.

Pin these three products into every recipient's tiles on Newsletter Content campaign <CAMPAIGN ID>, and exclude our gift cards.
Auto campaigns

Check the merge tag

An Auto campaign relies on the newsletter platform substituting a value that is unique per send. A value that differs per recipient gives every recipient their own sent campaign, and nobody shares a newsletter. Mailchimp, ActiveCampaign and Heyloyalty are safe; the date-based ones collide between two sends on the same day.

Which newsletter platform is Newsletter Content campaign <CAMPAIGN ID> set up for, and does it support Auto campaigns?
Troubleshooting

Look at what actually went out

Each newsletter an Auto campaign has served is recorded as a sent campaign. An empty list means no tile has ever been served, which usually means the code snippet isn't in a newsletter yet, or the newsletter went out and nobody opened it.

List the sent campaigns for Newsletter Content campaign <CAMPAIGN ID> and tell me when it last served a newsletter.

The three campaign types

My Hello Retail names them Auto, Rolling and Manual. The stored type uses older names, and these tools take the stored ones.

Dashboard type What it is
Auto campaign TEMPLATE Set up once, and every newsletter the customer sends gets its own fresh products. Each send is recorded as a sent campaign.
Rolling campaign AUTORESET One campaign, reused by every send. A recipient's products are re-picked once they are older than autoresetDays.
Manual campaign NORMAL One campaign for one send. A recipient's products are picked once and never change.

A recipient's products are picked the first time they open the mail and then cached, so when are they re-picked is the whole difference between the three.

Auto is the type to reach for when the customer sends newsletters regularly. They paste the snippet once and never configure a campaign again. It needs a newsletter platform whose snippet carries a campaign merge tag; platformSupportsAutoCampaigns in newsletterContent_getCampaign says whether the campaign's platform has one.

Rolling suits a recurring or automated flow where there's no per-send campaign id to hand, such as a weekly digest or a platform automation. A recipient keeps the products they were first given until those are autoresetDays old, then the next open picks fresh ones. Default 7 days, minimum 1.

Manual suits a one-off newsletter or a promotion whose content shouldn't drift. A re-send of the same newsletter shows a recipient the same products.

Sent campaigns

Every newsletter an Auto campaign has served is recorded as a sent campaign: the products chosen for that one newsletter, with its own open and click figures, named after the date it first went out. The first recipient to open the mail starts the record, and every later recipient of the same newsletter is served from it. The next newsletter gets a record of its own.

A sent campaign is a record of something that happened, not a campaign anyone configured. It isn't part of the Auto, Rolling or Manual lists, and newsletterContent_listCampaigns doesn't return it. Read one campaign's with newsletterContent_listSentCampaignsForTemplate.

Why a sent campaign reports type: NORMAL

Under the hood a sent campaign is stored as a NORMAL campaign carrying the Auto campaign's templateKey, which is what newsletterContent_getCampaign reports if you look one up by id. That's a storage detail, not a Manual campaign: a Manual campaign is the keyless kind, created by a person.

What fills the slots

A campaign shows productCount products, and they're filled in this order.

Fixed products come first, in the order given. There are three lists and they're not symmetrical:

List Who sees it
includeProductIds Pinned into every recipient's tiles.
defaultProductIds Only a recipient Hello Retail has no behavior on. A known recipient never sees them.
excludeProductIds Nobody. This is a veto, and it takes no slot.

Fixed products ignore the campaign's filters and its grouping rule, so a pinned product shows even when it's out of stock. On an Auto campaign they're used once: the first newsletter after they were set takes them, every later one gets empty lists, until the campaign is saved again. Any save re-arms them, so a customer who wants the same pinned products in each newsletter has to re-save the campaign between sends. On a Rolling or Manual campaign they simply apply to every recipient.

The algorithm fills what's left. It's the same ordered-step format that drives Recommendations, documented in docs://product-algorithms/format, read with newsletterContent_getCampaignAlgorithm and written with newsletterContent_updateCampaignAlgorithm.

The algorithm runs for a recipient, not a page visitor. There's no product or category in context, so the steps that read one, RELATED, ALTERNATIVES and BOUGHT_TOGETHER, have nothing to start from unless an earlier step puts products there with useAsContext. The steps that work unaided are the ones reading the recipient's own history (RETARGETED, RECENTLY_BOUGHT, VIEWED_WITH, BOUGHT_WITH) and the catalog-wide ones (TOP, MOST_BOUGHT, MOST_VIEWED, RECENTLY_CREATED, SEARCH, MANUAL).

A fallback pass runs if the slots still aren't full: the steps run again without excluding the recipient's recent campaigns, with an unfiltered top-products step appended. A campaign therefore rarely renders short, which also means a badly targeted algorithm shows up as generic products rather than as an empty mail.

Two exclusions apply on top of the algorithm and aren't configurable: the campaign's excludeProductIds, and the products this recipient already received from other campaigns on the website recently. The second one is why the same recipient doesn't see the same product across a newsletter series.

Order of work

  1. newsletterContent_listDesigns. A campaign can't be saved without a design.
  2. newsletterContent_createCampaign. Pick the type.
  3. newsletterContent_updateCampaignAlgorithm. The steps that pick the products.
  4. newsletterContent_updateCampaign and newsletterContent_updateCampaignFixedProducts. Platform, UTM parameters, pinned products.
  5. newsletterContent_previewCampaign. The products and tiles a recipient would actually get.

Step 5 can come before step 3, because the preview takes the same steps and filters as the update tool. On a campaign that's already sending, that's the order to use.

Once it's sending, Newsletter Content analytics is what tells you whether it worked.

The code snippet the customer pastes into their newsletter platform is built in the campaign editor in My Hello Retail. There's no MCP tool for it, and a campaign has to be saved before the snippet exists, because it embeds the campaign id or the template key.

newsletterContent_listCampaigns

List the Newsletter Content campaigns of a customer website, one type at a time. The dashboard shows Auto, Rolling and Manual on three separate pages, and these are three separate calls. This lists what the customer configured; the sent campaigns an Auto campaign accumulates are not part of any of the three, and have their own tool.

The result is paged. totalCount is how many match in all, hasMore says whether another page follows, and skip and limit are the window you asked for. designId and designName are filled in for an Auto campaign, which points at a saved design; they're null for a Rolling or Manual campaign, which carries its own copy of the design, and newsletterContent_getCampaign resolves what that copy still matches.

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.
type string Yes Which kind of campaign to list: TEMPLATE (the dashboard's Auto campaigns), AUTORESET (Rolling) or NORMAL (Manual).
includeArchived boolean No Whether to include archived campaigns. Defaults to false.
limit integer No How many campaigns to return, at most 100. Defaults to 25.
skip integer No How many campaigns to skip, for paging. Defaults to 0. The cost of a page grows with how deep it is, so page shallowly.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_listCampaigns",
    "arguments": {
      "websiteUuid": "<string>",
      "type": "TEMPLATE"
    }
  }
}
{
  "type": "TEMPLATE",
  "totalCount": 3,
  "skip": 0,
  "limit": 25,
  "hasMore": false,
  "campaigns": [
    {
      "id": "<string>",
      "name": "<string>",
      "type": "TEMPLATE",
      "state": "LIVE",
      "templateKey": "<string>",
      "productCount": 10,
      "designId": "<string>",
      "designName": "<string>",
      "createdAt": "<string>"
    }
  ]
}

newsletterContent_listSentCampaignsForTemplate

List the sent campaigns of one Auto campaign: one row per newsletter it has served, newest first, exactly as that campaign's card shows them in the dashboard. A campaign with none has never served a tile, which usually means its code snippet isn't in a newsletter yet, or the newsletter has gone out but nobody has opened it.

This is the list that needs paging most: a busy website holds hundreds of thousands of these. Find the templateKey with newsletterContent_listCampaigns for type TEMPLATE.

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.
templateKey string Yes The Auto campaign's templateKey, as newsletterContent_listCampaigns reports it for a TEMPLATE campaign.
includeArchived boolean No Whether to include archived sends. Defaults to false.
limit integer No How many sends to return, at most 100. Defaults to 25.
skip integer No How many sends to skip, for paging. Defaults to 0.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_listSentCampaignsForTemplate",
    "arguments": {
      "websiteUuid": "<string>",
      "templateKey": "<string>",
      "limit": 10
    }
  }
}
{
  "templateKey": "<string>",
  "totalCount": 48,
  "skip": 0,
  "limit": 10,
  "hasMore": true,
  "campaigns": [
    {
      "id": "<string>",
      "name": "2026-02-17 - Weekly newsletter",
      "state": "LIVE",
      "productCount": 10,
      "createdAt": "<string>"
    }
  ]
}

newsletterContent_getCampaign

Retrieve one Newsletter Content campaign: its type and lifecycle state, how many products it shows, the design it renders tiles from, its fixed products, its newsletter platform wiring, its UTM parameters and its Retail Media setting.

design.id is the id of a saved design only while the campaign still matches one. A Rolling or Manual campaign keeps its own copy of the design, taken when the campaign was last saved with that design selected, so design.id comes back as custom once the saved design has moved on. That's normal, not an error. Designs covers why the three types bind to a design differently.

The product-selection steps aren't part of this; read them with newsletterContent_getCampaignAlgorithm.

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. Use newsletterContent_listCampaigns to find available ids.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_getCampaign",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>"
    }
  }
}
{
  "id": "<string>",
  "name": "<string>",
  "type": "TEMPLATE",
  "state": "LIVE",
  "templateKey": "<string>",
  "createdAt": "<string>",
  "productCount": 10,
  "autoresetDays": 7,
  "design": {
    "id": "<string>",
    "name": "<string>",
    "width": 300,
    "height": 350
  },
  "includeProductIds": [],
  "defaultProductIds": [],
  "excludeProductIds": [],
  "platformKey": "MAILCHIMP",
  "platformName": "Mailchimp",
  "platformSupportsAutoCampaigns": true,
  "productsPerRow": 3,
  "mobileResponsive": true,
  "utmMedium": "email",
  "utmCampaign": "<string>",
  "overrideUtmParams": true,
  "retailMediaInjectionMode": "ALL"
}

newsletterContent_getCampaignAlgorithm

Read the product-selection algorithm of a campaign: the ordered steps that fill its slots, the global filters every step draws through, and whether product variants count as one product. This is the Recommendation strategy section of the campaign editor. productCount is the number of slots the steps fill, and filterableFields lists the product fields a filter or condition on this campaign may name. Each step carries all of its possible fields, with the ones its productType doesn't use set to null, and the number the dashboard labels it with, counting from 1.

The format is the same one Recommendations uses and is documented in docs://product-algorithms/format; read it before making sense of what comes back. Remember that the fixed products of newsletterContent_updateCampaignFixedProducts fill their slots before any of this runs, and that the algorithm runs for a recipient, so nothing is in context unless a step puts it there.

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. Use newsletterContent_listCampaigns to find available ids.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_getCampaignAlgorithm",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>"
    }
  }
}
{
  "campaignId": "<string>",
  "type": "TEMPLATE",
  "state": "LIVE",
  "productCount": 10,
  "filterByGroupingKey": true,
  "filters": [
    { "field": "inStock", "operator": "EQUALS", "value": "true" }
  ],
  "steps": [
    {
      "number": 1,
      "productType": "RECENTLY_BOUGHT",
      "productLimit": 0,
      "onlyOffers": false,
      "excludeProducts": true,
      "useAsContext": false,
      "filters": [],
      "condition": null,
      "skipDaysAgo": 0,
      "numberDaysAgo": 0,
      "numberReceipts": 100,
      "skipReceipts": 0,
      "productIds": null,
      "relatedTo": null,
      "searchTerm": null,
      "priceInfluence": null
    },
    {
      "number": 2,
      "productType": "BOUGHT_WITH",
      "productLimit": 0,
      "onlyOffers": false,
      "excludeProducts": false,
      "useAsContext": false,
      "filters": [],
      "condition": null,
      "skipDaysAgo": null,
      "numberDaysAgo": null,
      "numberReceipts": null,
      "skipReceipts": null,
      "productIds": null,
      "relatedTo": "RETARGETED",
      "searchTerm": null,
      "priceInfluence": null
    }
  ],
  "filterableFields": ["price", "inStock", "brand", "hierarchies"]
}

newsletterContent_previewCampaign

Show what a campaign would actually put in front of a recipient: the products it picks for them, which step of the algorithm each one came from, and the rendered tiles as images. It persists nothing and sends nothing, and it neither reads nor writes a recipient's cached products, so previewing can't decide what that recipient receives for real.

Preview after every algorithm change, and preview twice: once for a known recipient and once for an unknown one. A known recipient's own browsing history drives the personalized steps, while an unknown one gets the campaign's default products and whatever the catalog-wide steps return. An algorithm that only works for one of them is the usual defect, and it's invisible in the step list.

Pass steps and filters to preview an algorithm you have not saved. The arguments are the same ones newsletterContent_updateCampaignAlgorithm takes, so this is how to check an edit before writing it to a campaign that's already sending.

sourceInfos reports what each step contributed and why, which is where to look when a step returns nothing. Only the first four products are rendered as images, because every tile is a JPEG in the assistant's context; the rest are still listed. A recipient's address comes back masked.

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. Use newsletterContent_listCampaigns to find available ids.
audience string No Who to preview for: SAMPLED_KNOWN_RECIPIENT (a real recipient of this website, picked for you, which shows personalization working), UNKNOWN_RECIPIENT (someone Hello Retail has no behavior on, which is what a new subscriber is) or SPECIFIC_RECIPIENT (the address in email). Defaults to SAMPLED_KNOWN_RECIPIENT.
email string No The recipient's email address. Required for SPECIFIC_RECIPIENT and ignored otherwise. An address with no behavior on this website previews as an unknown recipient, and knownRecipient says so.
steps array No An unsaved step list to preview instead of the campaign's own, in the same shape newsletterContent_updateCampaignAlgorithm takes.
filters array No An unsaved global filter list to preview instead of the campaign's own.
filterByGroupingKey boolean No Whether variants the catalog groups together count as one product, for this preview only.

A website with no tracked recipient can't serve SAMPLED_KNOWN_RECIPIENT, and the call is refused rather than quietly falling back, because a silent switch of audience would be read as personalization having produced the result. Preview with UNKNOWN_RECIPIENT to see what the campaign sends regardless.

Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_previewCampaign",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>",
      "audience": "UNKNOWN_RECIPIENT"
    }
  }
}
{
  "campaignId": "<string>",
  "audience": "UNKNOWN_RECIPIENT",
  "recipient": null,
  "knownRecipient": false,
  "productCount": 10,
  "products": [
    {
      "position": 1,
      "title": "<string>",
      "url": "<string>",
      "onSale": true,
      "banner": false,
      "rendered": true,
      "error": null
    },
    {
      "position": 5,
      "title": "<string>",
      "url": "<string>",
      "onSale": false,
      "banner": false,
      "rendered": false,
      "error": null
    }
  ],
  "sourceInfos": [
    { "step": "Most viewed", "count": 10, "message": null }
  ],
  "debug": []
}

The tiles come back alongside this as image content, in the same order as products.


newsletterContent_createCampaign

Create a Newsletter Content campaign. Pick the type deliberately: it decides when a recipient's products are re-picked and it can't be changed afterwards. The three campaign types covers what each one is for.

The campaign starts with Hello Retail's default newsletter algorithm, which leads with recently viewed and bought products and products related to them, then falls back to most viewed, in stock only. Shape it with newsletterContent_updateCampaignAlgorithm, and set the platform, UTM parameters and fixed products with newsletterContent_updateCampaign and newsletterContent_updateCampaignFixedProducts.

Creating a campaign doesn't put anything in a newsletter. The customer has to paste the campaign's code snippet into their newsletter platform, and that snippet is built in the campaign editor in My Hello Retail.

Write operation

This tool creates a campaign on the website, LIVE from the start. Newsletter Content campaigns have no draft state. Nothing reaches a recipient until the code snippet is in a newsletter. 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 Name of the campaign, as shown in the dashboard's campaign list.
type string Yes TEMPLATE (an Auto campaign), AUTORESET (a Rolling campaign) or NORMAL (a Manual campaign). Can't be changed later.
designId string Yes The id of the design the tiles are rendered from. Must be a LIVE design of this website; use newsletterContent_listDesigns. A campaign can't be saved without one.
productCount integer No How many products the campaign shows, between 1 and 40. Defaults to 10.
autoresetDays integer No Rolling campaigns only: how many days a recipient keeps their products before fresh ones are picked. At least 1; defaults to 7.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_createCampaign",
    "arguments": {
      "websiteUuid": "<string>",
      "name": "Weekly newsletter",
      "type": "TEMPLATE",
      "designId": "<string>",
      "productCount": 6
    }
  }
}
{
  "id": "<string>",
  "name": "Weekly newsletter",
  "type": "TEMPLATE",
  "state": "LIVE",
  "templateKey": "<string>",
  "createdAt": "<string>",
  "productCount": 6,
  "autoresetDays": 7,
  "design": {
    "id": "<string>",
    "name": "<string>",
    "width": 300,
    "height": 350
  },
  "includeProductIds": [],
  "defaultProductIds": [],
  "excludeProductIds": [],
  "platformKey": null,
  "platformName": null,
  "platformSupportsAutoCampaigns": false,
  "productsPerRow": null,
  "mobileResponsive": null,
  "utmMedium": "",
  "utmCampaign": "",
  "overrideUtmParams": true,
  "retailMediaInjectionMode": "ALL"
}

newsletterContent_updateCampaign

Update a campaign's settings. Updates are partial: omitted fields are left unchanged, but at least one must be provided. The campaign's type can't be changed; a campaign that's the wrong type has to be created again.

Two edits reach beyond this campaign. Changing designId gives a Rolling or Manual campaign a fresh copy of that design, so it stops tracking whatever it carried before, while an Auto campaign points at the design and picks up later edits to it. And any save re-arms an Auto campaign's fixed products, which otherwise go out with the first newsletter after they were set and with no later one.

The product-selection steps are edited with newsletterContent_updateCampaignAlgorithm and the fixed products with newsletterContent_updateCampaignFixedProducts.

Write operation

This tool edits the campaign in place. Newsletter Content campaigns have no draft state, so the save is immediately the campaign's only version. Setting state to ARCHIVED hides the campaign and stops it serving new content; tiles already rendered keep working, so archiving doesn't blank the pictures in mail already sent. 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.
campaignId string Yes The id of the campaign. Use newsletterContent_listCampaigns to find available ids.
name string No New name for the campaign.
state string No LIVE or ARCHIVED.
productCount integer No How many products the campaign shows, between 1 and 40.
designId string No The id of a LIVE design of this website to render the tiles from; use newsletterContent_listDesigns.
autoresetDays integer No Rolling campaigns only: how many days a recipient keeps their products before fresh ones are picked. At least 1. Stored but unused on the other two types.
platformKey string No The newsletter platform the code snippet is written for, as newsletterContent_getCampaign reports it. Getting this wrong breaks the snippet's merge tags, so change it only when the customer has moved platform.
productsPerRow integer No How many tiles the generated snippet lays out per row. Ignored unless the platform's snippet is a table Hello Retail builds.
mobileResponsive boolean No Whether the snippet scales the tiles down on narrow screens. Ignored unless the platform supports it.
utmMedium string No utm_medium appended to every product link.
utmCampaign string No utm_campaign appended to every product link.
overrideUtmParams boolean No Whether Hello Retail's UTM parameters replace the ones the newsletter platform already put on a link. False leaves the platform's in place.
retailMediaInjectionMode string No Which Retail Media content may take slots in this campaign: ALL, PRODUCTS_ONLY, BANNERS_ONLY or NONE.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_updateCampaign",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>",
      "productCount": 8,
      "utmMedium": "email"
    }
  }
}

The whole campaign, in the shape newsletterContent_getCampaign returns.


newsletterContent_updateCampaignFixedProducts

Replace a campaign's fixed products: the products it pins, falls back to, or refuses. Each list you pass replaces that list whole; [] empties one and an omitted list is left alone. At least one must be provided.

The three aren't symmetrical, and this is the usual place to get one wrong. includeProductIds is pinned into every recipient's tiles, in this order, before the algorithm runs, and ignores the campaign's filters, so a pinned product shows even when it's out of stock. defaultProductIds are used only for a recipient Hello Retail has no behavior on, so this is a fallback rather than a second pinned list, and a known recipient never sees them. excludeProductIds are never recommended to anyone; this is a veto and takes no slot.

Pinning more products than the campaign's productCount leaves the algorithm nothing to fill, which is a valid but fully manual campaign. Product ids are the catalog's own; productData_search finds them.

Write operation

This tool replaces the campaign's fixed-product lists. On an Auto campaign they go out with the first newsletter after this call and with no later one, until the campaign is saved again. 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.
campaignId string Yes The id of the campaign. Use newsletterContent_listCampaigns to find available ids.
includeProductIds string[] No Products pinned into every recipient's tiles, in this order.
defaultProductIds string[] No Products shown only to recipients Hello Retail has no behavior on, in this order.
excludeProductIds string[] No Products never recommended, to any recipient.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_updateCampaignFixedProducts",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>",
      "includeProductIds": ["<string>", "<string>"],
      "excludeProductIds": ["<string>"]
    }
  }
}

The whole campaign, in the shape newsletterContent_getCampaign returns.


newsletterContent_updateCampaignAlgorithm

Change the product-selection algorithm of a campaign. Read docs://product-algorithms/format first: it holds every step type with the extra fields it carries, the filter operators and $context expressions, the run conditions and worked examples.

Updates are partial, and each argument replaces its part whole. Omitted arguments are left unchanged, but at least one must be given. Passing steps replaces every step, so read the current ones with newsletterContent_getCampaignAlgorithm and send them back with your edits; a campaign must keep at least one step. An input the engine can't run is refused with the path of the offending step, and nothing is saved. Input that's storable but probably not what you meant, such as a filter on a field the website can't filter on, is saved and reported in warnings.

The per-step, per-filter and per-condition fields are the same ones Recommendations uses, documented under recoms_updateAlgorithm. What differs is what's in context: the algorithm runs for a recipient, not a page visitor.

Write operation

This tool replaces the campaign's algorithm. Newsletter Content campaigns have no draft state, so the change reaches the campaign at once, though not the newsletters already out: a Manual campaign's recipients keep their products forever, a Rolling campaign's until they're autoresetDays old, and an Auto campaign applies the edit to the newsletters sent after it. Preview first with newsletterContent_previewCampaign, which takes the same arguments. 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.
campaignId string Yes The id of the campaign. Use newsletterContent_listCampaigns to find available ids.
steps array No The whole ordered step list, replacing the current one. Steps run from the top, each filling the remaining slots, and numbered from 1 as the dashboard labels them. A step's number is its position, not a way to move it: send the list in the order you want it run, and either leave number out or let it match. Fields per entry are documented under recoms_updateAlgorithm.
filters array No The whole global filter list, replacing the current one. These apply to every step except MANUAL; [] removes them all. A list-valued field (hierarchies, category, extraDataList.*) takes a JSON list even for a single value, as in ["green"].
filterByGroupingKey boolean No Whether variants the catalog groups together count as one product, so five colors of the same shirt can't take five slots.
Example request & response
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "newsletterContent_updateCampaignAlgorithm",
    "arguments": {
      "websiteUuid": "<string>",
      "campaignId": "<string>",
      "steps": [
        {
          "productType": "RETARGETED",
          "productLimit": 4,
          "skipDaysAgo": 1,
          "numberDaysAgo": 30
        },
        {
          "productType": "MOST_VIEWED",
          "productLimit": 0
        }
      ],
      "filters": [
        { "field": "inStock", "operator": "EQUALS", "value": "true" }
      ]
    }
  }
}
{
  "campaignId": "<string>",
  "type": "TEMPLATE",
  "state": "LIVE",
  "productCount": 10,
  "filterByGroupingKey": true,
  "filters": [
    { "field": "inStock", "operator": "EQUALS", "value": "true" }
  ],
  "steps": ["…as newsletterContent_getCampaignAlgorithm returns them"],
  "filterableFields": ["price", "inStock", "brand", "hierarchies"],
  "warnings": []
}