curl --request POST \
--url https://api.example.com/api/operation/similar-to \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Tenantid: <api-key>' \
--data '
{
"sessionId": "session-123",
"visitorId": "visitor-456",
"content": "Find products similar to this one",
"requestOrigin": "Operation",
"pageSize": 8,
"operationHideAiMessage": false,
"operationReturnFullProductInfo": false,
"chatMetadata": {
"productId": "product-123",
"websiteUrl": "https://shop.example.com/products/product-123"
}
}
'import requests
url = "https://api.example.com/api/operation/similar-to"
payload = {
"sessionId": "session-123",
"visitorId": "visitor-456",
"content": "Find products similar to this one",
"requestOrigin": "Operation",
"pageSize": 8,
"operationHideAiMessage": False,
"operationReturnFullProductInfo": False,
"chatMetadata": {
"productId": "product-123",
"websiteUrl": "https://shop.example.com/products/product-123"
}
}
headers = {
"Authorization": "Bearer <token>",
"Tenantid": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
Tenantid: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
sessionId: 'session-123',
visitorId: 'visitor-456',
content: 'Find products similar to this one',
requestOrigin: 'Operation',
pageSize: 8,
operationHideAiMessage: false,
operationReturnFullProductInfo: false,
chatMetadata: {
productId: 'product-123',
websiteUrl: 'https://shop.example.com/products/product-123'
}
})
};
fetch('https://api.example.com/api/operation/similar-to', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/operation/similar-to",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sessionId' => 'session-123',
'visitorId' => 'visitor-456',
'content' => 'Find products similar to this one',
'requestOrigin' => 'Operation',
'pageSize' => 8,
'operationHideAiMessage' => false,
'operationReturnFullProductInfo' => false,
'chatMetadata' => [
'productId' => 'product-123',
'websiteUrl' => 'https://shop.example.com/products/product-123'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Tenantid: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/operation/similar-to"
payload := strings.NewReader("{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Tenantid", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/operation/similar-to")
.header("Authorization", "Bearer <token>")
.header("Tenantid", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/operation/similar-to")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Tenantid"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}"
response = http.request(request)
puts response.read_body"data: {\"chatStream\":\"I found several products that match your request.\"}\n\ndata: {\"data\":{\"responseType\":\"ProductSearch\",\"sessionId\":\"session-123\",\"visitorId\":\"visitor-456\",\"responsePayload\":[{\"id\":\"product-123\"}],\"hasMoreProducts\":false,\"total\":1}}\n\n""Tenant ID Invalid.""Tenant tenant-123 not found #000"Find similar products
Find catalogue products similar to a base product.
curl --request POST \
--url https://api.example.com/api/operation/similar-to \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Tenantid: <api-key>' \
--data '
{
"sessionId": "session-123",
"visitorId": "visitor-456",
"content": "Find products similar to this one",
"requestOrigin": "Operation",
"pageSize": 8,
"operationHideAiMessage": false,
"operationReturnFullProductInfo": false,
"chatMetadata": {
"productId": "product-123",
"websiteUrl": "https://shop.example.com/products/product-123"
}
}
'import requests
url = "https://api.example.com/api/operation/similar-to"
payload = {
"sessionId": "session-123",
"visitorId": "visitor-456",
"content": "Find products similar to this one",
"requestOrigin": "Operation",
"pageSize": 8,
"operationHideAiMessage": False,
"operationReturnFullProductInfo": False,
"chatMetadata": {
"productId": "product-123",
"websiteUrl": "https://shop.example.com/products/product-123"
}
}
headers = {
"Authorization": "Bearer <token>",
"Tenantid": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
Tenantid: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
sessionId: 'session-123',
visitorId: 'visitor-456',
content: 'Find products similar to this one',
requestOrigin: 'Operation',
pageSize: 8,
operationHideAiMessage: false,
operationReturnFullProductInfo: false,
chatMetadata: {
productId: 'product-123',
websiteUrl: 'https://shop.example.com/products/product-123'
}
})
};
fetch('https://api.example.com/api/operation/similar-to', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/operation/similar-to",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sessionId' => 'session-123',
'visitorId' => 'visitor-456',
'content' => 'Find products similar to this one',
'requestOrigin' => 'Operation',
'pageSize' => 8,
'operationHideAiMessage' => false,
'operationReturnFullProductInfo' => false,
'chatMetadata' => [
'productId' => 'product-123',
'websiteUrl' => 'https://shop.example.com/products/product-123'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Tenantid: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/operation/similar-to"
payload := strings.NewReader("{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Tenantid", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/operation/similar-to")
.header("Authorization", "Bearer <token>")
.header("Tenantid", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/operation/similar-to")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Tenantid"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sessionId\": \"session-123\",\n \"visitorId\": \"visitor-456\",\n \"content\": \"Find products similar to this one\",\n \"requestOrigin\": \"Operation\",\n \"pageSize\": 8,\n \"operationHideAiMessage\": false,\n \"operationReturnFullProductInfo\": false,\n \"chatMetadata\": {\n \"productId\": \"product-123\",\n \"websiteUrl\": \"https://shop.example.com/products/product-123\"\n }\n}"
response = http.request(request)
puts response.read_body"data: {\"chatStream\":\"I found several products that match your request.\"}\n\ndata: {\"data\":{\"responseType\":\"ProductSearch\",\"sessionId\":\"session-123\",\"visitorId\":\"visitor-456\",\"responsePayload\":[{\"id\":\"product-123\"}],\"hasMoreProducts\":false,\"total\":1}}\n\n""Tenant ID Invalid.""Tenant tenant-123 not found #000"intent field.
Identifying the base product
For the most deterministic result, provide the base product ID inchatMetadata.productId. The API can also attempt to resolve a product from its title or from the natural-language content.
productIds is not used to select the base product for this operation.
Request example
curl --no-buffer --request POST \
"$PREEZIE_API_URL/api/operation/similar-to" \
--header "Authorization: Bearer $PREEZIE_OPERATION_TOKEN" \
--header "Tenantid: $PREEZIE_TENANT_ID" \
--header "Content-Type: application/json" \
--data '{
"sessionId": "session-123",
"visitorId": "visitor-456",
"content": "Find products similar to this one",
"requestOrigin": "Operation",
"pageSize": 8,
"operationHideAiMessage": false,
"operationReturnFullProductInfo": false,
"chatMetadata": {
"productId": "product-123",
"title": "Lightweight Trail Runner",
"websiteUrl": "https://shop.example.com/products/product-123"
}
}'
Behaviour
- The base product is excluded from the returned similar products.
pageSizecontrols the requested number of similar products.- If the request matches multiple possible base products, the stream may ask the shopper to confirm which product they mean.
- If the base product cannot be resolved, the stream returns a no-product response rather than running a similarity search.
Streaming response
The response usestext/event-stream. Each data: line contains one JSON message:
data: {"chatStream":"Here are some similar options."}
data: {"data":{"responseType":"SimilarProductEnquiry","responsePayload":[{"id":"product-456"}]}}
operationHideAiMessage to true to omit chatStream messages. Set operationReturnFullProductInfo to true to return full product objects instead of ID-only objects in responsePayload.Authorizations
A short-lived HS256 operation token. Its tenantId claim must exactly match the Tenantid header. Mint this token on a trusted server; never expose the tenant signing credential in browser code.
The preezie tenant identifier. This value identifies the catalogue and is not a secret.
Body
Natural-language request that guides the selected operation.
1"Show me lightweight black running shoes"
Conversation session identifier. Reuse it for related requests.
"session-123"
Stable identifier for the shopper or visitor.
"visitor-456"
Legacy top-level URL field. Use chatMetadata.websiteUrl for the current page context.
Optional context from the current product or page.
Show child attributes
Show child attributes
Source of the request. Use Operation for these endpoints.
Operation Explicit product identifiers consumed by operations such as comparison. For similarity and bundling, identify the base product with chatMetadata.productId instead.
Maximum number of product results requested. When omitted, the tenant's configured default is used.
x >= 1When true, suppresses chatStream events and returns only non-chat stream events.
When false, products in a conversation response payload are reduced to {"id": "..."} objects. When true, the full product objects are returned.
Response
A server-sent event stream. Each message is written as data: <JSON> followed by a blank line. The JSON payload contains one response key. operationHideAiMessage removes chatStream events; operationReturnFullProductInfo controls whether product payloads contain IDs only or full product objects.
A sequence of SSE messages whose data values follow the StreamEvent schema.
