Documentation Index Fetch the complete documentation index at: https://mintlify.com/Avelero/avelero/llms.txt
Use this file to discover all available pages before exploring further.
Retrieve a paginated list of products from your catalog with support for filtering, searching, and sorting.
Endpoint
trpc . products . list . query ( input )
Router location : apps/api/src/trpc/routers/products/index.ts:233
Request parameters
UUID of the brand. Must match the active brand context if provided.
Cursor for pagination. Obtained from the previous response’s meta.cursor field.
Number of products to return per page. Range : 1-100Default : 50
Array of field names to return. If omitted, all available fields are returned. Available fields :
id
name
description
brand_id
category_id
season_id
manufacturer_id
image_path
product_handle
upid
status
created_at
updated_at
Search query to filter products by name, description, or other text fields. Max length : 100 characters
Include product variants in the response. Default : false
Include product attributes (materials, environment, etc.) in the response. Default : false
Filtering
Advanced filtering using FilterState structure. Groups are combined with AND logic, conditions within groups are combined with OR logic. Show FilterState structure
{
groups : [
{
id: "group-1" ,
conditions: [
{
id: "condition-1" ,
fieldId: "status" ,
operator: "equals" ,
value: "published"
},
{
id: "condition-2" ,
fieldId: "category" ,
operator: "in" ,
value: [ "uuid-1" , "uuid-2" ]
}
],
asGroup: true
}
]
}
Filter operators :
equals, notEquals
in, notIn
contains, notContains
startsWith, endsWith
greaterThan, lessThan
greaterThanOrEqual, lessThanOrEqual
isEmpty, isNotEmpty
Filter value types :
String
Number
Boolean
Array of strings
Date range: { after: "2024-01-01", before: "2024-12-31" }
Number range: { min: 0, max: 100 }
Relative date: { type: "relative", option: "last 7 days" }
Sorting
Sort configuration Field to sort by Options :
name
status
createdAt
updatedAt
category
season
productHandle
Sort direction Options : "asc" or "desc"Default : "desc"
Response
Pagination metadata Total number of products matching the query
Cursor for fetching the next page. null if no more pages.
Whether more products are available
Example requests
Basic list
const products = await trpc . products . list . query ({
limit: 20
});
console . log ( products . data . length ); // Up to 20 products
console . log ( products . meta . total ); // Total matching products
console . log ( products . meta . hasMore ); // true if more pages available
// First page
const firstPage = await trpc . products . list . query ({
limit: 50
});
// Next page
if ( firstPage . meta . hasMore ) {
const secondPage = await trpc . products . list . query ({
cursor: firstPage . meta . cursor ,
limit: 50
});
}
With search
const products = await trpc . products . list . query ({
search: "cotton" ,
limit: 20
});
// Returns products with "cotton" in name, description, etc.
With filters
const publishedProducts = await trpc . products . list . query ({
filters: {
groups: [
{
id: "status-filter" ,
conditions: [
{
id: "cond-1" ,
fieldId: "status" ,
operator: "equals" ,
value: "published"
}
]
}
]
}
});
Multiple filter conditions (OR logic)
const products = await trpc . products . list . query ({
filters: {
groups: [
{
id: "category-filter" ,
conditions: [
// Products in category A OR category B
{
id: "cond-1" ,
fieldId: "category_id" ,
operator: "equals" ,
value: "category-a-uuid"
},
{
id: "cond-2" ,
fieldId: "category_id" ,
operator: "equals" ,
value: "category-b-uuid"
}
]
}
]
}
});
Multiple filter groups (AND logic)
const products = await trpc . products . list . query ({
filters: {
groups: [
{
id: "status-group" ,
conditions: [
{
id: "status-cond" ,
fieldId: "status" ,
operator: "equals" ,
value: "published"
}
]
},
{
id: "date-group" ,
conditions: [
{
id: "date-cond" ,
fieldId: "created_at" ,
operator: "greaterThan" ,
value: { after: "2024-01-01" }
}
]
}
]
}
});
// Returns products that are published AND created after 2024-01-01
With sorting
const products = await trpc . products . list . query ({
sort: {
field: "createdAt" ,
direction: "desc"
},
limit: 20
});
// Returns 20 most recently created products
With variants and attributes
const products = await trpc . products . list . query ({
includeVariants: true ,
includeAttributes: true ,
limit: 10
});
// Each product includes:
// - variants: Array of variant objects with SKU, barcode, etc.
// - materials: Array of material compositions
// - environment: Environmental impact data
// - journeySteps: Production journey
Field selection
const products = await trpc . products . list . query ({
fields: [ "id" , "name" , "product_handle" , "status" ],
limit: 100
});
// Returns only specified fields (more efficient for large lists)
Complex query
const products = await trpc . products . list . query ({
search: "organic" ,
filters: {
groups: [
{
id: "status-group" ,
conditions: [
{
id: "status-cond" ,
fieldId: "status" ,
operator: "equals" ,
value: "published"
}
]
},
{
id: "season-group" ,
conditions: [
{
id: "season-cond" ,
fieldId: "season_id" ,
operator: "in" ,
value: [ "spring-2024" , "summer-2024" ]
}
]
}
]
},
sort: {
field: "name" ,
direction: "asc"
},
limit: 50 ,
includeVariants: true
});
Date range filters
// Products created in 2024
const products = await trpc . products . list . query ({
filters: {
groups: [
{
id: "date-range" ,
conditions: [
{
id: "created-2024" ,
fieldId: "created_at" ,
operator: "between" ,
value: {
after: "2024-01-01T00:00:00Z" ,
before: "2024-12-31T23:59:59Z"
}
}
]
}
]
}
});
Relative date filters
// Products created in the last 7 days
const products = await trpc . products . list . query ({
filters: {
groups: [
{
id: "recent" ,
conditions: [
{
id: "last-week" ,
fieldId: "created_at" ,
operator: "relative" ,
value: {
type: "relative" ,
option: "last 7 days"
}
}
]
}
]
}
});
Available relative options :
today
yesterday
last 7 days
last 30 days
this month
last month
this quarter
this year
more than X days ago (with customDays field)
Performance optimization
Use includeVariants and includeAttributes only when needed. These flags trigger additional database queries and can impact performance for large result sets.
Use field selection to return only the data you need. This reduces response size and improves query performance.
// Efficient query for dropdown lists
const products = await trpc . products . list . query ({
fields: [ "id" , "name" , "product_handle" ],
limit: 100
});
Error codes
Invalid input or validation error Common causes :
limit exceeds 100
Invalid field name in fields array
Active brand does not match brand_id
Invalid filter structure
Invalid sort field
Validation rules
limit : 1-100 (default: 50)
search : Max 100 characters
fields : Must be valid product field names from PRODUCT_FIELDS
brand_id : Must match active brand context if provided
Source code reference
Schema definition : apps/api/src/schemas/products.ts:519 (productsDomainListSchema)
Implementation : apps/api/src/trpc/routers/products/index.ts:233
Database query : @v1/db/queries/products (listProductsWithIncludes)
Available fields : apps/api/src/schemas/products.ts:45 (PRODUCT_FIELDS)