Skip to content

Recommendations Customization

View MD

Luigi’s Box Recommendations Customizations API allows you to manually override the automated recommendation algorithms. You can promote specific items (upsell), enforce brand consistency, or curate seasonal collections by “pinning” items to specific positions in the result set.

To use this feature, a recommender must be initialized. See Recommender API for more details.

Check the OpenAPI Specification for the formal contract in YAML.

To effectively use this API, you must understand the relationship between the following components:

  • Customization (Scope): This represents the Context or the Trigger. It defines when a set of rules should apply. For example, “Only apply these rules when the user is looking at a Fender Guitar” or “Apply these rules to the Basket page.”
  • Pin: This represents the Action or the Result. It defines what items should appear. For example, “Show this specific guitar strap in position 1.”
  • Target: The specific rule used to trigger the Customization (e.g., a specific Item ID or a Category).
flowchart TD
Tracker["Tracker or store"] --> Model["Recommender model"]
Model --> Cust1["Customization 1: target item A"]
Model --> Cust2["Customization 2: target brand Nike"]
Cust1 --> Pin1["Pin: show item X at position 1"]
Cust1 --> Pin2["Pin: show item Y at position 2"]
Cust2 --> Pin3["Pin: show item Z at position 1"]

Every customization is attached to a specific Recommender Model (e.g., basket, product_detail). Within that model, you can define Target Types to control specificity.

When a recommendation request matches multiple customizations, the Priority determines which one wins:

  1. Item Target (Highest): Matches a specific Item ID (e.g., “User is viewing Product A”).
  2. Criteria Target: Matches item attributes (e.g., “User is viewing any item where Brand is Nike”).
  3. All (Lowest): Applies globally to the model (e.g., “Always apply on the Homepage”).

The Customization Object (often referred to as the “Scope”) is the parent container. It holds the target definition and the list of pins.

FieldTypeRequiredDescription
idUUIDRead-onlyUnique identifier.
modelStringYesRecommender model name (e.g., basket).
target_typeStringYesitem, criteria, or all.
target_identityStringCond.The item ID (ID) if target_type is item.
target_criteriaObjectCond.The Criteria Object if target_type is criteria.
tagsArrayNoList of organizational tags.
pin_definitionsArrayYesList of Pin Objects.
creatorStringRead-onlyUser who created the customization.

Target: Item

{
"id": "199620b4-...",
"model": "basket",
"target_type": "item",
"target_identity": "/p/123",
"tags": ["guitar"],
"pin_definitions": [ ... ]
}

Target: Criteria

{
"id": "199620b4-...",
"model": "basket",
"target_type": "criteria",
"target_criteria": {
"attribute": "brand",
"operator": "in",
"values": ["Fender"]
},
"pin_definitions": [ ... ]
}

Target: All

{
"id": "199620b4-...",
"model": "basket",
"target_type": "all",
"pin_definitions": [ ... ]
}

Once a Customization is triggered, the Pins determine which items are injected into the results.

  • Item Pin: Injects a specific product ID.
  • Criteria Pin: Injects items that match specific metadata (e.g., “Any item that is Red”). Note: This is computationally expensive.
  • Regular (position: N): Forces the item into the Nth slot (1-based index).
  • Global (position: -1): Attempts to pin the item in every position (usually used with Criteria pins to flood results).
  • Block (position: 0): Acts as a Blacklist. Prevents the defined item or criteria from appearing in the recommendations.
FieldTypeRequiredDescription
positionIntegerYes1-based index. Use -1 for Global, 0 for Block.
pin_typeStringYesitem or criteria.
pin_identityStringCond.Item ID if pin_type is item.
pin_criteriaObjectCond.Criteria Object if pin_type is criteria.
active_fromDateNoISO 8601 Start date.
active_toDateNoISO 8601 End date.
is_block_pinBooleanNoIf true, excludes matching items.

Pin Type: Item

{
"position": 1,
"pin_type": "item",
"pin_identity": "/p/234",
"active_from": "2025-01-22T08:49:58Z",
"is_block_pin": false
}

Pin Type: Criteria

{
"position": 4,
"pin_type": "criteria",
"pin_criteria": {
"attribute": "color",
"operator": "in",
"values": ["red"]
}
}

Because multiple customizations can target the same context, conflicts can occur. The system resolves them using a Priority Selection & Shifting strategy.

