The Discovery API has three top level queries for browsing, searching and autocomplete. There are all optimized for read performance.
The Discovery API offers three query types — browse, search, and autocomplete — that share the same toolbox: full-text search, filtering, faceting, sorting, pagination, ranking, and personalization. This page is the reference for those shared concepts; the per-query pages cover how each query type applies them.
Browse queries are your go-to for fetching items of a given shape from your Crystallize tenant. They share the same capabilities as search queries — filtering, faceting, sorting, and pagination — but target a single shape.
Typical use cases:
See a sample browse query below.
Search queries have the same capabilities as browse queries, but query across every shape in your tenant. Because the result set can therefore contain documents of different shapes, your query must handle each shape it expects to receive.
Autocomplete queries are designed for partial matching, typically returning a small subset of the data available through search and browse.
Use cases:
Every Discovery capability operates on the fields you index. Each indexed field has a type that determines how it can be used — filtered, faceted, sorted, or used to rank results.
Fields are referenced in GraphQL by their mapped name (graphqlMapping), a GraphQL-safe alias for the underlying document path — for example a path such as variants.stock is exposed under a normalized name, since dots and colons are not valid in GraphQL field names. The supported field types and what each one supports:
| Field type | Filter | Facet | Sort | rankBy |
|---|---|---|---|---|
| token | ✓ | ✓ | ✓ | — |
| string / keyword | ✓ | — | — | — |
| autocomplete | ✓ (typeahead) | — | — | — |
| number | ✓ | ✓ | ✓ | ✓ |
| date | ✓ | ✓ | ✓ | ✓ |
| boolean | ✓ | — | — | — |
| geo (GEO_POINT) | ✓ (geo) | — | — | — |
Vocabularies are named vector (embedding) spaces configured per tenant. Each item stores a materialized vector per vocabulary (vectors.<vocabulary>). Vocabularies power the vector-based capabilities: tasteCosine ranking, userTaste personalization, and nearestTo similarity search.
Alongside the structured filter argument, queries accept top-level parameters that scope what is searched:
The filter argument is a tree of field conditions. Each filterable field appears under its mapped name and accepts a type-specific set of operators:
| Operator | Applies to | Description |
|---|---|---|
| exists | all types | Whether the field is present on the document. |
| equals / not_equals | string, number, date, boolean | Exact (in)equality. |
| in / not_in | string, number, date | Value is (not) one of a list. |
| contains / not_contains | string | Substring match. |
| phrase | string | Match an ordered sequence of words. |
| regex / not_regex | string | Regular-expression match. |
| range (gt, gte, lt, lte) | number, date | Open or closed range bounds. |
| autocomplete | autocomplete | Prefix/typeahead match against a partial term; accepts fuzzy options. |
| within | geo | Geo containment (see Geo filtering). |
Fields of type GEO_POINT support the within operator, which matches points contained in a region. Three region shapes are available:
Each point is a { lat, long } pair.
Field conditions combine through nested AND and OR lists, each holding further filter objects, so you can express arbitrarily nested boolean logic. Conditions on different fields at the same level are combined with AND.
On tenant-wide queries (no single shape), type_in restricts results to a list of item types.
Facets return aggregated counts alongside results, for building filterable navigation. Request facets per field; the available facet shapes depend on the field type:
Every facet accepts an optional key — the name under which its result appears in the response. Facet results are returned on the summary (see Results & SearchSummary).
The sorting argument orders results by one or more fields, each with a direction of asc or desc. Token, number, and date fields are sortable. You can also sort by score, the relevance (or rankBy) score of each hit.
Queries support two pagination styles:
rankBy gives you structured control over result ordering. It evaluates a list of weighted terms and sums them into a final score (finalScore = Σ weight × signal). Each term selects one signal:
Each term takes a weight (negative weights penalize). Term-level options include vocabulary, from, field, halfLifeDays, and normalize (min–max normalize the term across the result window before weighting). rankBy itself takes a tieBreaker field for stable ordering of equal scores, and explain to include a per-term score breakdown on each hit. Scoring runs within a bounded top-K window of the text-search candidates.
context.userTaste personalizes ranking using the current shopper's taste. Provide one taste vector per vocabulary; each is compared (cosine similarity) against items' stored vectors and the per-vocabulary scores are summed.
Each userTaste entry has three fields:
For per-vocabulary weighting, or to blend taste with other signals, use rankBy with tasteCosine terms (from: userTaste) instead of relying on context.userTaste alone.
nearestTo powers "more like this": it ranks items by similarity to an anchor item's own stored vector, rather than a supplied taste vector. It takes vocabulary (which vector space), like (the anchor, identified by exactly one of sku or itemId), and k (how many nearest neighbours to return). The anchor item itself is excluded from the results.
Full-text and autocomplete matching can tolerate typos through options.fuzzy:
Every browse and search response contains hits (the matched documents) and a summary.
Each hit is a document exposing common fields such as itemId, name, path, language, type, shape, publicationState, the timestamps createdAt / updatedAt / publishedAt / indexedAt, its score, and a paginationToken for cursor pagination.
The summary carries query-level metadata:
The topics query returns the topics of your tenant. It accepts language, and either path or parentId (parentId takes precedence) to fetch the children of a given topic. Each returned topic exposes id, name, path, parentId, displayColor, and meta.
Product documents expose price helpers so you can resolve prices directly from Discovery results:
At the result-set level, summary.priceRange returns the min and max price across all hits.