Record what the shopper did with a decision
curl --request POST \
--url https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"signals": [
{
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"type": "impression",
"occurred_at": "2026-09-17T12:00:00Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"position": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
},
"client": {
"page_url": "https://tienda-demo.example/productos/remera",
"languages": [
"es-AR"
],
"timezone": "America/Argentina/Buenos_Aires",
"viewport": {
"width": 390,
"height": 844,
"pixel_ratio": 3
}
}
},
{
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"type": "add_to_cart",
"occurred_at": "2026-09-17T12:00:11Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"item_id": "itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8",
"variant_id": "var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1",
"position": 1,
"quantity": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
}
}
]
}
'import requests
url = "https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals"
payload = { "signals": [
{
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"type": "impression",
"occurred_at": "2026-09-17T12:00:00Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"position": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
},
"client": {
"page_url": "https://tienda-demo.example/productos/remera",
"languages": ["es-AR"],
"timezone": "America/Argentina/Buenos_Aires",
"viewport": {
"width": 390,
"height": 844,
"pixel_ratio": 3
}
}
},
{
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"type": "add_to_cart",
"occurred_at": "2026-09-17T12:00:11Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"item_id": "itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8",
"variant_id": "var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1",
"position": 1,
"quantity": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
}
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
signals: [
{
signal_id: 'sig_01JB3Z8YQK7N2VME5T4RD9WX0A',
type: 'impression',
occurred_at: '2026-09-17T12:00:00Z',
decision_id: 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
position: 1,
visitor: {visitor_id: 'vis_Q2x9mT4pL7rK1sV8', session_id: 'ses_Hn3bW6yZ0cF5dJ2e'},
client: {
page_url: 'https://tienda-demo.example/productos/remera',
languages: ['es-AR'],
timezone: 'America/Argentina/Buenos_Aires',
viewport: {width: 390, height: 844, pixel_ratio: 3}
}
},
{
signal_id: 'sig_01JB3Z9C6M0PT8RHY2KWFA5N3B',
type: 'add_to_cart',
occurred_at: '2026-09-17T12:00:11Z',
decision_id: 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
item_id: 'itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8',
variant_id: 'var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1',
position: 1,
quantity: 1,
visitor: {visitor_id: 'vis_Q2x9mT4pL7rK1sV8', session_id: 'ses_Hn3bW6yZ0cF5dJ2e'}
}
]
})
};
fetch('https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals', 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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals",
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([
'signals' => [
[
'signal_id' => 'sig_01JB3Z8YQK7N2VME5T4RD9WX0A',
'type' => 'impression',
'occurred_at' => '2026-09-17T12:00:00Z',
'decision_id' => 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
'position' => 1,
'visitor' => [
'visitor_id' => 'vis_Q2x9mT4pL7rK1sV8',
'session_id' => 'ses_Hn3bW6yZ0cF5dJ2e'
],
'client' => [
'page_url' => 'https://tienda-demo.example/productos/remera',
'languages' => [
'es-AR'
],
'timezone' => 'America/Argentina/Buenos_Aires',
'viewport' => [
'width' => 390,
'height' => 844,
'pixel_ratio' => 3
]
]
],
[
'signal_id' => 'sig_01JB3Z9C6M0PT8RHY2KWFA5N3B',
'type' => 'add_to_cart',
'occurred_at' => '2026-09-17T12:00:11Z',
'decision_id' => 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
'item_id' => 'itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8',
'variant_id' => 'var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1',
'position' => 1,
'quantity' => 1,
'visitor' => [
'visitor_id' => 'vis_Q2x9mT4pL7rK1sV8',
'session_id' => 'ses_Hn3bW6yZ0cF5dJ2e'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals"
payload := strings.NewReader("{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"results": [
{
"index": 0,
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"status": "accepted"
},
{
"index": 1,
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"status": "duplicate"
},
{
"index": 2,
"signal_id": "sig_01JB3ZAD7N1QU9SJZ3LXGB6P4C",
"status": "rejected",
"reason": "unknown_decision"
}
]
}{
"type": "https://api.crossup.ai/salespilot/errors/invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"errors": [
{
"code": "<string>",
"detail": "<string>",
"pointer": "<string>"
}
]
}{
"type": "https://api.crossup.ai/salespilot/errors/unauthorized",
"title": "Authentication required",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/forbidden-connection",
"title": "Connection is not accessible",
"status": 403,
"detail": "<string>",
"code": "forbidden_connection",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/signal-batch-limit-exceeded",
"title": "Signal batch limit exceeded",
"status": 422,
"detail": "<string>",
"code": "signal_batch_limit_exceeded",
"request_id": "<string>",
"max_signals_per_batch": 50,
"actual_signals": 2
}{
"type": "https://api.crossup.ai/salespilot/errors/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "<string>",
"code": "rate_limited",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/internal-error",
"title": "Internal server error",
"status": 500,
"detail": "<string>",
"code": "internal_error",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/signals-unavailable",
"title": "Signals cannot be recorded right now",
"status": 503,
"detail": "<string>",
"code": "signals_unavailable",
"request_id": "<string>"
}Operaciones
Registrar señales del storefront
Guarda lo que el comprador hizo con una recomendación ya servida y lo reenvía al motor, que sigue siendo el dueño de las interacciones.
POST
/
v1
/
connections
/
{connection_id}
/
storefront-signals
Record what the shopper did with a decision
curl --request POST \
--url https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"signals": [
{
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"type": "impression",
"occurred_at": "2026-09-17T12:00:00Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"position": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
},
"client": {
"page_url": "https://tienda-demo.example/productos/remera",
"languages": [
"es-AR"
],
"timezone": "America/Argentina/Buenos_Aires",
"viewport": {
"width": 390,
"height": 844,
"pixel_ratio": 3
}
}
},
{
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"type": "add_to_cart",
"occurred_at": "2026-09-17T12:00:11Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"item_id": "itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8",
"variant_id": "var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1",
"position": 1,
"quantity": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
}
}
]
}
'import requests
url = "https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals"
payload = { "signals": [
{
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"type": "impression",
"occurred_at": "2026-09-17T12:00:00Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"position": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
},
"client": {
"page_url": "https://tienda-demo.example/productos/remera",
"languages": ["es-AR"],
"timezone": "America/Argentina/Buenos_Aires",
"viewport": {
"width": 390,
"height": 844,
"pixel_ratio": 3
}
}
},
{
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"type": "add_to_cart",
"occurred_at": "2026-09-17T12:00:11Z",
"decision_id": "dec_7k2m9q4v8x1z5c3b6n0j7h2f4d",
"item_id": "itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8",
"variant_id": "var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1",
"position": 1,
"quantity": 1,
"visitor": {
"visitor_id": "vis_Q2x9mT4pL7rK1sV8",
"session_id": "ses_Hn3bW6yZ0cF5dJ2e"
}
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
signals: [
{
signal_id: 'sig_01JB3Z8YQK7N2VME5T4RD9WX0A',
type: 'impression',
occurred_at: '2026-09-17T12:00:00Z',
decision_id: 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
position: 1,
visitor: {visitor_id: 'vis_Q2x9mT4pL7rK1sV8', session_id: 'ses_Hn3bW6yZ0cF5dJ2e'},
client: {
page_url: 'https://tienda-demo.example/productos/remera',
languages: ['es-AR'],
timezone: 'America/Argentina/Buenos_Aires',
viewport: {width: 390, height: 844, pixel_ratio: 3}
}
},
{
signal_id: 'sig_01JB3Z9C6M0PT8RHY2KWFA5N3B',
type: 'add_to_cart',
occurred_at: '2026-09-17T12:00:11Z',
decision_id: 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
item_id: 'itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8',
variant_id: 'var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1',
position: 1,
quantity: 1,
visitor: {visitor_id: 'vis_Q2x9mT4pL7rK1sV8', session_id: 'ses_Hn3bW6yZ0cF5dJ2e'}
}
]
})
};
fetch('https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals', 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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals",
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([
'signals' => [
[
'signal_id' => 'sig_01JB3Z8YQK7N2VME5T4RD9WX0A',
'type' => 'impression',
'occurred_at' => '2026-09-17T12:00:00Z',
'decision_id' => 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
'position' => 1,
'visitor' => [
'visitor_id' => 'vis_Q2x9mT4pL7rK1sV8',
'session_id' => 'ses_Hn3bW6yZ0cF5dJ2e'
],
'client' => [
'page_url' => 'https://tienda-demo.example/productos/remera',
'languages' => [
'es-AR'
],
'timezone' => 'America/Argentina/Buenos_Aires',
'viewport' => [
'width' => 390,
'height' => 844,
'pixel_ratio' => 3
]
]
],
[
'signal_id' => 'sig_01JB3Z9C6M0PT8RHY2KWFA5N3B',
'type' => 'add_to_cart',
'occurred_at' => '2026-09-17T12:00:11Z',
'decision_id' => 'dec_7k2m9q4v8x1z5c3b6n0j7h2f4d',
'item_id' => 'itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8',
'variant_id' => 'var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1',
'position' => 1,
'quantity' => 1,
'visitor' => [
'visitor_id' => 'vis_Q2x9mT4pL7rK1sV8',
'session_id' => 'ses_Hn3bW6yZ0cF5dJ2e'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals"
payload := strings.NewReader("{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://salespilot.crossup.ai/v1/connections/{connection_id}/storefront-signals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"signals\": [\n {\n \"signal_id\": \"sig_01JB3Z8YQK7N2VME5T4RD9WX0A\",\n \"type\": \"impression\",\n \"occurred_at\": \"2026-09-17T12:00:00Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"position\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n },\n \"client\": {\n \"page_url\": \"https://tienda-demo.example/productos/remera\",\n \"languages\": [\n \"es-AR\"\n ],\n \"timezone\": \"America/Argentina/Buenos_Aires\",\n \"viewport\": {\n \"width\": 390,\n \"height\": 844,\n \"pixel_ratio\": 3\n }\n }\n },\n {\n \"signal_id\": \"sig_01JB3Z9C6M0PT8RHY2KWFA5N3B\",\n \"type\": \"add_to_cart\",\n \"occurred_at\": \"2026-09-17T12:00:11Z\",\n \"decision_id\": \"dec_7k2m9q4v8x1z5c3b6n0j7h2f4d\",\n \"item_id\": \"itm_01JB2XQ7W9E4R6T8Y0U2I4O6P8\",\n \"variant_id\": \"var_01JB2XQ7W9E4R6T8Y0U2I4O6Q1\",\n \"position\": 1,\n \"quantity\": 1,\n \"visitor\": {\n \"visitor_id\": \"vis_Q2x9mT4pL7rK1sV8\",\n \"session_id\": \"ses_Hn3bW6yZ0cF5dJ2e\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"results": [
{
"index": 0,
"signal_id": "sig_01JB3Z8YQK7N2VME5T4RD9WX0A",
"status": "accepted"
},
{
"index": 1,
"signal_id": "sig_01JB3Z9C6M0PT8RHY2KWFA5N3B",
"status": "duplicate"
},
{
"index": 2,
"signal_id": "sig_01JB3ZAD7N1QU9SJZ3LXGB6P4C",
"status": "rejected",
"reason": "unknown_decision"
}
]
}{
"type": "https://api.crossup.ai/salespilot/errors/invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"errors": [
{
"code": "<string>",
"detail": "<string>",
"pointer": "<string>"
}
]
}{
"type": "https://api.crossup.ai/salespilot/errors/unauthorized",
"title": "Authentication required",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/forbidden-connection",
"title": "Connection is not accessible",
"status": 403,
"detail": "<string>",
"code": "forbidden_connection",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/signal-batch-limit-exceeded",
"title": "Signal batch limit exceeded",
"status": 422,
"detail": "<string>",
"code": "signal_batch_limit_exceeded",
"request_id": "<string>",
"max_signals_per_batch": 50,
"actual_signals": 2
}{
"type": "https://api.crossup.ai/salespilot/errors/rate-limited",
"title": "Too many requests",
"status": 429,
"detail": "<string>",
"code": "rate_limited",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/internal-error",
"title": "Internal server error",
"status": 500,
"detail": "<string>",
"code": "internal_error",
"request_id": "<string>"
}{
"type": "https://api.crossup.ai/salespilot/errors/signals-unavailable",
"title": "Signals cannot be recorded right now",
"status": 503,
"detail": "<string>",
"code": "signals_unavailable",
"request_id": "<string>"
}Ésta registra lo que hizo el comprador. Para actualizar el catálogo, la
operación es Ingerir un evento de catálogo.
Una señal cuelga de una recomendación
Toda señal lleva eldecision_id: el id de la recomendación que devolvió
getRecommendations. En la API ese objeto es
Decision, la lista de productos recomendados para ese momento. El id es único
por respuesta: dos impresiones de la misma oferta son dos recomendaciones distintas.
La señal no lleva los ids del motor: el servidor los guardó al servir la
recomendación. Si viajaran desde el navegador, cualquiera con la clave pública
podría apuntar una interacción a otra oferta.
decision_id tiene que existir y ser de esta conexión. Si no, la
respuesta es rejected con reason: unknown_decision, igual que para un id
que nunca existió: así nadie puede sondear recomendaciones ajenas.
El lote se contesta señal por señal
Hasta 50 señales por pedido; más essignal_batch_limit_exceeded y no se guarda ninguna. La
respuesta es 202 con un resultado por posición:
status | Qué pasó |
|---|---|
accepted | Se guardó y quedó encolada para el motor |
duplicate | Ese signal_id ya estaba. No se creó trabajo nuevo |
rejected | No se guardó. reason dice por qué |
Reenviar el mismo lote es seguro
signal_id lo genera el SDK y es estable entre reintentos: la segunda
llegada contesta duplicate sin trabajo nuevo.
Qué campos lleva cada tipo
type | item_id | quantity | order_external_id |
|---|---|---|---|
impression | — (es de la recomendación entera) | — | — |
click | obligatorio | — | — |
add_to_cart | obligatorio | opcional: se suma a la línea (1 si falta) | — |
remove_from_cart | obligatorio | — | — |
update_quantity | obligatorio | obligatoria: fija la línea; 0 la saca | — |
purchase | obligatorio | opcional | opcional |
dismiss | obligatorio | — | — |
item_id y variant_id son ids canónicos (itm_, var_), los mismos de
la recomendación. El servidor los traduce a los ids de la tienda.
Cada señal es un cambio, no el carrito entero
El servidor lleva lo que el comprador tiene de cada recomendación: una línea por ítem y variante.add_to_cart suma, update_quantity fija, remove_from_cart
saca. Cada señal manda sólo su cambio y el servidor arma el estado acumulado:
una señal perdida no borra lo anterior, y un reenvío no suma dos veces.
El 503 pide reintentar
Si el registro no está disponible, la respuesta es503 signals_unavailable y
no se guardó ninguna señal del lote. El SDK guarda el lote y lo vuelve a
mandar. Una recomendación, en cambio, se sirve aunque el registro falle.
Qué guarda el servidor
Para auditar el pedido: IP,User-Agent, Accept-Language, Origin,
Referer y el client del SDK. Nada de eso vuelve en la respuesta.
El contrato acota la forma de visitor: no puede ser un mail ni un teléfono.
Un visitor o un client mal formado se descarta: la señal se guarda sin
él, con un warning sin el valor.Autorizaciones
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Parámetros de ruta
CrossUp connection identifier.
Minimum string length:
1Cuerpo
application/json
Required array length:
1 - 50 elementsShow child attributes
Show child attributes
Respuesta
The batch was answered signal by signal
Show child attributes
Show child attributes