curl --request GET \
--url https://omnicommerce.sg/api/v1/products \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://omnicommerce.sg/api/v1/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://omnicommerce.sg/api/v1/products"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"items": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"sku": "<string>",
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"isVariant": true,
"stockQuantity": 1,
"variantCount": 1,
"status": "<string>",
"statusFacets": {
"lifecycle": "draft",
"derived": [
"flagged"
],
"zaloraQualityControl": {}
}
}
],
"hasMore": true,
"nextOffset": 123,
"summary": {
"totalCount": 123,
"statusCounts": {}
},
"pagination": {
"offset": 123,
"limit": 123,
"total": 123,
"hasMore": true,
"nextOffset": 123,
"maxLimit": 123,
"defaultLimit": 123
}
}List Products
List products for the authenticated organization with optional filters and pagination. Authenticate with an API key or OAuth bearer token. The organization is taken from that credential; do not send organizationId.
Stock and variants
Rows are in items. Read catalog stock from items[].stockQuantity: parent rows already aggregate their non-deleted variants, and virtual bundles use component availability with any manual cap. Null means unknown, not zero. A row with variantCount above 0 has variants; fetch them from GET /api/v1/products/{productId}. List rows do not contain inventoryQuantity, inventory.quantity, or an embedded variants array.
curl --request GET \
--url https://omnicommerce.sg/api/v1/products \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://omnicommerce.sg/api/v1/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://omnicommerce.sg/api/v1/products"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"items": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"sku": "<string>",
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"isVariant": true,
"stockQuantity": 1,
"variantCount": 1,
"status": "<string>",
"statusFacets": {
"lifecycle": "draft",
"derived": [
"flagged"
],
"zaloraQualityControl": {}
}
}
],
"hasMore": true,
"nextOffset": 123,
"summary": {
"totalCount": 123,
"statusCounts": {}
},
"pagination": {
"offset": 123,
"limit": 123,
"total": 123,
"hasMore": true,
"nextOffset": 123,
"maxLimit": 123,
"defaultLimit": 123
}
}Authorizations
Bearer API key for server-to-server access. Session auth is also supported in first-party UI flows.
Query Parameters
Filter by one catalog view status. Lifecycle values include draft, active, archived and deleted; derived views include flagged, errors, qc_pending and qc_rejected. A product may have a lifecycle value and multiple derived signals simultaneously.
Filter by enabled marketplace.
shopee, lazada, tiktok, shopify, zalora, amazon, ebay Filter by marketplace country (e.g., Singapore, Malaysia).
80Search query for product name or SKU.
200Exact catalog SKU match after trim. Not fuzzy and not substring. Repeat the parameter or comma-separate up to 50 SKUs. Combined with other filters using AND.
200Minimum price filter.
x >= 0Maximum price filter.
x >= 0Sort order for results.
updatedAt, createdAt, name, price Result limit per page. Values above the cap are clamped silently; the applied value is returned in pagination.limit. Defaults to 20.
1 <= x <= 50Zero-based pagination offset. Use pagination.nextOffset from the previous response to page forward. Defaults to 0.
x >= 0