flowchart TD
Start{"Conflict detected?"}
Start -- No --> Apply["Apply pin normally"]
Start -- Yes --> Type{"Collision type"}
Type -- Same position --> Select["Select pins with highest priority"]
Select --> Order["Order by recency"]
Order --> Return["Return selected pins and shift downstream pins"]
Type -- Duplicate item --> LocCheck{"Same scope?"}
LocCheck -- Yes --> MinPos["Use minimum position"]
LocCheck -- No --> HighScope["Use pin from higher-priority scope"]
Type -- Block vs regular --> BlockScope{"Does the regular pin have higher scope priority?"}
BlockScope -- Yes --> RegularWins["Regular pin overrides block"]
BlockScope -- No --> BlockWins["Item is blocked and removed"]

Situation:

  • Pins A & B (High Priority, e.g., Item Scope) want Position 2.
  • Pin C (Low Priority, e.g., Criteria Scope) also wants Position 2.
  • Pin X (Any Priority) wants Position 3.

Resolution:

  1. Select Winner: The system selects only the pins with the highest priority (Pins A & B). Pin C is ignored completely because it lost the priority battle for Position 2.
  2. Order Winners: A and B are ordered by recency (e.g., input order).
  3. Shift Downstream: Because A and B now occupy Position 2 and 3, the original Pin X (which wanted Position 3) is pushed down to Position 4.

Result:

  • Pos 2: Pin A
  • Pos 3: Pin B
  • Pos 4: Pin X (Shifted)
  • (Pin C is discarded).

Situation: The same item is pinned in multiple places.

Resolution:

  • Same Scope: The item appears at the minimum (lowest number) position defined.
  • Different Scopes: The pin from the highest priority scope is respected.

Situation: One rule says “Show Item A”, another says “Block Item A”.

Resolution: The Regular pin overrides the Block pin only if its scope has a higher priority. Otherwise, the Block pin wins, and the item is completely excluded from the recommendation results.

The Criteria Object allows defining complex rules using logic (and, or, not) and attribute comparisons. It is used in target_criteria (Customization) and pin_criteria (Pin).

The top level must be a Logical operator or an Attribute condition.

Combines multiple criteria using boolean logic.

FieldTypeDescription
operatorStringand, or, not (unary).
criteriaArrayList of nested criteria objects.

Example:

{
"operator": "or",
"criteria": [
{
"attribute": "color",
"operator": "in",
"values": ["red", "black"]
},
{
"operator": "and",
"criteria": [
{
"attribute": "gender",
"operator": "in",
"values": ["woman", "unisex"]
},
{
"attribute": "size",
"operator": "lte",
"values": [38]
}
]
}
]
}

Basic criteria comparing item attributes to static values.

FieldDescription
attributeThe name of the attribute (e.g., brand).
operatorComparison operation.
valuesList of values to match against.
conditionOptional dynamic condition (see below).
transformationOptional value transformation (see below).

Supported Operators:

TypeOperators
Text/Booleanin, not_in, all_of, exists, not_exists
Numeric/Datelt, lte, gt, gte

Example:

{
"attribute": "color",
"operator": "in",
"values": ["red", "black"]
}

Matches specific item types (product, variant, query, category, article).

FieldDescription
operatorin, not_in
valuesList of types (e.g., ["product", "variant"]).
conditionOptional dynamic condition.

Allows comparing an attribute against a value derived from the current context (e.g., “Recommend items with the same brand as the current item”).

FieldDescription
left_attributeAttribute name to use for validation.
left_valuePlaceholder referencing which part of the attribute to use (e.g., @same).
operatorSupported operators: in, not_in, all_of, exists, not_exists (text/boolean); lt, lte, gt, gte, between, eq, neq (numeric/date).
right_valuesValues to match against the left side.
transformationOptional value transformation (see below).

Supported left_value placeholders:

  • @same: Exact value of the attribute.
  • @same_first, @same_last: First or last value of a list.
  • @same_second, @same_third: Second or third value of a list.
  • @same_first_two, @same_first_three: First two or three values of a list.
  • @same_second_and_later, @same_third_and_later: All values from the second or third onward.
  • @same_but_last: All values except the last.
  • *_main_only: Suffix to target only the first list in multidimensional attributes (e.g., @same_first_main_only).

Example:

{
"left_attribute": "_category",
"left_value": "@same",
"operator": "in",
"right_values": ["Shoes"]
}

Transforms the value before comparison.

FieldTypeRequiredDescription
functionStringThe operation to perform (e.g., +, *).
valueNumberThe argument for the function (e.g., 42, -0.8).

Supported Functions:

  • Numeric:
    • +: Add the value to the original number.
    • *: Multiply the original number by the value.
  • Date:
    • +: Add value (in days) to the original date.
  • Text/Array:
    • length: Count the characters or array items. (No value required). Example:
{
"function": "+",
"value": -5
}