Products
Products represent sellable items at a merchant location. Product responses include pricing, stock quantity, product copy, images, inventory details, merchant/location details, and the collections the product belongs to.
Products represent sellable items at a merchant location. Product responses include pricing, stock quantity, product copy, images, inventory details, merchant/location details, and the collections the product belongs to.
List Products
GET /v1/products
Returns paginated products for the authenticated token's merchant.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number to return. |
perPage | number | 100 | Number of products per page. |
sortBy | string | createdAt | Product field to sort by. Common values are createdAt, updatedAt, price, quantity, status, featured, handle, and currency. |
sortOrder | string | desc | Sort direction. Use asc or desc. |
Example
const response = await fetch(
'https://api.shopquery.ai/v1/products?page=1&perPage=20&sortBy=price&sortOrder=asc',
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/json'
}
}
)
const products = await response.json()
import axios from 'axios'
const { data: products } = await axios.get(
'https://api.shopquery.ai/v1/products',
{
params: {
page: 1,
perPage: 20,
sortBy: 'price',
sortOrder: 'asc'
},
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/json'
}
}
)
Response
{
"meta": {
"total": 1,
"perPage": 20,
"currentPage": 1,
"lastPage": 1,
"firstPage": 1,
"firstPageUrl": "/v1/products?page=1",
"lastPageUrl": "/v1/products?page=1",
"nextPageUrl": null,
"previousPageUrl": null
},
"data": [
{
"id": "prd_abc123",
"handle": "classic-shirt",
"quantity": 24,
"price": 29.99,
"currency": "USD",
"status": "published",
"featured": false,
"title": "Classic Shirt",
"subtitle": "Cotton button-down shirt",
"description": "A lightweight everyday shirt.",
"barcode": "1234567890123",
"variants": [{ "key": "Size", "value": "Medium" }],
"specifications": { "material": "Cotton" },
"images": [
{
"path": "products/classic-shirt.jpg",
"mimeType": "image/jpeg",
"role": "image",
"url": {
"upload": "https://...",
"download": "https://..."
}
}
],
"collections": [
{
"id": "col_abc123",
"name": "New Arrivals",
"handle": "new-arrivals",
"description": "Recently added products.",
"status": "published",
"createdAt": "2026-05-13T10:00:00.000+00:00",
"updatedAt": "2026-05-13T10:00:00.000+00:00"
}
],
"createdAt": "2026-05-13T10:00:00.000+00:00",
"updatedAt": "2026-05-13T10:00:00.000+00:00"
}
]
}
Search Products
POST /v1/products/search
Searches merchant-scoped products and returns the matched product with search metadata. Results are ordered by search relevance.
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search text. |
limit | number | No | Maximum number of search matches to consider. Defaults to 10. |
Example
const response = await fetch('https://api.shopquery.ai/v1/products/search', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'cotton shirt',
limit: 10
})
})
const results = await response.json()
import axios from 'axios'
const { data: results } = await axios.post(
'https://api.shopquery.ai/v1/products/search',
{
query: 'cotton shirt',
limit: 10
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/json'
}
}
)
Response
[
{
"product": {
"id": "prd_abc123",
"handle": "classic-shirt",
"quantity": 24,
"price": 29.99,
"currency": "USD",
"status": "published",
"featured": false,
"title": "Classic Shirt",
"images": [],
"collections": []
},
"search": {
"index": 0,
"results": [
{
"product_id": "prd_abc123",
"location_id": "loc_abc123",
"type": "title",
"text": "Classic Shirt"
}
]
}
}
]
The product object has the same shape as products from GET /v1/products. The search.index field represents the product's first position in the underlying search results.