POST
Record what the shopper did with a decision
This one records what the shopper did. To update the catalog, the operation is Ingest a catalog event.

A signal belongs to a recommendation

Every signal carries the decision_id: the id of the recommendation that getRecommendations returned. In the API that object is Decision, the list of products recommended for that moment. The id is unique per response: two impressions of the same offer are two different recommendations. The signal does not carry the engine’s ids: the server stored them when it served the recommendation. If they came from the browser, anyone with the public key could point an interaction at another offer. decision_id must exist and belong to this connection. If not, the response is rejected with reason: unknown_decision, the same as for an id that never existed: that way nobody can probe other stores’ recommendations.

The batch is answered signal by signal

Up to 50 signals per request; more is signal_batch_limit_exceeded and none is stored. The response is 202 with one result per position: A broken signal doesn’t drag the others down: the batch is a delivery, not a unit.

Resending the same batch is safe

signal_id is generated by the SDK and is stable across retries: the second arrival answers duplicate with no new work.

Which fields each type carries

item_id and variant_id are canonical ids (itm_, var_), the same as in the recommendation. The server translates them to the store’s ids.

Each signal is a change, not the whole cart

The server keeps what the shopper holds from each recommendation: one line per item and variant. add_to_cart adds, update_quantity sets, remove_from_cart removes. Each signal sends only its change and the server builds the running state: a lost signal doesn’t erase what came before, and a resend doesn’t add twice.

A 503 asks for a retry

If the store is unavailable, the response is 503 signals_unavailable and none of the batch’s signals was stored. The SDK keeps the batch and sends it again. A recommendation, by contrast, is served even if recording fails.

What the server stores

To audit the request: IP, User-Agent, Accept-Language, Origin, Referer and the SDK’s client. None of it comes back in the response. The contract limits the shape of visitor: it can’t be an email or a phone. A malformed visitor or client is dropped: the signal is stored without it, with a warning that leaves out the value.

Authorizations

Authorization
string
header
required

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

Path Parameters

connection_id
string
required

CrossUp connection identifier.

Minimum string length: 1

Body

application/json
signals
object[]
required
Required array length: 1 - 50 elements

Response

The batch was answered signal by signal

results
object[]
required