Search and relevance

Ranking rules

Change the results for chosen searches. Put products first, hide them, lift or lower a brand, narrow the results or weigh fields differently, on a schedule and per profile.

What a rule is

A ranking rule changes the results of chosen searches. "When someone searches for katus, put these three roofing sheets first." "During the autumn sale, lift the brand Eterniit on every search." A rule has a when (the searches it fires for) and a then (one or more actions).

The Rules page with a try a search box showing that one rule applies to tape, and two rules: tape pin 2 products, live, and Christmas packaging, scheduledThe rules list, with a search to see which rules apply

Rules and profiles do different jobs:

  • A search profile sets how every search of one search box works: the fields, the typo tolerance, the facets and the sorts.
  • A rule changes a few searches, or every search for a while, without touching the profile. Merchandisers can add and remove rules for campaigns while the profile stays the same.

If a change should hold for every search, all the time, change the profile. If it is about particular words, particular listing pages or a date range, write a rule.

Rules belong to an index. They run on every profile of it unless you limit them to some profiles. A saved change applies from the next search on, with no reindex.

In the cabinet, open an index and then Rules. The list shows each rule as a sentence, such as "Search is katus · Pin 3 products · All profiles", with its status and an on/off switch. Try a search at the top shows which rules fire for a search you type.

Templates

New rule offers a starting point. Every template can be changed before you save.

TemplateWhat it sets up
Feature products for a searchPut chosen products first when people search for a word.
Promote a brand or categoryLift a brand or category higher in the results.
Push down productsMove a brand or category lower without hiding it.
Send a search to a categoryShow only one category for a search.
Hide products from a searchKeep chosen products out of the results for a search.
Campaign for every searchLift products on every search for a week. The dates start at the current hour.
Start from scratchAn empty rule: pick the searches and actions yourself.

When it fires

The editor's When someone searches for block holds the conditions. A rule fires when the search matches one of its phrases, and the request carries the filters of its filtered pages, if it has any.

The rule editor for tape with a match of exactly, the search tape, and a preview where the two pinned products come firstThe rule editor with its live preview

Searches

The phrases the rule fires for, up to 100 of 1 to 200 characters each. Any one of them is enough. Phrases and searches are compared after the same clean-up:

  • Capital letters and accents do not matter: "karcher" matches "Kärcher".
  • Anything that is not a letter or a digit counts as a space, and repeated spaces count as one: "t-shirt" matches "t shirt".
  • Synonyms count too. A rule for "tv" also fires for "telly" when the two are synonyms.

If the profile searched a corrected spelling after did you mean, rules match the corrected query.

Match

How a phrase is compared with the whole search. The cabinet calls the three options exactly, anything containing and anything starting with.

matchFires whenPhrase "kast" fires forDoes not fire for
is (default)the search is the phrase"kast", "Kast!""kast 50l", "kastekann"
containsthe phrase appears as whole words anywhere"kast", "plastic kast 50l""kastekann"
startsWiththe search begins with the phrase as whole words"kast", "kast 50l""plastic kast", "kastekann"

All three compare whole words. "kast" never fires for "kastekann", because "kastekann" is a different word.

A rule with no phrases fires on every search, the empty query on a category page included. In the editor, turn on Every search. Use it for campaigns, together with a schedule.

Only on filtered pages

Under Only on filtered pages (advanced), a rule can require filters in the request. This is for brand or category listing pages. The rule fires only when the shopper's search is filtered like this.

  • A value or a list fires when the request filters that field with at least these values. A condition {"brand": "Eterniit"} holds for a request with {"brand": ["Eterniit", "Ruukki"]}.
  • A range, an exists check or category nodes must equal the request's filter exactly. Write the condition the way your storefront sends the filter.

Actions

The Then block holds 1 to 10 actions. Add an action offers the five kinds below.

Put products first

pinType actionValues 1 to 24 products

What it does

Chosen products lead the results, in your order. In the editor, pick them with the product search and drag them into order. Each pinned hit carries _pinned: true in the response.

{ "type": "pin", "ids": ["sheet-120", "sheet-80", "ridge-1"] }

