Configure Recommendation pages

ℹ️

This feature is currently in beta.

This feature is currently available to a small group of users and may change. To request access, contact your Customer Success Manager.

A Recommendation page is a named, ordered set of recommendation pods that render together on one storefront page, such as a product detail page or a cart. Instead of requesting each pod separately, your storefront requests the whole page in one call with Retrieve page results, and Constructor removes duplicate products across the page's pods before it responds.

This guide covers how to configure pages through the Page Management API at /v1/recommendation_pages. Each operation has its own reference page under Recommendation pages.

Before you start

  • Pages and pods both belong to one index and section, chosen with the key and section query parameters. section defaults to Products. Every pod on a page must already exist in the same key and section as the page, and a page configured for one section can't be retrieved from another.
  • Requests authenticate with an API token. Retrieving pages requires the recommendations(r) scope; creating, replacing, updating, and deleting them requires recommendations(w).

The page resource

{
  "page_id": "pdp_b2c",
  "display_name": "PDP - B2C",
  "page_type": "pdp",
  "pods": [
    { "pod_id": "similar_items" },
    { "pod_id": "complete_the_look" }
  ],
  "metadata_json": {
    "page_config": { "deduplication_key": "item_id" }
  },
  "created_at": "2026-07-15T10:00:00",
  "updated_at": "2026-07-15T10:00:00"
}
FieldDescription
page_idThe page's identifier within the key and section, and the {page_id} your storefront requests. A lowercase slug of letters, digits, underscores, and hyphens that starts with a letter or digit, up to 255 characters.
display_nameA human-readable label for dashboards and reporting, from 2 to 100 characters.
page_typeThe role the page plays in your storefront. See Page types.
podsThe pods on the page, in the order a shopper sees them. See Pod order.
metadata_json.page_config.deduplication_keyWhat counts as a duplicate across the page's pods. See Deduplication key.
created_at, updated_atWhen the page was created and last changed. Read-only.

Page types

page_type is required. It's metadata only and doesn't affect retrieval behavior today.

ValuePage
pdpProduct detail page
plpProduct listing page, including search results pages
homeHomepage or other landing page
cartCart page
atcAdd-to-cart confirmation or mini-cart
checkoutCheckout flow
order_confirmOrder confirmation page
empty_cartEmpty cart state
otherAny page that doesn't fit the types above

Pod order

List the pods in the order a shopper encounters them on the rendered page: top to bottom, then left to right for pods that sit side by side. If a pod appears only at a smaller breakpoint, place it where it falls in the primary desktop layout.

  • Page results return the pods in this order. A retrieval request can't reorder them; only a configuration write changes the order.
  • The order describes your layout; your storefront still controls rendering.
  • Constructor decides which pod keeps a product that more than one pod would return, and how it decides may change, so don't rely on a particular pod keeping a particular product. To guarantee that a product appears in a specific pod, slot it there: slotted products are never removed.

Keep the order accurate when you redesign a page so reporting continues to reflect what shoppers see.

Deduplication key

deduplication_key applies to the whole page and can't be overridden in a retrieval request.

ValueA product is a duplicate when an earlier result has
item_id (default)the same item_id, whatever its variation
item_and_variation_idthe same item_id and the same variation_id

The default suits most catalogs: a shopper who sees the same product twice in different colors still sees a duplicate. Choose item_and_variation_id when variations are meaningfully different products, such as furniture in different fabrics.

Limits

A page holds at most 5 pods. A pod can appear only once on a page. A page can also have no pods, such as before you assign any: it keeps its settings, and its results return an empty pods list.

Endpoints

MethodPathBehavior
GET/v1/recommendation_pagesList pages, optionally only those that use a pod.
POST/v1/recommendation_pagesCreate a page. Answers 409 if the page_id is taken.
GET/v1/recommendation_pages/{page_id}Retrieve a page.
PUT/v1/recommendation_pages/{page_id}Create or fully replace a page.
PATCH/v1/recommendation_pages/{page_id}Update some fields of a page.
DELETE/v1/recommendation_pages/{page_id}Delete a page and return the configuration it had. Its pods aren't affected.

Every successful write answers 200 OK with the page as stored, including a POST and a PUT that creates a page.

Replace or update a page

