Skip to content

    Pre-launch API. The concepts described here are settled, but the API shape is not: request and response fields, parameters and defaults can still change. Build against it, and talk to your Luigi's Box contact before you put an integration into production.

    Personalization

    View source

    Personalization tailors a slate to the shopper in front of it, using what they have done recently in this channel. It is on by default and turned off per request with "personalize": false.

    InputWhereIdentifies
    X-Lbx-Visitor-IdHeader, required on every discovery requestThis browser, over the long term
    user_idBody field, optionalThe signed-in shopper, across their devices
    personalizeBody field, default trueWhether to personalize this request
    Terminal window
    curl -X POST 'https://api.eu1.luigisbox.ai/discovery/v1/search?channel_id=lbn_4hj9tv&surface_id=lbs_search_main' \
    -H 'Authorization: Bearer <token>' \
    -H 'X-Lbx-Visitor-Id: 8f14e45f-ea0f-4b5c-9a1d-2b3c4d5e6f70' \
    -H 'Content-Type: application/json' \
    -d '{
    "type": "product",
    "query": "running shoes",
    "personalize": true,
    "user_id": "customer-88213"
    }'

    personalize asserts two things at once: personalize this answer, and this shopper has consented to behavioural personalization. The flag is recorded on the ranking record for the request, so it governs both what the shopper sees and what the request may be used for afterwards.

    Read it from your consent manager on every request rather than relying on the default:

    // Read consent from your own consent manager — never hardcode it.
    const personalize = consentManager.hasAnalyticsConsent();

    The corresponding flag on analytics events is consent_granted. Read both from the same source, so a shopper’s choice is applied consistently on the request and on the event that reports it. See Sending events.

    X-Lbx-Visitor-Id is required on every discovery request whether or not you personalize, and it is the input personalization depends on most.

    • Generate it once per browser and persist it — a UUID in a first-party cookie or localStorage.
    • Keep it stable across token refreshes, page loads and sessions. A visitor ID that changes per page load makes every visit look like a new shopper.
    • Never generate it server-side. If your backend calls discovery, your frontend produces the value and your backend forwards it verbatim. A server-generated ID collapses every shopper into one.
    • Reset it on sign-out if a shared device is a realistic concern for your storefront.
    function visitorId() {
    let id = localStorage.getItem('lbx_visitor_id');
    if (!id) {
    id = crypto.randomUUID();
    localStorage.setItem('lbx_visitor_id', id);
    }
    return id;
    }

    user_id is your own stable customer key. Sending it lets a signed-in shopper’s history follow them between devices — the phone they browsed on and the laptop they buy on.

    • Send it only while the shopper is authenticated in your storefront.
    • Use a stable internal key, not an email address or anything else that identifies a person. Luigi’s Box treats it as an opaque string; you decide what it reveals.
    • Omit it, or send it blank, for anonymous traffic. Both are treated as anonymous.
    • Keep sending X-Lbx-Visitor-Id as well. The two are complementary, not alternatives.

    Personalization helps most where a shopper’s intent is broad and the catalog is large, and least where they have already been specific.

    PlacementPersonalize?Why
    Homepage recommendationsYesNothing else to go on
    Search with a broad query — “shoes”YesMany valid answers; recent behaviour breaks the tie
    Search with a precise query — a SKULittle effectOne right answer already
    Category listingOftenOrdering within a large category
    Cart cross-sellYesThe cart plus history beats the cart alone
    Explicit sort — “price, low to high”No effect on orderThe shopper asked for a specific ordering

    Send true wherever you have consent; the surface decides how much to use.

    Personalized and non-personalized traffic are reported separately; compare them, or run an A/B test on the surface, to size the effect. Both need analytics events flowing: without clicks, cart additions and purchases, there is nothing to personalize from and nothing to measure with.