A pinned product shows even when it does not match the search words. It still has to pass every filter: the profile's filters and exclusions, the rule filters, and the shopper's facet clicks.

Best practices and common mistakes

  • Pins only apply when results are ordered by relevance. See Pins, sorting and facets.
  • Pin few products. Shoppers read the first row; 3 to 6 pins usually beat 24.

Related

Hide products

hideType actionValues 1 to 500 products

What it does

Chosen products never show for these searches. Hiding beats pinning. A product that one rule hides and another pins stays hidden.

{ "type": "hide", "ids": ["sheet-old-2019"] }

Best practices and common mistakes

  • To hide a whole brand or category from one storefront for every search, an exclusion in the profile is simpler than a rule.

Lift or lower products

boostType actionValues factor 0.1 to 10

What it does

Moves a brand, a category or any product group up or down. The relevance of every product that matches the filters is multiplied by factor. Above 1 lifts, below 1 lowers.

The editor offers named steps and a custom value:

StepFactor
Lower a lot0.3
Lower0.6
Lift2
Lift a lot5
Customany value from 0.1 to 10
{ "type": "boost", "filters": { "brand": "Eterniit" }, "factor": 2 }

Best practices and common mistakes

  • A lift is not a pin. A lifted product that matches the search badly can still rank below a good match. Use a pin to put a product first for sure.
  • Several boosts multiply for a product that matches more than one, up to 100 times in total.
  • Boosts change relevance, so they have no effect when the shopper sorts by price or another field.

Show only

filterType action

What it does

Narrows the results to a brand, category or other group, like a profile filter. Only products that match show for these searches, and facet counts narrow with them.

{ "type": "filter", "filters": { "category": { "terms": ["Roofing>Sheets"] } } }

Best practices and common mistakes

  • The "Send a search to a category" template uses this action. A search for "katus" (Estonian for roof) can show only roofing products, even though "katus" also appears in gutter descriptions.
  • Filters from several rules all apply. Two rules that show only different brands leave no results.

Search fields differently

fieldWeightsType actionValues weights 0 to 100

What it does

Gives a field more or less say in the ranking, or stops searching it, for these searches only. A weight replaces the profile's weight for that field. 0 means the field is not searched. In the editor, leave a field empty to keep the profile's weight.

{ "type": "fieldWeights", "weights": { "sku": 10, "description": 0 } }

Best practices and common mistakes

  • Useful when one word means two things: a search for "apple" in a hardware store can weigh the brand field up and the description down.
  • When two rules set a weight for the same field, the higher rule in the list wins.
  • Weights that would leave no field to search are ignored, and the profile's weights apply.

When it runs

Schedule

Always or Between two dates. A rule with dates is live from activeFrom, included, until activeUntil, not included. Leave one empty for no start or no end. The cabinet shows the times in your time zone; the API takes and returns ISO dates with a time zone, such as 2026-11-20T00:00:00Z. The end must be after the start.

Profiles

All profiles (the default) or Chosen profiles. A rule limited to chosen profiles fires only for searches through those profiles. Deleting a profile removes it from every rule. A rule that is left with no profile is switched off, so that it does not start firing on every profile.

Skip the rules below

With Skip the rules below when this one applies (stop), a firing rule ends the run. Rules lower in the list do not fire for that search.

Order

Rules run from the top of the list to the bottom. In the list, drag a rule, or use Move up and Move down in its menu. Clear the list's search and status filter to change the order. Order matters for three things: the order in which pins from several rules appear, which rule's field weight wins, and where a stop rule ends the run.

Status

Each rule shows one status:

StatusruleStatusMeaning
LiveliveOn, and firing for matching searches.
ScheduledscheduledOn, and its start date is still ahead.
EndedendedOn, but its end date has passed.
OffoffSwitched off.
Needs attentionattentionOn, but a field it uses no longer fits the mapping. Search skips the rule until you fix it.

A rule needs attention when the mapping changed after it was saved. For example, a boost filters on brand, and brand is no longer filterable or facetable. The rule's issues list says which field and why.

Preview and test

The editor's Preview runs a search through a profile you pick, with the draft rule, before you save it. It shows the results with the rule and marks how each product moved compared with today's results: Pinned 1, ↑ 3, ↓ 2 or New. It also names other rules that fire for the same search.

