Appearance
Product Discovery
Learn how to search, filter, and sort products to help users find exactly what they're looking for.
Product Filtering
Available filtering options:
- Category filters -
categoryId,categorySlug(matches category + subcategories) - Price ranges -
minPrice,maxPrice(prices in cents) - Text search -
name,producer,origin,search(full-text) - Boolean flags -
isSeasonal,isVqa,isKosher,isBuyable - Numeric ranges -
minAlcoholPercent,maxAlcoholPercent,minVolumeMl,maxVolumeMl
Combine multiple filters for more specific searches.
Filter by Category
Using Category ID
Use case: User selects a category from a dropdown or navigation menu.
graphql
query ProductsByCategory($categoryId: String!) {
products(
filters: {
categoryId: $categoryId
maxPrice: 5000
}
pagination: { first: 20 }
) {
edges {
node {
sku
name
priceInCents
producerName
origin
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Variables:
json
{
"categoryId": "123"
}Using Category Slug
Use case: Building SEO-friendly URLs like /wine/red-wine.
graphql
query WineProducts {
products(
filters: {
categorySlug: "wine/red-wine"
maxPrice: 5000
}
pagination: { first: 20 }
) {
edges {
node {
sku
name
priceInCents
producerName
thumbnailUrl
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Category Matching
Both categoryId and categorySlug match the specified category plus all its subcategories. For example, filtering by "wine" will return red wines, white wines, sparkling wines, etc.
To search for categories by name, see the Categories & Collections guide.
Filter by Price
Use case: User sets a price range slider or selects "Under $20" filter.
Find products under $20:
graphql
query AffordableProducts {
products(
filters: {
categorySlug: "wine"
maxPrice: 2000
}
pagination: { first: 20 }
) {
edges {
node {
sku
name
priceInCents
producerName
origin
unitVolumeMl
thumbnailUrl
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Prices in Cents
All prices are in cents (not dollars). To filter for products under $20, use maxPrice: 2000. To display prices, divide by 100: priceInCents / 100.
Filter by Producer
Use case: User searches for products from their favorite winery or brewery.
graphql
query ProducerProducts($producer: String!, $minPrice: Int!, $maxPrice: Int!) {
products(
filters: {
producer: $producer
minPrice: $minPrice
maxPrice: $maxPrice
}
pagination: { first: 30 }
) {
edges {
node {
sku
name
priceInCents
unitVolumeMl
alcoholPercent
thumbnailUrl
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Variables:
json
{
"producer": "Jackson-Triggs",
"minPrice": 1000,
"maxPrice": 3000
}Filter by Characteristics
Use case: Show only seasonal VQA wines during holiday promotions.
graphql
query SeasonalVQAWines {
products(
filters: {
categorySlug: "wine"
isSeasonal: true
isVqa: true
}
pagination: { first: 20 }
) {
edges {
node {
sku
name
priceInCents
producerName
origin
unitVolumeMl
alcoholPercent
thumbnailUrl
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Boolean Filters
Combine boolean filters to create specific product collections:
isSeasonal: true- Limited-time seasonal productsisVqa: true- VQA (Vintners Quality Alliance) certified winesisKosher: true- Kosher-certified productsisBuyable: true- Currently available for purchase
Omit a filter (or set to null) to include all values.
Combined Filters and Sorting
Use case: User searches for "French Chardonnay under $40, sorted by price".
graphql
query ComplexProductSearch {
products(
filters: {
name: "Chardonnay"
origin: "France"
minPrice: 1500
maxPrice: 4000
isVqa: false
}
pagination: { first: 15 }
sortBy: PRICE
sortDirection: ASC
) {
edges {
node {
sku
name
priceInCents
producerName
origin
unitVolumeMl
alcoholPercent
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}Sorting Products
Available sort fields:
NAME- Alphabetical by product namePRICE- By price (combine withASCfor low-to-high,DESCfor high-to-low)ALCOHOL_PERCENT- By alcohol contentVOLUME- By bottle/package sizePRICE_PER_ALCOHOL_ML- Best value for alcohol contentSELL_RANK_MONTHLY/SELL_RANK_YEARLY- By popularityUPDATED_AT- Recently updated products
Use sortDirection: ASC (ascending) or DESC (descending).
Pagination
Use case: Load more products as user scrolls ("infinite scroll").
graphql
query ProductsPage($after: String) {
products(
filters: { categorySlug: "wine" }
pagination: {
first: 25
after: $after
}
sortBy: NAME
) {
edges {
node {
sku
name
priceInCents
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}To load the next page, pass pageInfo.endCursor as the after parameter:
json
{
"after": "cursor-value-from-previous-response"
}Pagination Best Practices
- Product lists: 20-50 items per page
- Search results: 15-25 items per page
- Infinite scroll: 25-30 items per load
- Performance: Request only the fields you need to reduce response size
- Cursor-based: Always use
pageInfo.endCursorandafterfor consistent results
The API uses Relay-style cursor-based pagination for reliable, consistent paging even when the dataset changes.
Next Steps
- Store Location - Find nearby stores
- Inventory Lookup - Check product availability
- Categories & Collections - Work with categories and collections
- Rate Limits - API usage limits