Recently Viewed
Recently viewed
POST /api/v1/indexes/{index_name}/recommendations/recently-viewed
Purpose
Return the products a shopper has viewed, most recent first, so they can pick up where they left off.
Background
The shelf is read from the shopper's history in the event tracking pixel. By default, a product counts as viewed when the pixel recorded a ClickEvent for it. Each document appears once, at the time the shopper last interacted with it. The shelf is a history, not a ranking: it is ordered by recency, and ranking settings, merchandising rules and personalisation do not apply.
When to use
- Product detail pages: A "Recently viewed" carousel, excluding the product on the page
- Homepage and cart: Bring returning shoppers back to products they were considering
- Search and collection pages: A side rail of the shopper's recent products
Example (cURL)
curl -X POST "https://ecom.marqo-ep.ai/api/v1/indexes/product-catalog/recommendations/recently-viewed" \
-H "x-marqo-index-id: ${MARQO_INDEX_ID}" \
-H "Content-Type: application/json" \
-d '{
"userId": "8d0f6c1e-3b7a-4f2e-9c55-1a2b3c4d5e6f",
"excludeDocIds": ["sku_51230"],
"filter": "in_stock:true",
"limit": 12
}'
Prerequisites
The event tracking pixel must be installed on the store and personalisation must be enabled for the index. Otherwise every request returns a 400 (see Errors).
Parameters
Filters use the Marqo Filter DSL. The endpoint uses strict validation: any unrecognised parameter returns a 400 error.
| Name | Type | Required | Description | Example |
|---|---|---|---|---|
| userId | string | yes | Shopper identifier, as sent to the event tracking pixel. Use an anonymous browser identifier, never an email address or customer number: the shelf can be read with your public index ID. | "8d0f6c1e-…" |
| sessionId | string | no | Limit the shelf to products viewed in this session. Default: the shopper's whole history. | "xyz789" |
| eventTypes | array[string] | no | Interactions that count as a view: ClickEvent, AddToCartEvent or both. Defaults to ["ClickEvent"]. Purchases are not accepted. | ["ClickEvent", "AddToCartEvent"] |
| excludeDocIds | array[string] | no | Document IDs (_id) to leave out, such as the product on the current page. | ["sku_51230"] |
| limit | integer | no | Max number of results to return, from 1 to 500. Defaults to 10. | 12 |
| filter | string | no | Server-side constraints applied to the shopper's products (e.g. hide out-of-stock items). See Marqo Filter DSL. | "in_stock:true" |
| attributesToRetrieve | array[string] | no | Attributes to return for each document. If omitted, the attribute list configured for the index is returned, the same default as search. | ["title", "price", "image_url"] |
If your index collapses variants (see Deduping Variants), each product appears once, at its most recent view.
Products removed from the index or excluded by filter, and variants collapsed into a more recent view, are dropped, so the shelf can be shorter than limit. There is no offset.
Response (example)
{
"hits": [
{
"_id": "sku_40118",
"_score": 0,
"title": "Linen Duvet Cover - Sage",
"price": 249.0,
"image_url": "https://cdn.example.com/sku_40118.jpg",
"parentProductId": "prod_40100",
"_lastInteractedAt": 1761456000000,
"_eventType": "ClickEvent"
}
],
"processingTimeMs": 6,
"limit": 12
}
| Field | Type | Description |
|---|---|---|
| hits | array[object] | The shopper's products, most recent first, each with _id and the retrieved attributes. _score has no meaning on this endpoint. |
| hits[]._lastInteractedAt | integer | When the shopper last interacted with the product, in milliseconds since the Unix epoch. |
| hits[]._eventType | string | The type of that interaction: ClickEvent or AddToCartEvent. |
| processingTimeMs | integer | Server processing time in milliseconds. |
| limit | integer | The limit applied to the request. |
| Header | Description |
|---|---|
x-marqo-results-personalized | Always present. true when the shelf has hits, otherwise false. |
Shoppers with no history
When the shopper has no matching views, or their history cannot be fetched in time, the endpoint returns 200 with an empty hits array. There is no fallback shelf: hide the carousel when hits is empty.
Errors
Error responses have the body {"error": "<message>"}.
| Status | Message |
|---|---|
| 400 | Parameter 'userId' is required and must be a non-empty string |
| 400 | Personalized recommendations not configured, please contact Marqo to enable them when the index has no event tracking pixel or personalisation is switched off |
| 400 | Parameter 'eventTypes' does not accept PurchaseEvent; allowed values are ClickEvent, AddToCartEvent |
| 400 | Parameter 'eventTypes' must be a non-empty array |
| 400 | Parameter 'limit' must be at least 1 or Parameter 'limit' must be less than or equal to 500 |
| 400 | Unrecognized param(s): '<name>' for any parameter not listed above |
| 400 | A message from the request validator when a value fails its constraint, for example an eventTypes entry that is not ClickEvent or AddToCartEvent |
| 400 | Search failed: <reason> when the underlying search rejects the request, for example an invalid filter |