textstring
Free-text query, matched VISUALLY against material imagery ("striped wallpaper", "warm terrazzo"). A bare colour word ("sage") automatically runs as a colour-only search.
textModesenum[]
How to interpret `text`. Default ["visual"] — a text→image VISUAL search. "lexical" (opt-in) runs a BM25 ATTRIBUTE-lens search over material names + canonical attribute terms (find by what it's called / what it IS); detected colour words are stripped from the lexical terms and reranked instead. Requesting BOTH ["visual","lexical"] runs the visual search and notes it — compose a separate lexical search to blend them.
visuallexical
coloursobject[]
Explicit colour palette to match. Each entry is EITHER a `hex` OR a `name` (a descriptive or brand paint name resolved server-side — never invent a hex for a name). PRECEDENCE: when set, these override any colour word detected in `text`. Unresolvable names fail with a typed error listing them, so you can correct and retry.
hexstring
The colour to match, as 3- or 6-digit hex. Provide EITHER `hex` OR `name`, never both. Only pass `hex` when you already hold an EXACT hex — for a colour NAME use `name` and let the server resolve it.
namestring
A colour NAME to match — a descriptive name ('sage green', 'terracotta', 'warm sand') or a brand paint name ('Gauntlet Gray', 'Hale Navy', 'White Dove'). Resolved server-side to its exact library hex (misspellings are fuzzy-matched). NEVER invent a hex for a name — pass the name here. Provide EITHER `name` OR `hex`, never both.
weightnumber
Relative proportion of this colour in the desired palette (0–1). Weights are normalised across the palette; omit for equal parts.
roleenum
Per-colour swatch eligibility (default 'any'). PRECEDENCE: `colourLogic` governs cross-colour combination (all/any); `role` governs which swatch of a product may satisfy THIS colour, and ANDs on top of the logic. 'is' = the colour must be the product's DOMINANT swatch; 'accent' = the colour must be a minor swatch (proportion 0.05–0.35) and is excluded from the proportion-match term; 'any' = today's nearest-swatch match.
anyisaccent
sourceNamestring
Human name the colour came from (e.g. "sage", "Elephant's Breath") — echoed back for display; never affects matching. (For a name you want RESOLVED to a hex, use `name` instead.)
colourLogicenum
"all" (default): results should contain the whole palette, ranked by average distance + proportion match. "any": results matching ANY palette colour, ranked by their best single-colour distance.
allany
colourToleranceenum
How close a colour must be to count as a match. 'normal' (default) is today's behaviour; 'tight' narrows the OKLab match threshold and prunes far single-colour matches; 'loose' widens the threshold.
tightnormalloose
colourAppearanceobject
HARD appearance gate on the material's DOMINANT colour, independent of the colour palette — works on a text-only query too. Variants without colour extraction are EXCLUDED whenever any axis is set (NULL scalars never match).
lightnessobject
OKLab lightness window (L ∈ [0,1]); dark ≈ 0, light ≈ 1.
warmthobject
OKLab warmth window (b axis); cool < 0 < warm, ≈ −0.1..0.1.
moodenum
Mood-language colour entry — resolves to a curated checked-in colour palette. Use it for evocative mood queries ('coastal', 'moody', 'earthy') rather than a single colour. A mood ALONE runs as a colour search; a mood WITH text reranks the text results by the mood palette (a gentle tint). One of: warm (Warm — Reds, oranges, yellows - inviting and cozy); cool (Cool — Blues, teals, cool grays - calm and professional); earthy (Earthy — Browns, tans, terracotta - natural and grounded); moody (Moody — Deep, saturated, dramatic - rich and atmospheric); bold (Bold — High chroma, vibrant - energetic and eye-catching); light-airy (Light + Airy — Pastels, pale tones - soft and spacious); natural (Natural — Greens, wood tones, stone - organic and balanced); neutral (Neutral — Whites, grays, blacks - versatile and timeless); romantic (Romantic — Soft pinks, mauves, blush - tender and elegant); coastal (Coastal — Sandy beiges, ocean blues, seafoam - relaxed seaside); industrial (Industrial — Cool grays, concrete, metallic - urban and modern); luxe (Luxe — Deep jewel tones, rich emeralds, sapphires - opulent); vintage (Vintage — Muted, dusty tones - nostalgic and timeworn); serene (Serene — Soft blues, sage, muted lavender - calm and peaceful); scandi (Scandi — Warm whites, pale woods, cream - Scandinavian minimalism); cosy (Cosy — Deep plaster, amber, tobacco - enveloping warmth); heritage (Heritage — Rich historical tones with saturated depth - classic and grounded); mid-century (Mid-Century — Olive, mustard, teal, terracotta - retro modern); pastel (Pastel — Sage, duck egg, blush - soft colors with body).
warmcoolearthymoodyboldlight-airy+13 more
sortenum
Re-order the final scored results by a colour-appearance axis (default 'relevance' = the fused score). 'light'/'dark' by dominant lightness, 'vivid'/'muted' by chroma, 'colourful' by overall vibrancy. With search signals present this REORDERS the matches; for pure colour browsing use the dedicated browse surface instead. Variants without colour extraction sink to the end.
relevancelightdarkvividmutedcolourful
similarToanyOf
Find materials that LOOK like a seed image. Supply `variantId` to seed from an existing variant's primary image, or `vector` — a pre-computed halfvec literal (`[a,b,…]`) from an externally-embedded image — to drive the image arm directly. PRECEDENCE: wins over `text` (the response carries a note when both were given).
imageoneOf
A raw incoming image to search by (URL or base64). The HTTP adapter embeds it and sets `similarTo: { vector }`; wins over `text`.
type: urlobject
urlstring<uri>
HTTP(S) URL of the query image. MUST be an https URL.
type: base64object
datastring
Base64-encoded image bytes (or a data URI) the caller already holds — e.g. a form upload — so there is nothing to host.
categoryobject
booststring
Soft category preference — results of this product type score higher but others still appear.
filterstring[]
HARD gate: only these public taxonomy categories are returned. Values are category-group or product-type display names (case-insensitive), or canonical taxonomy keys. A group expands to every child product type; an unknown value errors listing every valid name.
weightsobject
FREE multipliers over the per-signal scores (each signal ∈ [0,1]); no sum-to-1 requirement. Omitted keys use the mode defaults (text: image 1.0 / category 0.5, plus a colour RERANK weight of 0.4 for a strong/explicit colour or 0.25 for a weak/derived one; colour mode: colour 1.0). Max achievable score = sum of active weights.
filtersvariant[]
Typed attribute filters applied as a hard restriction before ranking. Each entry is either a term match (`attributeId` + `term`) or a presence check (`attributeId` + `hasValue: true` — any accepted value). Presence filters always route as hard spec gates. Aesthetic/meaning term filters (pattern, texture, directionality, and the other visual-meaning attributes) are applied as a pool-bounded post-filter over the visual candidate pool rather than a whole-catalog restriction.
Variant 1object
attributeIdstring
Canonical attribute id, e.g. "primary_material" or "fire_rating".
termstring
Canonical term the attribute must equal, e.g. "textile".
hasValue: trueobject
attributeIdstring
Canonical attribute id that must have an accepted value, e.g. "sample_image_mm_per_px".
limitinteger
Results per page (default 24, max 48).
cursorstring
Opaque pagination cursor from a previous response. NOTE: ANN search is approximate — tail items may reorder slightly between pages.
explainboolean
Include per-signal scores on each result (`signals`).
collapseenum
Group results by product before pagination. "product" returns one representative (highest-ranked) variant per product, with hidden siblings counted in `siblingCount`. Default "none" returns every variant unchanged.
noneproduct
countboolean
Opt-in feed total. When true the response carries `counts.variants` (and `counts.products` under `collapse:"product"`). The variant total is EXACT up to a cap of 1000 and reported as `basis:"lowerBound"` beyond it — and ALWAYS `lowerBound` for ANN-ranked pools (image / colour / visual-text / visual-meaning post-filters), where the finite candidate pool is the only honest figure. Counts are never silently approximated: an exact count is labelled `exact`, a capped or pool-bounded one `lowerBound`. Default false (skip the count query entirely).
hasImagesboolean
When true, only return results that have at least one catalog image (a servable card thumbnail). Off by default so search stays honest about the FULL catalog, including image-less records. It filters the LEXICAL attribute lens — the one source that can surface an image-less record; the visual arms (image / colour / text→image) are inherently image-backed, so the flag is a no-op there. The opt-in `counts.variants` feed total honours it too (image-less records are excluded from the count). Default false.
viewenum
Result projection. "full" (default) returns the complete `searchResultItemSchema` (palette, colourMeta, hasImage, siblings, explain signals/meanings). "card" returns the lean `searchCardItemSchema` (identity + name + thumbnail + score) for grid rendering, skipping the per-page palette / appearance / meaning reads. The response echoes the chosen `view`, which discriminates the `results` union.
fullcard