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
keyandsectionquery parameters.sectiondefaults toProducts. 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 requiresrecommendations(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"
}| Field | Description |
|---|---|
page_id | The 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_name | A human-readable label for dashboards and reporting, from 2 to 100 characters. |
page_type | The role the page plays in your storefront. See Page types. |
pods | The pods on the page, in the order a shopper sees them. See Pod order. |
metadata_json.page_config.deduplication_key | What counts as a duplicate across the page's pods. See Deduplication key. |
created_at, updated_at | When 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.
| Value | Page |
|---|---|
pdp | Product detail page |
plp | Product listing page, including search results pages |
home | Homepage or other landing page |
cart | Cart page |
atc | Add-to-cart confirmation or mini-cart |
checkout | Checkout flow |
order_confirm | Order confirmation page |
empty_cart | Empty cart state |
other | Any 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.
| Value | A product is a duplicate when an earlier result has |
|---|---|
item_id (default) | the same item_id, whatever its variation |
item_and_variation_id | the 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
| Method | Path | Behavior |
|---|---|---|
GET | /v1/recommendation_pages | List pages, optionally only those that use a pod. |
POST | /v1/recommendation_pages | Create 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
PUT | PATCH | |
|---|---|---|
display_name, page_type | Required | Changed only if supplied |
pods | Required; replaces the complete list | If supplied, replaces the complete list; if omitted, left unchanged |
metadata_json | Replaced: any setting you leave out, or the whole field, returns to its default | Merged 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 at1) oroffset, but not both, and set the page size withnum_results_per_page(default20, maximum100). - Pass
pod_idto return only the pages whosepodsinclude 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]§ion=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:
- Call
GET /v1/recommendation_pages?pod_id=<pod_id>to fetch the blocking pages with their currentpods. - For each page,
PATCHthe page with itspodslist 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. - Retry the pod delete.
Errors
Errors use the same shape as other configuration endpoints:
{ "message": "<description>" }| Status | Cause | Message |
|---|---|---|
400 | Invalid page_id | page_id: Must be a lowercase slug containing only letters, numbers, underscores, and hyphens. |
400 | display_name too short | display_name: Must be at least 2 characters. |
400 | display_name too long | display_name: Must be at most 100 characters. |
400 | Invalid page_type | page_type: Must be one of pdp, plp, home, cart, atc, checkout, order_confirm, empty_cart, other. |
400 | Invalid deduplication_key | metadata_json.page_config.deduplication_key: Must be one of item_id, item_and_variation_id. |
400 | Too many pods | pods: A page may contain at most 5 pods; 6 were supplied. |
400 | Repeated pod | pods: Pod "similar_items" appears more than once at index 2. |
404 | Unknown pod | pods[1].pod_id: Recommendation pod "unknown_pod" was not found for section "Products". |
404 | Unknown page | Recommendation page "pdp_b2c" was not found. |
409 | Page already exists (POST) | Page "pdp_b2c" already exists for section "Products". Use PUT to replace it. |
409 | Pod 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]§ion=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]§ion=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]§ion=Products" \
-d '{ "metadata_json": { "page_config": { "deduplication_key": "item_and_variation_id" } } }'Updated about 3 hours ago