Products
Your product and service catalogue. A product may or may not track stock; the ones that do get an inventory record in a warehouse.
Use cases: Use the Products API to sync a catalogue, look a product up by SKU or barcode at the point of sale, and keep prices in step with your own system.
GET
/productsList products.
`search` is the only filter this endpoint reads — there is no filtering by vendor or by product kind. `products` and `data` hold the same rows.
Query Parameters
| Name | Type | Description | |
|---|---|---|---|
search | string | Free-text search across name, SKU and manufacturer SKU. | |
limit | number | Items per page. Default 50, clamped to 1-200. | |
offset | number | Row offset to start from (default 0). | |
page | number | 1-based page number (default 1). Converted to an offset; an explicit `offset` wins over it. | |
pageSize | number | Alias of `limit`. Wins over `limit` when both are sent. |
Request
curl -X GET "https://api.glance.co.il/products" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Response
Response
{
"products": [
{
"id": 4102,
"visibleId": "7c1f0a52-59a1-4f0e-9a0b-2d3e4f5a6b7c",
"name": "Website Development",
"sku": "SRV-WEB",
"manufacturerSku": null,
"unit": "project",
"unitCost": 5000,
"buyingPrice": 0,
"isPhysical": false,
"isActive": true,
"groups": []
}
],
"data": "… same rows as `products`",
"page": 1,
"totalCount": 128,
"total": 128,
"totalPages": 3,
"hasMore": true,
"pagination": {
"total": 128,
"limit": 50,
"offset": 0,
"hasMore": true,
"page": 1,
"pageSize": 50,
"totalPages": 3
}
}GET
/products/id/:idGet a single product by its `visibleId`.
Returned flat, not wrapped in `data`. `vendorId` mirrors the row's `entityId`; `vendors` carries each supplier's own SKU and buying price.
Path Parameters
| Name | Type | Description | |
|---|---|---|---|
id | string | required | The product's `visibleId` (a UUID), as returned by `GET /products` — not the numeric `id`. |
Request
curl -X GET "https://api.glance.co.il/products/id/:id" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Response
Response
{
"id": 4102,
"visibleId": "7c1f0a52-59a1-4f0e-9a0b-2d3e4f5a6b7c",
"name": "Website Development",
"sku": "SRV-WEB",
"manufacturerSku": null,
"description": "Design and build",
"unit": "project",
"unitCost": 5000,
"buyingPrice": 0,
"isPhysical": false,
"isActive": true,
"trackSerialNumbers": false,
"minStockLevel": 0,
"maxStockLevel": null,
"vendorId": null,
"vendorIds": [],
"vendors": [],
"groups": [],
"hoursBank": null
}GET
/products/sku/:skuLook a product up by SKU — yours or the manufacturer's. This is the barcode-scanning path.
404 PRODUCT_NOT_FOUND when neither SKU matches.
Path Parameters
| Name | Type | Description | |
|---|---|---|---|
sku | string | required | The product's `sku` or its `manufacturerSku`. Either matches. |
Request
curl -X GET "https://api.glance.co.il/products/sku/:sku" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Response
Response
{
"id": 4102,
"visibleId": "7c1f0a52-59a1-4f0e-9a0b-2d3e4f5a6b7c",
"name": "Website Development",
"sku": "SRV-WEB",
"manufacturerSku": null,
"unit": "project",
"unitCost": 5000,
"vendorIds": [],
"vendors": [],
"groups": []
}POST
/products/createCreate a product.
`productId` is the numeric id, while `GET /products/id/:id` and `PUT /products/edit/:id` take the `visibleId` — read the product back off `GET /products` (or by its SKU) to get that. `inventoryId` is present only when `isWithInventory` was true. `GET /products/next-sku` returns `{ sku }` — the next SKU in your numbering, if you use one.
Body Parameters
| Name | Type | Description | |
|---|---|---|---|
name | string | required | Product name. |
sku | string | required | Your SKU. Also the lookup key for GET /products/sku/:sku. |
manufacturerSku | string | The manufacturer's or supplier's SKU. GET /products/sku/:sku matches on this too, which is what makes barcode scanning work. | |
unit | string | required | Unit of measure, e.g. "יח'", "hours", "kg". |
description | string | Free-text description. | |
unitCost | number | Selling price per unit. Defaults to 0. | |
buyingPrice | number | Cost per unit. Defaults to 0. | |
profitMode | string | "markup" (profit over cost) or "margin" (profit as a share of the price) — how the profit percentage is computed on the pricing screen. | |
isPhysical | boolean | Whether this is a physical good rather than a service. Defaults to true. | |
isWithInventory | boolean | Track stock for this product. Requires `warehouseId`. Defaults to false. | |
warehouseId | number | Warehouse to open the stock record in. Required when `isWithInventory` is true. | |
startingInventory | number | Opening quantity in that warehouse. Defaults to 0. | |
reservedQuantity | number | Quantity to mark as reserved on creation. Defaults to 0. | |
inventoryLocation | string | Free-text location within the warehouse. | |
minStockLevel | number | Reorder threshold. Defaults to 0. | |
maxStockLevel | number | Upper stock threshold. | |
trackSerialNumbers | boolean | Track individual serial numbers for this product. Defaults to false. | |
vendorId | number | Primary vendor (internal numeric id). | |
vendorIds | number[] | Every vendor that supplies this product. Per-vendor prices and SKUs live on the vendor's pricelist, not here. | |
expenseCategoryId | number | Expense category for purchases of this product. | |
incomeCategoryId | number | Income category for sales of this product. | |
fileId | number | Id of an uploaded image for the product. | |
hoursBank | object | Turns the product into an hours-bank package — prepaid time a client draws down against. Only accepted while the "ניהול בנק שעות" module is active for the company; sent otherwise it is rejected. | |
defaultTotalMinutes | number | required | Minutes the package sells by default. |
hourlyRate | number | required | Net (pre-VAT) rate per hour that values the bank. |
billingMode | string | required | "PREPAID" (paid up front, drawn down) or "POSTPAID" (worked first, billed after). |
minSessionMinutes | number | Minimum billable minutes per work session. | |
roundingIncrementMinutes | number | Round each session up to this block, in minutes. | |
defaultExpiryDays | number | Days from issue until the bank expires. Omit or null for no expiry. | |
policyOnExpiry | string | "RECOGNIZE" (breakage — recognise the unused deferred income) or "LIABILITY" (keep it on the books). | |
notifyThresholdPercent | number | Notify the client when this share of the bank is left, 1–100. | |
notifyOnDepletion | boolean | Notify when the bank runs out. | |
notifyOnExpiry | boolean | Notify when the bank expires. | |
notifyChannel | string | "EMAIL", "SMS" or "NONE". | |
monthlyReportEnabled | boolean | Send the client a monthly usage report. | |
currency | string | Three-letter currency code. |
Request
curl -X POST "https://api.glance.co.il/products/create" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"sku": "example_sku",
"manufacturerSku": "example_manufacturerSku",
"unit": "example_unit",
"description": "example_description",
"unitCost": 0,
"buyingPrice": 0,
"profitMode": "example_profitMode",
"isPhysical": true,
"isWithInventory": true,
"warehouseId": 0,
"startingInventory": 0,
"reservedQuantity": 0,
"inventoryLocation": "example_inventoryLocation",
"minStockLevel": 0,
"maxStockLevel": 0,
"trackSerialNumbers": true,
"vendorId": 0,
"vendorIds": "example_vendorIds",
"expenseCategoryId": 0,
"incomeCategoryId": 0,
"fileId": 0,
"hoursBank": {}
}'Response
Response
{
"success": true,
"productId": 4102,
"inventoryId": 771
}PUT
/products/edit/:idUpdate a product. All fields are optional.
Setting `isWithInventory` to true on a product that has no stock record opens one — which is where `inventoryId` in the response comes from. A product that already has one returns 400 INVENTORY_ALREADY_EXISTS.
Path Parameters
| Name | Type | Description | |
|---|---|---|---|
id | string | required | The product's `visibleId` (a UUID). |
Body Parameters
| Name | Type | Description | |
|---|---|---|---|
name | string | Product name. | |
sku | string | Your SKU. Also the lookup key for GET /products/sku/:sku. | |
manufacturerSku | string | The manufacturer's or supplier's SKU. GET /products/sku/:sku matches on this too, which is what makes barcode scanning work. | |
unit | string | Unit of measure, e.g. "יח'", "hours", "kg". | |
description | string | Free-text description. | |
unitCost | number | Selling price per unit. Defaults to 0. | |
buyingPrice | number | Cost per unit. Defaults to 0. | |
profitMode | string | "markup" (profit over cost) or "margin" (profit as a share of the price) — how the profit percentage is computed on the pricing screen. | |
isPhysical | boolean | Whether this is a physical good rather than a service. Defaults to true. | |
isWithInventory | boolean | Track stock for this product. Requires `warehouseId`. Defaults to false. | |
warehouseId | number | Warehouse to open the stock record in. Required when `isWithInventory` is true. | |
startingInventory | number | Opening quantity in that warehouse. Defaults to 0. | |
reservedQuantity | number | Quantity to mark as reserved on creation. Defaults to 0. | |
inventoryLocation | string | Free-text location within the warehouse. | |
minStockLevel | number | Reorder threshold. Defaults to 0. | |
maxStockLevel | number | Upper stock threshold. | |
trackSerialNumbers | boolean | Track individual serial numbers for this product. Defaults to false. | |
vendorId | number | Primary vendor (internal numeric id). | |
vendorIds | number[] | Every vendor that supplies this product. Per-vendor prices and SKUs live on the vendor's pricelist, not here. | |
expenseCategoryId | number | Expense category for purchases of this product. | |
incomeCategoryId | number | Income category for sales of this product. | |
fileId | number | Id of an uploaded image for the product. | |
hoursBank | object | Turns the product into an hours-bank package — prepaid time a client draws down against. Only accepted while the "ניהול בנק שעות" module is active for the company; sent otherwise it is rejected. | |
defaultTotalMinutes | number | required | Minutes the package sells by default. |
hourlyRate | number | required | Net (pre-VAT) rate per hour that values the bank. |
billingMode | string | required | "PREPAID" (paid up front, drawn down) or "POSTPAID" (worked first, billed after). |
minSessionMinutes | number | Minimum billable minutes per work session. | |
roundingIncrementMinutes | number | Round each session up to this block, in minutes. | |
defaultExpiryDays | number | Days from issue until the bank expires. Omit or null for no expiry. | |
policyOnExpiry | string | "RECOGNIZE" (breakage — recognise the unused deferred income) or "LIABILITY" (keep it on the books). | |
notifyThresholdPercent | number | Notify the client when this share of the bank is left, 1–100. | |
notifyOnDepletion | boolean | Notify when the bank runs out. | |
notifyOnExpiry | boolean | Notify when the bank expires. | |
notifyChannel | string | "EMAIL", "SMS" or "NONE". | |
monthlyReportEnabled | boolean | Send the client a monthly usage report. | |
currency | string | Three-letter currency code. | |
isActive | boolean | Deactivate a product to keep its history while taking it out of the catalogue. |
Request
curl -X PUT "https://api.glance.co.il/products/edit/:id" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "example_name",
"sku": "example_sku",
"manufacturerSku": "example_manufacturerSku",
"unit": "example_unit",
"description": "example_description",
"unitCost": 0,
"buyingPrice": 0,
"profitMode": "example_profitMode",
"isPhysical": true,
"isWithInventory": true,
"warehouseId": 0,
"startingInventory": 0,
"reservedQuantity": 0,
"inventoryLocation": "example_inventoryLocation",
"minStockLevel": 0,
"maxStockLevel": 0,
"trackSerialNumbers": true,
"vendorId": 0,
"vendorIds": "example_vendorIds",
"expenseCategoryId": 0,
"incomeCategoryId": 0,
"fileId": 0,
"hoursBank": {},
"isActive": true
}'Response
Response
{
"success": true,
"inventoryId": 771
}DELETE
/products/delete/:idDelete a product.
A product referenced by documents or stock movements cannot be deleted — deactivate it with `isActive: false` instead.
Path Parameters
| Name | Type | Description | |
|---|---|---|---|
id | number | required | The product's numeric `id` — this endpoint takes the numeric id, not the `visibleId` the read and update endpoints take. |
Request
curl -X DELETE "https://api.glance.co.il/products/delete/:id" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Response
Response
{
"success": true
}