Autocomplete

Autocomplete

Query suggestions as the shopper types, built every hour from your own searches, field values and custom entries.

What autocomplete does

As the shopper types, the search box asks Zaproo for completions: "sams" answers "samsung tv", "samsung", "samsung soundbar". Each index has its own suggestion index, built from three sources:

  • Queries that shoppers searched on your store and that found products.
  • Field values of the fields you choose, such as every brand.
  • Custom suggestions you add by hand, such as a campaign name.

Suggestions only ever come from that suggestion index, so a suggest request stays fast and never touches your products. The index is rebuilt every hour.

In the cabinet, open an index and then Autocomplete. The page has four parts: Settings, Suggestion index (the rebuild button), Preview and Custom suggestions.

Settings

Each index has one suggest config. The first time anyone opens it, in the cabinet or with GET, it is created with the defaults below and a new suggest key.

The Autocomplete page with the settings form, the suggestion index with a Rebuild now button, and a preview listing tape, duct tape and office tape for the query taAutocomplete settings with a live preview

GET/v1/projects/:projectId/indices/:indexId/suggestions/configProject member or any secret keyPUT/v1/projects/:projectId/indices/:indexId/suggestions/configProject admin or a full-access secret key

PUT replaces the whole config, so send every setting. A field that is not a keyword field with doc values, or a searchProfileKey that no profile of this index has, answers 400 SUGGEST_CONFIG_INVALID with one issue per problem.

Settings that shape the answer (limit, fuzzy, defaultSuggestions, facetHints, searchProfileKey) apply to the very next suggest request. Settings that shape the build (fields, minQueryCount, lookbackDays) apply with the next build: wait for the hourly one or press Rebuild now.

curl -X PUT https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/suggestions/config \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{
    "limit": 8,
    "fuzzy": true,
    "defaultSuggestions": {"enabled": true, "count": 5},
    "facetHints": true,
    "searchProfileKey": "PROFILE_KEY",
    "fields": ["brand"],
    "minQueryCount": 2,
    "lookbackDays": 30
  }'

Suggestions per answer

limitType integerDefault 8Values 1 to 20

What it does

How many suggestions one answer holds at most. In the cabinet: Suggestions per answer.

Best practices and common mistakes

  • 6 to 8 fit a dropdown on a phone without scrolling. More than 10 is hard to scan while typing.

Allow one typo per word

fuzzyType booleanDefault true

What it does

Lets each word the shopper types differ by one letter from a suggestion, after an exact first letter: "samsnug" still finds "samsung tv". A suggestion that matches without a typo scores twice as high as one that needs the typo, so exact completions come first.

Best practices and common mistakes

  • Leave it on for most stores. Turn it off when shoppers mostly type codes, where one changed character is a different product.

Empty query suggestions

defaultSuggestionsType { enabled, count }Default enabled true, count 5Values count 1 to 20

What it does

What an empty q answers, for example when the shopper clicks into the search box before typing. With enabled, it lists the count most searched queries. Off, an empty q answers an empty list. In the cabinet: Suggest popular searches for an empty query and Empty query shows.

Best practices and common mistakes

  • Only queries are listed here, never field values or custom suggestions.
  • A new store has no searches yet, so the list stays empty until shoppers have searched for a while.

Facet hints

facetHintsType booleanDefault true

What it does

Adds a category to suggestions where one stands out: "samsung tv" in TV. The storefront can then search "samsung tv" with that category already filtered. A hint comes from the first facetable hierarchy field of the index, and only when more than half of the products the query finds sit in one category; the deepest such category wins. The 200 most popular queries get a hint.

With this off, every suggestion answers facetHint: null. Custom suggestions can carry a hint of their own.

Best practices and common mistakes

  • Hints need a hierarchy field that is facetable in the mapping. Without one, queries get no hints, but field values still point at their own field.

Search profile for a clicked suggestion

searchProfileKeyType profile key | nullDefault null

What it does

The profile the storefront should search with when the shopper picks a suggestion. Zaproo does not use it itself; it echoes it in every suggest answer, so the storefront does not have to hard-code it. In the cabinet: Search profile for a clicked suggestion.

Related

Field values

fieldsType field namesDefault []Values up to 10 keyword fields

What it does

Fields whose values become suggestions, such as brand or series. Each must be a keyword field that is filterable, facetable or sortable. Each field adds up to its 200 most frequent values. In the cabinet: Field values (comma separated).

Best practices and common mistakes

  • Pick short, typed-by-name values: brands, product lines, collections. A field like title makes no sense here, because every title would become a suggestion.
  • A field value scores like a query searched about twice, so popular queries rank above it and one-off queries below it.

Minimum searches to qualify

minQueryCountType integerDefault 2Values 1 to 1000

What it does

How many different visitors must have searched a query, with results, before it becomes a suggestion. Each distinct sessionId sent with search counts once; searches without a sessionId count one each.

Best practices and common mistakes

  • Send a stable sessionId with every search from the storefront. Then one shopper who repeats a phrase cannot turn it into a public suggestion.
  • Raise it on a busy store to keep rare or odd queries out. On a new store, 1 or 2 fills the list sooner.

Lookback

lookbackDaysType integerDefault 30Values 1 to 90

