Merchandising rules, without a deploy.
Pin a hero SKU to the top of "sneaker" searches on Friday. Boost your private-label brand globally. Bury a discontinued line from category results. Trooply's merchandising engine lets merchandisers run campaigns, promotions, and taxonomy decisions from a portal UI — no engineering ticket, no weekend release.
Three rule types, one engine.
Rules run on every search — image, text, voice, fusion, widget — in a fixed order that keeps interactions predictable.
Force SKUs to the top
Pass a list of product IDs in order. Position #1 in the list lands at position #1 in the response, ignoring similarity score. Perfect for hero products during a campaign.
Multiply the similarity score
Boost multiplier 1.2–2.0 promotes; 0.5–0.8 de-emphasises. The product still ranks organically — boosted products just ride higher in the list. Scores cap at 1.0 after boost.
Remove from results
Matching product IDs are filtered out before the response builds. Use for discontinued lines, region-gated products, or a campaign that ran its course without being fully indexed out.
A control layer over retrieval.
Self-scoping rules
A rule fires only when its scope condition matches — query is exactly "sale", or query contains "sneaker", or the response category equals "Footwear". No global side effects.
Campaign windows
Every rule has optional start_at and end_at. A Black Friday pin kicks in at midnight Friday, stops at midnight Monday, and nobody has to remember to turn it off.
Priority tie-breaks
When multiple rules match the same product, the one with lower priority wins. The engine sorts deterministically so two merchandisers don't stomp on each other's campaigns.
Explainability
Every moved result carries applied_rules in its match breakdown. Click any card in the portal and see exactly which rule pushed it up.
Portal editor + REST API
Merchandisers use /portal/merchandising. Automation pipelines use /v1/merchandising/rules. Both surfaces write to the same store.
Cache-invalidated on write
Rules cache per tenant for 60 seconds. Any create / update / delete invalidates the cache immediately — a new pin is live on the next search, not the next minute.
Where rules earn their keep.
Pin the hero SKU for "sale"
A pin rule scoped query_exact: "sale" with a 72-hour window. Shoppers searching "sale" Friday morning see the campaign hero; Monday's shoppers see organic results again, automatically.
Global 1.3× brand boost
A boost rule scoped always with a curated product list and multiplier 1.3. Your brand gets consistent lift on every query without overriding relevance.
Bury last season's fashion
A bury rule scoped category_match: "Fashion" keeps old-season SKUs out of category results while still letting direct product-ID links work.
Boost new arrivals in a category
A boost rule scoped category_match: "Electronics" with priority 50 gives newly-indexed SKUs a temporary lift — pair with a 30-day window and recency handles itself.
Apply order (this is the important part).
When multiple rules match, the engine applies them in a fixed, deterministic order:
- Bury first. Drop every buried product ID from the candidate list. This happens before anything else so a single bury rule can't be overridden by a pin or boost elsewhere.
- Boost second. Multiply each matched product's similarity score by its boost multiplier. Re-sort. When two boost rules match the same product, the highest multiplier wins (all are still stamped on the breadcrumb for audit).
- Pin last. Prepend pinned products to the front of the response in list order. Pinned products keep their real score for display but get position 1, 2, 3, … regardless of organic rank.
Within each phase, rules run in priority ascending, then created_at descending. A priority-50 rule always runs before a priority-100 rule; a newer priority-100 rule runs before an older priority-100 rule.
Example: a pin rule via API
POST /v1/merchandising/rules
Authorization: Bearer $TOKEN
Content-Type: application/json
{
"rule_type": "pin",
"scope_type": "query_exact",
"scope_value": "sale",
"product_ids": ["SKU-HERO", "SKU-FEATURED-2"],
"priority": 5,
"start_at": "2026-04-25T00:00:00Z",
"end_at": "2026-04-28T00:00:00Z",
"description": "Spring-sale campaign pins"
}
Order matters for pins — index 0 lands at position #1, index 1 lands at position #2, and so on. Boost and bury treat product_ids as a set; order is ignored.
Common questions.
Do rules work for visual (image-upload) searches too?
Yes — every search path goes through the same re-rank and merchandising layer. A pin rule with scope_type: always will pin the listed products regardless of whether the shopper queried by text, photo, voice, or crop.
What happens when a pinned product isn't in the result set?
It's silently skipped — we don't inject products the retrieval stage didn't surface. Pinning a product that doesn't match the query at all would just mislead shoppers.
How many rules can I have?
Thousands — rules are cheap. The common pattern is dozens of active rules at any time with a rolling set of campaign-specific pins and a few always-on boosts for priority brands.
Can the same SKU be both pinned and boosted?
Yes. The rules compose: boost multiplies the score, pin overrides the position. The breadcrumb captures both applied rules so you can audit later.
Is there a way to schedule a rule?
Yes — every rule has optional start_at and end_at. A future-dated rule is a no-op until its start; after its end, it stops applying without needing to be deleted.
How do I debug why a product moved?
Every moved result carries metadata._match_breakdown.applied_rules with the rule ID, rule type, effect, and human description. The portal's Match Analysis modal surfaces this for every result card.
Move merchandising off the ticket queue.
Free forever tier includes merchandising rules. Portal editor at /portal/merchandising.