List Products
GET/api/v2/products
Get a paginated list of products using Spatie QueryBuilder.
products:readGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Authentication: Requires Bearer token.
Supports both simple query filters (filter[field]=value) and advanced grouped filters (filter_groups tree). Default: shows non-archived products sorted by -created_at.
Allowed sorts: id, sku, name, type, barcode, mpn, hts_code, unit_cost, average_cost, supplier_price, weight, length, width, height, case_quantity, case_weight, daily_average_consumption, daily_average_consumption_net_returns, min_stock_level, total_quantity_sold, total_orders, archived_at, created_at, updated_at
Default pagination: 10 per page.
The response also includes unfiltered_total, the count of rows in the base scope before any user filters are applied — used by the frontend to show export totals.
Stock UoM filters (added 2026-05-30):
filter[stock_uom_id]— by uom_id (exact, comma-separated)filter[stock_uom_code]— by UoM code (advanced text ops)filter[stock_uom_name]— by UoM display name (advanced text ops)
The response includes inventory_non_sellable — physically-present stock in non-sellable bins. It is excluded from inventory_available but is part of On Hand (On Hand = Available + Allocated + On Hold + Non-Sellable).
Also supports hts_code (Harmonized Tariff Schedule code) for filtering (filter[hts_code]) and sorting.
Sparse fieldsets (included):
Pass included a JSON array of response field names to receive only those fields. The server then loads only the data those fields need instead of the full product payload, which makes narrow lookups — resolving a barcode to a product, for example — markedly cheaper. id is always returned. Omitting the parameter returns the complete payload, unchanged.
Example: included=["id","sku","barcode","inventory_available"]
Request
Responses
- 200
- 401
- 403
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.