What it does

How many days of searches the build reads. Search history is kept for 90 days, so 90 is the most. In the cabinet: Lookback (days).

Best practices and common mistakes

  • 30 days follows seasons and trends. A longer window keeps steady sellers but lets last season's queries linger.

Suggest key

suggestKeyType stringValues 16 URL-safe characters, read-only

What it does

The public handle of the index's suggestions, used in the suggest URL. It is created with the config and never changes. The cabinet shows it at the top of Settings.

Best practices and common mistakes

  • The suggest key is not a secret, and it is no credential. The request still needs an API key of the same project.

Custom suggestions

A custom suggestion is a text you want offered, with a weight and an optional facet hint. Use it for campaign names, new product lines nobody has searched for yet, or to push one completion above the rest.

GET/v1/projects/:projectId/indices/:indexId/suggestions/customProject member or any secret keyPOST/v1/projects/:projectId/indices/:indexId/suggestions/customProject admin or a full-access secret keyDELETE/v1/projects/:projectId/indices/:indexId/suggestions/custom/:suggestionIdProject admin or a full-access secret key
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/suggestions/custom \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{"text": "black friday deals", "weight": 20, "facetHint": {"key": "category", "value": "Deals"}}'
text
string required
1 to 100 characters. Unique per index after lowercasing and collapsing spaces, otherwise 409 SUGGESTION_TAKEN.
weight
number required
Above 0, up to 1,000,000. It becomes the suggestion's score as is.
facetHint
{ key, value } | null
The field and value the suggestion points at. Defaults to null.

An index holds up to 1000 custom suggestions; one more answers 409 SUGGESTION_LIMIT_REACHED. A new or deleted custom suggestion shows up with the next build.

Weight

A query scores log1p(searches), the natural log of one plus the number of visitors who searched it. A query searched by 100 visitors scores about 4.6, by 10,000 about 9.2. Your weight is compared with that number directly:

WeightRanks
1Like a field value: above queries searched once, below anything popular.
5Above queries with fewer than about 150 visitors.
10Above queries with fewer than about 22,000 visitors.
15 and aboveAbove every query.

When a custom suggestion has the same text as a query or a field value, the custom one wins: its weight and its hint are used.

Rebuilding

A worker rebuilds every index that has a suggest config once an hour. It reads the queries of the lookback window, the values of the configured fields and the custom suggestions, writes a new suggestion index and swaps it in, so suggest keeps answering during the build. Queries that are a misspelling of a far more popular one ("samsnug tv" next to "samsung tv") are dropped.

Press Rebuild now after adding custom suggestions, changing the field list or uploading a new catalog. It queues a task; the cabinet shows its status and, when it is done, how many suggestions the new index holds.

POST/v1/projects/:projectId/indices/:indexId/suggestions/rebuildProject admin or a full-access secret key
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/suggestions/rebuild \
  -H "Authorization: Bearer $ZS_KEY"
# 202 {"taskId": "..."}

Poll GET /v1/projects/:projectId/tasks/:taskId like any other task. The hourly schedule skips an index whose build is already queued or running.

The suggest request

The storefront calls one route with the suggest key. The body holds only q, up to 100 characters.

POST/v1/suggest/:suggestKeyPublic key from an allowed origin, or a secret key of the same project
curl -X POST https://api.zaproo-search.com/v1/suggest/$SUGGEST_KEY \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -d '{"q": "sams"}'
{
  "suggestions": [
    {"text": "samsung tv", "kind": "query", "facetHint": {"key": "category", "value": "TV"}},
    {"text": "Samsung", "kind": "field", "facetHint": {"key": "brand", "value": "Samsung"}},
    {"text": "samsung soundbar", "kind": "query", "facetHint": null}
  ],
  "searchProfileKey": "PROFILE_KEY",
  "tookMs": 4
}

A suggest key of another project, or of an index outside the key's index scope, answers 404 SUGGEST_NOT_FOUND. Before the first build, every request answers an empty list. Suggest has its own rate limit, twice that of search, because it fires on every keystroke: 1200 requests a minute per key and 2400 per client IP.

The cabinet's Preview uses a second route that takes the index id instead of the suggest key and answers the same:

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

Call the public route from the shopper's browser with a public key whose allowed origins list your shop's domains. From a server, use a secret key with read access, scoped to the index: a server sends no Origin header, so a public key answers 403 ORIGIN_NOT_ALLOWED there.

Suggestion kinds

kindComes fromfacetHint
queryA search that shoppers made and that found productsThe category most of its products sit in, when there is one
fieldA value of one of the configured fieldsThat field and value
customA custom suggestionThe hint you gave it, or null

Queries are shown as they are stored, lowercased with spaces collapsed. Field values and custom suggestions keep the spelling you gave them.

Common mistakes

  • No suggestions on a new store. Queries need searches first. Add the brand field under Field values and a few custom suggestions, then press Rebuild now.
  • A change to the field list does nothing. Field values, the minimum count and the lookback only apply with the next build.
  • Suggestions from tests and the playground. Searches with a saved profile from the cabinet playground are logged like storefront searches. Keep minQueryCount at 2 or more and send a sessionId from the storefront, so a handful of test searches from one person stays out.