PUTPATCH
display_name, page_typeRequiredChanged only if supplied
podsRequired; replaces the complete listIf supplied, replaces the complete list; if omitted, left unchanged
metadata_jsonReplaced: any setting you leave out, or the whole field, returns to its defaultMerged recursively into the current settings; a null setting returns to its default

pods is always replaced as a whole and can never be patched in part. To add, remove, or reorder a pod, send the complete list in the order you want. "pods": [] empties the page and keeps its other settings. PATCH rejects "pods": null.

List pages

GET /v1/recommendation_pages returns {"pages": [...], "total_count": <int>}, ordered by page_id. total_count is the number of matching pages before pagination.

  • Paginate with page (starting at 1) or offset, but not both, and set the page size with num_results_per_page (default 20, maximum 100).
  • Pass pod_id to return only the pages whose pods include that pod. Without it, every page in the key and section is returned.
curl -u '[api token]:' \
  "https://ac.cnstrc.com/v1/recommendation_pages?key=[your key]&section=Products&pod_id=similar_items"

Delete a pod that a page uses

Deleting a recommendation pod with DELETE /v1/recommendation_pods/{pod_id} is rejected with 409 Conflict while any page still lists the pod. The pod isn't deleted and no page is changed. The message names every blocking page:

{
  "message": "Recommendation pod \"similar_items\" cannot be deleted because it is referenced by page(s): \"home_b2b\", \"pdp_b2c\". Remove the pod from these pages first."
}

Pods are never removed from pages automatically. To delete a pod that pages use:

  1. Call GET /v1/recommendation_pages?pod_id=<pod_id> to fetch the blocking pages with their current pods.
  2. For each page, PATCH the page with its pods list minus that pod. If it was the page's only pod, the page is left empty and keeps its settings. Interfaces that manage pages can offer to do this automatically.
  3. Retry the pod delete.

Errors

Errors use the same shape as other configuration endpoints:

{ "message": "<description>" }
StatusCauseMessage
400Invalid page_idpage_id: Must be a lowercase slug containing only letters, numbers, underscores, and hyphens.
400display_name too shortdisplay_name: Must be at least 2 characters.
400display_name too longdisplay_name: Must be at most 100 characters.
400Invalid page_typepage_type: Must be one of pdp, plp, home, cart, atc, checkout, order_confirm, empty_cart, other.
400Invalid deduplication_keymetadata_json.page_config.deduplication_key: Must be one of item_id, item_and_variation_id.
400Too many podspods: A page may contain at most 5 pods; 6 were supplied.
400Repeated podpods: Pod "similar_items" appears more than once at index 2.
404Unknown podpods[1].pod_id: Recommendation pod "unknown_pod" was not found for section "Products".
404Unknown pageRecommendation page "pdp_b2c" was not found.
409Page already exists (POST)Page "pdp_b2c" already exists for section "Products". Use PUT to replace it.
409Pod still used by a page (pod DELETE)Recommendation pod "similar_items" cannot be deleted because it is referenced by page(s): "home_b2b", "pdp_b2c". Remove the pod from these pages first.

Indexes in pod messages are zero-based positions in the pods array you sent. Blocking pages in the last message are listed in page_id order.

Examples

Create a page:

curl -X POST -H 'Content-Type: application/json' \
  -u '[api token]:' \
  "https://ac.cnstrc.com/v1/recommendation_pages?key=[your key]&section=Products" \
  -d '{
    "page_id": "pdp_b2c",
    "display_name": "PDP - B2C",
    "page_type": "pdp",
    "pods": [
      { "pod_id": "similar_items" },
      { "pod_id": "complete_the_look" }
    ]
  }'

Reorder the pods and add one, leaving the other fields unchanged:

curl -X PATCH -H 'Content-Type: application/json' \
  -u '[api token]:' \
  "https://ac.cnstrc.com/v1/recommendation_pages/pdp_b2c?key=[your key]&section=Products" \
  -d '{
    "pods": [
      { "pod_id": "complete_the_look" },
      { "pod_id": "similar_items" },
      { "pod_id": "recently_viewed" }
    ]
  }'

Treat variations as distinct products:

curl -X PATCH -H 'Content-Type: application/json' \
  -u '[api token]:' \
  "https://ac.cnstrc.com/v1/recommendation_pages/pdp_b2c?key=[your key]&section=Products" \
  -d '{ "metadata_json": { "page_config": { "deduplication_key": "item_and_variation_id" } } }'

Did this page help you?