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.
Ranking answers most questions well. Business rules are for the ones it cannot know about: the supplier deal that has to be visible this week, the discontinued line that must stop appearing, the hero product on the sale page.
A rule does not replace ranking. It is applied inside it — the results are still ranked, and the rule adjusts the outcome. That is why the rules you write and the ranking you did not configure can coexist without one flattening the other.
A rule names the products it acts on, by ID or by criteria such as a brand or a clearance
flag, and one of four effects. pin fixes a position. ban removes. boost and bury
shift the ranking, at full strength or fading over time.
Four questions
Section titled “Four questions”Rules are grouped into campaigns. A campaign answers three questions, and each rule inside it answers a fourth:
| Question | Where it lives | |
|---|---|---|
| Targeting | Which catalogs, channels, surfaces and intents does this apply to? | Campaign |
| Trigger | Which requests does it fire on? | Campaign match |
| Schedule | When does it run? | Campaign starts_at / ends_at |
| Effect | Which products, and what happens to them? | Each rule |
Targeting has a permissive default: a dimension you leave empty means all of it. The trigger is always present, and a campaign with no schedule runs whenever it is active.
A campaign holds 1–50 rules and belongs to one organization. Its name must be unique among the organization’s live campaigns.
“Product” on these pages stands for any catalog object the surface serves. The same rules
apply to categories, brands or articles; an ID such as category/shoes names the type.
A first campaign
Section titled “A first campaign”Pin one product to the top of search results for “running shoes”, for two weeks:
curl -X POST 'https://api.eu1.luigisbox.ai/platform/v1/campaigns' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "organization_id": "lbo_r2vn8c", "name": "Spring running push", "status": "active", "starts_at": "2026-04-01T00:00:00Z", "ends_at": "2026-04-15T00:00:00Z", "catalog_ids": ["lbc_8w3k2p"], "intents": ["search"], "match": { "operator": "and", "conditions": [ { "field": "trigger.request:query", "operator": "matches", "value": "running shoes" } ] }, "rules": [ { "name": "Hero: Kestrel Trail", "record_match": { "operator": "and", "conditions": [ { "field": "@id", "operator": "eq", "value": "product/sku-4410" } ] }, "effect": { "type": "pin", "position": 1 } } ] }'The response is 201 with the created campaign, its lbm_… ID and its rules’ lbr_… IDs.
Read that body as the four questions in order: catalog_ids and intents are the
targeting, match is the trigger, starts_at / ends_at are the schedule, and the one
rule pairs a product selector with an effect. A pin holds for the whole campaign; a boost or
bury can instead fade over a decay_window — see
Rules and effects.
Two condition trees, two jobs
Section titled “Two condition trees, two jobs”A campaign carries two condition trees that look alike and answer different questions:
| Tree | Asks | Fields |
|---|---|---|
match on the campaign | Does this campaign apply to this request? | trigger.-prefixed |
record_match on a rule | Which products does this rule act on? | Catalog fields |
A rule only runs on requests its campaign fires on, and a campaign that fires but whose rules select no products does nothing. Both trees have to be right.
Lifecycle
Section titled “Lifecycle”status | Behaviour |
|---|---|
draft | Saved, never served. The default. |
active | Served, subject to its schedule |
paused | Saved and not served; can be reactivated |
archived | Terminal |
starts_at and ends_at are UTC instants and are optional — leave both out for a campaign
that runs whenever it is active. timezone records the zone the schedule was authored in
so it can be reopened there; it is informational and never shifts the instants.
Practical advice
Section titled “Practical advice”- Give rules names that say why.
"Supplier deal — Northwear Q2"explains itself six months later;"Boost 1"does not. - Prefer criteria to lists of IDs. A rule on
clearance = truekeeps working as stock turns over; a list of 200 IDs decays into a maintenance job. - Always set
ends_atfor a promotion. Campaigns that outlive their reason are the main cause of results nobody can explain. - Pick the right tool for hiding products. A ban hides a set of products in one
context: prescription drugs in recommenders but not in search, or a category the mobile
app does not sell. Target the campaign by intent or channel and leave
ends_atout. Use a channel’s visibility filter when the products should never appear on that channel at all, and remove products from the catalog when they should appear nowhere. - Check the effect. A rule trades relevance for control. Watch the surface’s reporting after a campaign goes live — see Analytics.
Where to go next
Section titled “Where to go next”| Rules and effects | Which products, and what happens to them |
| Triggers | Which requests a campaign fires on |
| Targeting | Which catalogs, channels, surfaces and intents it covers |
| Resolving conflicts | Who wins when several rules hit one product |
| Authoring API | The endpoints, field by field |
See also
Section titled “See also”- Sponsored products — third-party placements in the same slate
- Filters — the operator vocabulary and the missing-attribute rule
- Account structure — catalogs, channels, surfaces and tags
Was this page helpful?
Thanks.