POST
Get a recommendation decision
You send the moment and its context; a recommendation comes back with every product complete, ready to display without another call. An empty list is valid too, and it carries the reason.

The six moments

If the moment’s requirement is missing, the response is 400 invalid_request and pointer names the field. A context_item_id in a cart moment is echoed in context, but it doesn’t change the recommendation.

The request doesn’t pick the store

There is no store_id: the server takes the store from the key and checks that connection_id belongs to it. No body field reads someone else’s data.

The visitor

visitor is optional: { visitor_id, session_id? }, shaped vis_… and ses_…. It never makes the request fail: with another shape, it’s dropped and not stored. It is never shopper data: Visitor and context. Every request is recorded with its visitor and the recommendation it returned: that’s how a click is later tied to it.

What it returns

The response is the recommendation (in the API, Decision: the list of products recommended for that moment).
  • decision_id: the recommendation’s id, unique per response. Two identical requests are two recommendations.
  • request_id: the same value as the X-Request-ID header.
  • context: what the recommendation started from. shooter carries the starting product, and cart_items, the cart as it arrived.
  • results[]: item_id, variant_id?, position, reason_codes[] and product, complete: item, taxonomy, variants with prices and availability.
There is no score and no engine suggestion id. The ranking is the position, and a contract test fails if a score ever shows up.
product is optional: if it couldn’t be read, the result goes out without it, and you can resolve it with read the catalog. item.description travels as the platform sends it; Tiendanube sends HTML, so sanitize it. reason_codes shows up on the recommendation and on each result: one explains the whole response, the other that position. On an empty list, it says what happened:

cart_items is an array of objects

Optional (omitted means []), but never null. Each element is { item_id, variant_id, quantity }, with quantity ≥ 1. Past the limit, the response is cart_items_limit_exceeded, with max_items_per_cart and actual_items.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

Every field but the connection, the placement and the surface is optional in the schema, and the surface decides what is needed. pdp, cart and checkout need a shooter (context_item_id) or at least one cart item. success-page, in-checkout and carousel need at least one cart item; a shooter sent with them is recorded and echoed but does not drive the engine. A request with neither is a 400. cart_id is the store's own id for the cart and belongs with cart_items: send it whenever the cart is not empty. It is not required by the schema — a request without it is served normally — but the decision it produces cannot be tied back to a sale.

connection_id
string
required
Minimum string length: 1
placement_key
string
required
Minimum string length: 1
surface
enum<string>
required

The storefront moment that asks for recommendations. Three moments start from a product the shopper is looking at or just added (the shooter, context_item_id): pdp (product page), cart (right after adding to the cart) and checkout (when the purchase starts). The other three read only the cart: success-page (purchase finished), in-checkout (inside the checkout) and carousel (the cart page).

Available options:
pdp,
cart,
checkout,
success-page,
in-checkout,
carousel
Minimum string length: 1
context_item_id
string

The shooter item (the product the moment starts from), when the moment has one.

Minimum string length: 1
cart_items
object[]

The cart as the storefront sees it. Omitted means empty.

cart_id
string

The store's own id for this cart. Send it whenever cart_items is not empty: it is what ties the sale back to the offer once the order comes in through the webhook. A request that carries a cart without it still answers 200 and still serves a recommendation, but that decision cannot be attributed to a sale later.

Required string length: 1 - 256
visitor
object

Pseudonymous identity of the browser that asks. The storefront SDK creates and keeps it; it carries no personal data and must never be an email, a phone number or a platform customer id. Sending it is optional, and a visitor that does not match this shape never fails the request: the server drops it, answers without it and does not store it.

client
object

What the storefront SDK can read in the browser about the request. Every field is optional and sending it never fails the request: a context the server cannot read is dropped and the recommendation is served anyway. The server also records the client IP, User-Agent, Accept-Language, Origin and Referer from the HTTP request; none of this is returned.

Response

Recommendation decision

decision_id
string
required

Unique per response. Signals about what was shown reference it.

Minimum string length: 1
request_id
string
required

The same value as the X-Request-ID response header.

Minimum string length: 1
store_id
string
required
Minimum string length: 1
connection_id
string
required
Minimum string length: 1
placement_key
string
required
Minimum string length: 1
surface
enum<string>
required

The storefront moment that asks for recommendations. Three moments start from a product the shopper is looking at or just added (the shooter, context_item_id): pdp (product page), cart (right after adding to the cart) and checkout (when the purchase starts). The other three read only the cart: success-page (purchase finished), in-checkout (inside the checkout) and carousel (the cart page).

Available options:
pdp,
cart,
checkout,
success-page,
in-checkout,
carousel
Minimum string length: 1
context
object
required

What the decision was taken from, echoed so the storefront does not have to remember it.

results
object[]
required
reason_codes
string[]
required
Minimum string length: 1
generated_at
string<date-time>
required
visitor
object

Pseudonymous identity of the browser that asks. The storefront SDK creates and keeps it; it carries no personal data and must never be an email, a phone number or a platform customer id. Sending it is optional, and a visitor that does not match this shape never fails the request: the server drops it, answers without it and does not store it.