The Store API uses Ransack for filtering and sorting collection endpoints. All query parameters are passed via the q parameter.
Filtering
Pass filter conditions using the q parameter with Ransack predicates:
const products = await client.store.products.list({
name_cont: 'shirt',
price_gte: 20,
price_lte: 100,
})
Common Predicates
| Predicate | Description | SDK | cURL |
|---|
eq | Equals | status_eq: 'active' | q[status_eq]=active |
not_eq | Not equals | status_not_eq: 'draft' | q[status_not_eq]=draft |
cont | Contains (case-insensitive) | name_cont: 'shirt' | q[name_cont]=shirt |
start | Starts with | name_start: 'Spree' | q[name_start]=Spree |
end | Ends with | slug_end: 'tote' | q[slug_end]=tote |
lt | Less than | price_lt: 50 | q[price_lt]=50 |
lteq | Less than or equal | price_lteq: 50 | q[price_lteq]=50 |
gt | Greater than | price_gt: 10 | q[price_gt]=10 |
gteq | Greater than or equal | price_gteq: 10 | q[price_gteq]=10 |
in | In a list | status_in: ['active', 'draft'] | q[status_in][]=active&q[status_in][]=draft |
null | Is null | deleted_at_null: true | q[deleted_at_null]=true |
not_null | Is not null | completed_at_not_null: true | q[completed_at_not_null]=true |
present | Is present (not empty) | description_present: true | q[description_present]=true |
blank | Is blank (null or empty) | description_blank: true | q[description_blank]=true |
true | Is true (boolean) | purchasable_true: 1 | q[purchasable_true]=1 |
false | Is false (boolean) | purchasable_false: 1 | q[purchasable_false]=1 |
The SDK automatically wraps filter keys in q[...] and appends [] for array values — just pass flat params.
Combining Filters
Multiple filters are combined with AND logic:
// Products that contain "shirt" AND cost between $20-$100
const products = await client.store.products.list({
name_cont: 'shirt',
price_gteq: 20,
price_lteq: 100,
})
Filtering by Association
You can filter by associated model attributes using underscore notation:
// Products in a specific taxon (category)
const products = await client.store.products.list({
taxons_id_eq: 'txn_abc123',
})
// Taxons at a specific depth
const taxons = await client.store.taxons.list({
depth_eq: 1,
})
Product Scopes
Products support additional filter scopes beyond standard Ransack predicates:
const products = await client.store.products.list({
price_gte: 20, // Minimum price
price_lte: 100, // Maximum price
with_option_value_ids: ['optval_abc', 'optval_def'], // Filter by option values
in_stock: true, // Only in-stock products
})
| Scope | Description | SDK | cURL |
|---|
price_gte | Minimum price | price_gte: 20 | q[price_gte]=20 |
price_lte | Maximum price | price_lte: 100 | q[price_lte]=100 |
with_option_value_ids | Filter by option value IDs | with_option_value_ids: ['optval_abc'] | q[with_option_value_ids][]=optval_abc |
in_stock | Only in-stock products | in_stock: true | q[in_stock]=true |
out_of_stock | Only out-of-stock products | out_of_stock: true | q[out_of_stock]=true |
multi_search | Full-text search | multi_search: 'shirt' | q[multi_search]=shirt |
Sorting
Use the sort parameter to sort product results. The backend handles routing to the appropriate sort mechanism:
// Sort by price
const products = await client.store.products.list({
sort: 'price asc',
})
// Sort by best selling
const products = await client.store.products.list({
sort: 'best_selling',
})
// Sort by name
const products = await client.store.products.list({
sort: 'name asc',
})
Product Sort Options
| Value | Description |
|---|
manual | Manual sort order (default, uses taxon position) |
best_selling | Best selling products first |
price asc | Price low to high |
price desc | Price high to low |
name asc | Name A-Z |
name desc | Name Z-A |
available_on desc | Newest first |
available_on asc | Oldest first |
For other resources, use q[s] with standard Ransack column sorts:
const taxons = await client.store.taxons.list({
sort: 'name asc',
})
All collection endpoints return paginated results. Control pagination with page and limit parameters:
const { data: products, meta } = await client.store.products.list({
page: 2,
limit: 10,
})
// meta contains pagination info
console.log(meta)
// {
// page: 2,
// limit: 10,
// count: 85,
// pages: 9,
// from: 11,
// to: 20,
// in: 10,
// previous: 1,
// next: 3
// }
| Parameter | Default | Max | Description |
|---|
page | 1 | - | Page number |
limit | 25 | 100 | Number of records per page |
Collection responses include a meta object with pagination info:
{
"data": [...],
"meta": {
"page": 1,
"limit": 25,
"count": 85,
"pages": 4,
"from": 1,
"to": 25,
"in": 25,
"previous": null,
"next": 2
}
}
| Field | Description |
|---|
page | Current page number |
limit | Records per page |
count | Total number of records |
pages | Total number of pages |
from | Starting record number on this page |
to | Ending record number on this page |
in | Number of records returned on this page |
previous | Previous page number (null if first page) |
next | Next page number (null if last page) |