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>"
}Operações
Registrar sinais do storefront
Guarda o que o comprador fez com uma recomendação já servida e o reenvia ao motor, que continua sendo o dono das interações.
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>"
}Esta registra o que o comprador fez. Para atualizar o catálogo, a
operação é Ingerir um evento de catálogo.
Um sinal pertence a uma recomendação
Todo sinal leva odecision_id: o id da recomendação que
getRecommendations devolveu. Na API esse objeto é
Decision, a lista de produtos recomendados para aquele momento. O id é único
por resposta: duas impressões da mesma oferta são duas recomendações diferentes.
O sinal não leva os ids do motor: o servidor os guardou ao servir a
recomendação. Se viajassem do navegador, qualquer um com a chave pública poderia
apontar uma interação para outra oferta.
decision_id tem que existir e ser desta conexão. Se não, a resposta é
rejected com reason: unknown_decision, igual a um id que nunca existiu:
assim ninguém consegue sondar recomendações alheias.
O lote é respondido sinal por sinal
Até 50 sinais por requisição; mais ésignal_batch_limit_exceeded e nenhum é salvo. A resposta é
202 com um resultado por posição:
status | O que aconteceu |
|---|---|
accepted | Foi salvo e entrou na fila para o motor |
duplicate | Esse signal_id já existia. Nenhum trabalho novo |
rejected | Não foi salvo. reason diz por quê |
Reenviar o mesmo lote é seguro
signal_id é gerado pelo SDK e é estável entre tentativas: a segunda
chegada responde duplicate sem trabalho novo.
Que campos cada tipo leva
type | item_id | quantity |
|---|---|---|
impression | — (é da recomendação inteira) | — |
click | obrigatório | — |
add_to_cart | obrigatório | opcional: soma à linha (1 se faltar) |
remove_from_cart | obrigatório | — |
update_quantity | obrigatório | obrigatória: fixa a linha; 0 a remove |
checkout_started | — (é da recomendação inteira) | — |
dismiss | obrigatório | — |
cart_id vai opcional em todos: o id do carrinho na sua loja. É o que liga a
recomendação ao pedido quando ele entra pela sua plataforma. Não existe um sinal
de compra: Sinais e atribuição.
item_id e variant_id são ids canônicos (itm_, var_), os mesmos da
recomendação. O servidor os traduz para os ids da loja.
Cada sinal é uma mudança, não o carrinho inteiro
O servidor mantém o que o comprador tem de cada recomendação: uma linha por item e variante.add_to_cart soma, update_quantity fixa, remove_from_cart
remove. Cada sinal manda só a sua mudança e o servidor monta o estado
acumulado: um sinal perdido não apaga o anterior, e um reenvio não soma duas
vezes.
O 503 pede nova tentativa
Se o registro não está disponível, a resposta é503 signals_unavailable e
nenhum sinal do lote foi salvo. O SDK guarda o lote e o manda de novo. Uma
recomendação, por outro lado, é servida mesmo se o registro falhar.
O que o servidor guarda
Para auditar a requisição: IP,User-Agent, Accept-Language, Origin,
Referer e o client do SDK. Nada disso volta na resposta.
O contrato limita a forma de visitor: não pode ser um e-mail nem um telefone.
Um visitor ou um client malformado é descartado: o sinal é salvo sem
ele, com um warning sem o valor.Autorizações
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Parâmetros de caminho
CrossUp connection identifier.
Minimum string length:
1Corpo
application/json
Required array length:
1 - 50 elementsShow child attributes
Show child attributes
Resposta
The batch was answered signal by signal
Show child attributes
Show child attributes