POST/v1/projects/:projectId/indices/:indexId/rules/testProject member or any secret key

The body is a search request plus profileId (the stored profile to search through) and an optional draft: {"id": <rule id or none>, "rule": <rule>}. The draft takes the place of the stored rule with that id, or runs last when it has no id. The answer has fired (the rules that fired, in order), results, and with a draft also baseline, the same search without the draft. Tests are not counted in Analytics.

curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/rules/test \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{"profileId": "'$PROFILE_ID'", "q": "katus",
       "draft": {"rule": {"name": "Roof sheets first", "when": {"queries": ["katus"]},
                          "then": [{"type": "pin", "ids": ["sheet-120", "sheet-80"]}]}}}'

Pins, sorting and facets

Pins apply only when results are ordered by relevance:

  • The shopper sorts by a field. A sort such as price:asc puts relevance aside, and pins with it. A pinned product shows only if it matches the search, in its place in the price order, and carries no _pinned flag.
  • The profile has always-show-first clauses. Pins apply when, after the profile's pinnedSort clauses, the order is by relevance. With pinnedSort set to inStock:desc and the default sort _relevance, pins lead within each group. A pinned product that is out of stock comes after every product in stock.
  • The shopper clicks a facet. Pins pass through the same filters as every other product. A click on another brand removes a pinned product of a different brand from the results.

Pinned products count in the facets like any other result.

How several rules combine

Every rule that fires adds its actions:

  • Pins join in rule order, without duplicates, up to 24 in total.
  • Hidden products add up, and a hidden product is never pinned.
  • Boosts multiply for a product that matches several, up to 100 times in total.
  • Filters all apply.
  • For each field, the weight from the highest firing rule wins.

Limits

WhatLimit
Rules per index1,000 (409 RULE_LIMIT_REACHED above)
Phrases per rule100, each 1 to 200 characters
Actions per rule10
Pinned products per action, and per search24
Hidden products per action500
Boost factor0.1 to 10
Field weight0 to 100
Profiles per rule50
Rule name1 to 100 characters

Over the API and MCP

GET/v1/projects/:projectId/indices/:indexId/rulesProject member or any secret keyPOST/v1/projects/:projectId/indices/:indexId/rulesProject admin or a full-access secret keyGET/v1/projects/:projectId/indices/:indexId/rules/:ruleIdProject member or any secret keyPUT/v1/projects/:projectId/indices/:indexId/rules/:ruleIdProject admin or a full-access secret keyDELETE/v1/projects/:projectId/indices/:indexId/rules/:ruleIdProject admin or a full-access secret keyPUT/v1/projects/:projectId/indices/:indexId/rules/orderProject admin or a full-access secret key

POST adds the rule at the bottom of the list. PUT replaces the whole rule. PUT .../order takes {"ids": [...]} with every rule id of the index exactly once, in the new order, or answers 400 RULE_ORDER_MISMATCH. A rule that names a field the mapping does not allow for its use, or a profile of another index, answers 400 RULE_INVALID with one issue per problem.

curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/rules \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{
    "name": "Autumn sale: Eterniit",
    "when": {"queries": []},
    "then": [{"type": "boost", "filters": {"brand": "Eterniit"}, "factor": 2}],
    "activeFrom": "2026-11-01T00:00:00Z",
    "activeUntil": "2026-11-15T00:00:00Z"
  }'

The fields of a rule, with their defaults: name, enabled (true), profiles ([], every profile), when with queries ([]), match ("is") and filters ({}), activeFrom and activeUntil (null), then, and stop (false). A stored rule also has id, position (0 runs first) and issues.

Common mistakes

  • A pin does not show. The shopper sorted by a field, the pinned product fails a filter, or another rule hides it. Type the search under Try a search to see which rules fire.
  • A rule fires too often. contains with a short phrase fires on every search with that word. Use is for one-word searches you want to steer.
  • A rule never fires on a category page. Its filtered-page condition uses another form than the storefront sends, such as a list where the storefront sends {"terms": [...]}.
  • A campaign does not end. It has no end date. Set Between two dates, or switch it off when the campaign is over.