Products
Products is the core of Picqer. You can only sell and buy items that exists as a product in your catalog. To start managing stock of a product, add the product first and then update its stock.
See also documentation for stock and compositions and product parts.
| Name |
Type |
Required |
Description |
| idproduct |
integer |
generated |
Unique Picqer reference |
| idvatgroup |
integer |
required |
Linked to resource Vatgroups |
| name |
string |
required |
Name of product |
| price |
float |
required |
Price excluding VAT |
| fixedstockprice |
float |
optional |
Fixed stock price of product excluding VAT |
| idsupplier |
integer |
optional |
Linked to resource Suppliers |
| productcode |
string |
required |
Product code of product, needs to be unique |
| productcode_supplier |
string |
optional |
Product code of this product at supplier, used for purchase orders |
| deliverytime |
integer |
optional |
Delivery time from supplier in days |
| description |
string |
optional |
Longer description of product |
| barcode |
string |
optional |
Barcode (usually GS1, EAN13 or UPC code) |
| type |
string |
optional |
Only options: normal (default), unlimited_stock, virtual_composition, composition_with_stock |
| unlimitedstock |
boolean |
optional |
Deprecated in favor of 'type'. When unlimited stock is true, no stock will be monitored for this product |
| weight |
integer |
optional |
Weight of this product in grams |
| length |
integer |
optional |
Length of this product in centimeters. Not available for virtual compositions |
| width |
integer |
optional |
Width of this product in centimeters. Not available for virtual compositions |
| height |
integer |
optional |
Height of this product in centimeters. Not available for virtual compositions |
| minimum_purchase_quantity |
integer |
optional |
The minimum amount you need to purchase from your supplier |
| purchase_in_quantities_of |
integer |
optional |
If you need to purchase this products in batches of x pieces |
| hs_code |
string |
optional |
HS Code for customs |
| country_of_origin |
string |
optional |
Country of origin of this product for customs (needs to be ISO 3166 2-char code) |
| active |
boolean |
optional |
Default true |
| track_lot_numbers |
boolean |
optional |
Whether to require a lot number when stock of this product is registered. Default false. Only available when traceability is enabled for the account. |
| track_expiration_dates |
boolean |
optional |
Whether to require an expiration date when stock of this product is registered. Default false. Only available when traceability is enabled for the account. |
| idfulfilment_customer |
integer |
optional |
Only for Picqer Fulfilment: Linked to belonging fulfilment customer |
| analysis_pick_amount_per_day |
float |
generated |
The average amount this product has been picked per day in the last 28 days |
| analysis_abc_classification |
string |
optional|generated |
Classification of A, B or C product, based on the recent amount of pick actions. Will be updated once every week. If you want to set the classification yourself, disable ABC classification in settings. |
| pricelists |
array |
optional |
Array with pricelists set for the product |
| pricelists.idpricelist |
integer |
required |
Linked to resource Pricelists |
| pricelists.price |
float |
required |
Price of the product set for the pricelist |
Set track_lot_numbers and track_expiration_dates when creating or updating a product. A product is traceable when at least one of these settings is true. Only products with type set to normal can enable tracking; other product types keep both settings false.
The account must have traceability enabled to change these settings. When traceability is disabled, supplied tracking settings are ignored. On updates, omitted settings remain unchanged.
Setting track_lot_numbers to false clears lot numbers from the product's stock locations. Setting track_expiration_dates to false clears expiration dates from those locations. Historical values on picklists, receipts and returns are retained. Enabling tracking again does not restore the cleared location values.
Before changing a traceable product's type, disable both tracking settings in a separate update request. Changing the type while tracking is enabled returns 400 Bad Request with error_code 39, even if the same request also disables tracking.
With this call, you will only get the active products. Provide the inactive parameter to get the inactive products.
GET
https://example.picqer.com/api/v1/products
HTTP/1.1 200 OK
[
{
"idproduct": 626,
"idvatgroup": 18,
"idsupplier": null,
"productcode": "6531",
"name": "HyperKewl Ultra Sport Cooling Vest",
"price": 54.46,
"fixedstockprice": 32.11,
"productcode_supplier": "",
"deliverytime": null,
"description": null,
"barcode": null,
"unlimitedstock": false,
"assembled": false,
"type": "normal",
"weight": 1500,
"length": 30,
"width": 25,
"height": 7,
"minimum_purchase_quantity": 0,
"purchase_in_quantities_of": 0,
"hs_code": null,
"country_of_origin": null,
"active": true,
"created": "2023-03-08 14:22:23",
"updated": "2024-09-13 14:37:11",
"comment_count": 0,
"analysis_abc_classification": "C",
"analysis_pick_amount_per_day": "0.036",
"tags": {
"TopWebshop": {
"idtag": 1075,
"title": "TopWebshop",
"color": "#5993be",
"inherit": true,
"textColor": "#000000"
},
"SummerProducts": {
"idtag": 1156,
"title": "SummerProducts",
"color": "#c7b4f6",
"inherit": true,
"textColor": "#000000"
}
},
"productfields": [
{
"idproductfield": 11,
"title": "Eenheid",
"value": "liter"
}
],
"images": [
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original"
],
"stock": [
{
"idwarehouse": 18,
"stock": 0,
"reserved": 6,
"reservedbackorders": 6,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": -6
}
],
"pricelists": []
},
{
"idproduct": 633,
"idvatgroup": 18,
"idsupplier": null,
"productcode": "6531-RB-7-9",
"name": "Hyperkewl Evaporative Cooling Vest Ultra Blue 7-9yr",
"price": 54.46,
"fixedstockprice": 0,
"productcode_supplier": "",
"deliverytime": null,
"description": null,
"barcode": "857825001442",
"unlimitedstock": false,
"assembled": false,
"type": "normal",
"weight": null,
"length": null,
"width": null,
"height": null,
"minimum_purchase_quantity": 0,
"purchase_in_quantities_of": 0,
"hs_code": null,
"country_of_origin": null,
"active": true,
"tags": {},
"productfields": [
{
"idproductfield": 11,
"title": "Eenheid",
"value": "liter"
}
],
"images": [
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original"
],
"stock": [
{
"idwarehouse": 18,
"stock": 112,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 112
}
],
"pricelists": [
{
"idpricelist": 1198,
"price": 50.25
},
{
"idpricelist": 1154,
"price": 48.75
}
]
}
]
You can filter the products with the following parameters. Add these filters as querystring parameters to the URL.
| Attribute |
Description |
Example |
| inactive |
Only provide this attribute to get the inactive products. Do not provide this attribute if you want to get the active products. |
true |
| tag |
Get the products that have the given tag name associated with them. |
summer |
| type |
Get products of a given type. Valid values are: normal, unlimited_stock, virtual_composition, composition_with_stock. Omitting this parameter returns products of all types. You can specify one type per request. |
normal |
| productcode |
Get the product with the provided productcode. Use this filter to get a single product. |
EJK89272 |
| idsupplier |
Get the products linked to this supplier. |
1532 |
| idproducts |
Get multiple, specific products at once. Limited to 100 products per page and sorting is as normal. |
9283,9928,3049,9922 |
| search |
Fuzzy search with a limited number of characters through the fields name, product code, supplier product code and barcode. It returns a list of results matching the search approximately. Searching for 1 specific product with the product code? Please use the "productcode" filter instead of search. |
|
| idfulfilment_customer |
Get the products for this fulfilment customer. |
623 |
GET
https://example.picqer.com/api/v1/products/{idproduct}
HTTP/1.1 200 OK
{
"idproduct": 633,
"idvatgroup": 18,
"idsupplier": null,
"name": "Hyperkewl Evaporative Cooling Vest Ultra Blue 7-9yr",
"price": 54.46,
"fixedstockprice": 0,
"productcode": "6531-RB-7-9",
"productcode_supplier": "",
"deliverytime": null,
"description": "",
"barcode": "857825001442",
"unlimitedstock": false,
"weight": 200,
"length": 12,
"width": 12,
"height": 6,
"active": true,
"created": "2023-03-08 14:22:23",
"updated": "2024-09-13 14:37:11",
"comment_count": 0,
"analysis_abc_classification": "C",
"analysis_pick_amount_per_day": "0.036",
"tags": {
"SummerProducts": {
"idtag": 1156,
"title": "SummerProducts",
"color": "#c7b4f6",
"inherit": true,
"textColor": "#000000"
}
},
"productfields": [
{
"idproductfield": 11,
"title": "Eenheid",
"value": "liter"
}
],
"images": [
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original",
"https://link-to-image.com/image2867/original"
],
"stock": [
{
"idwarehouse": 18,
"stock": 112,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 112
}
],
"pricelists": [
{
"idpricelist": 1198,
"price": 45.67
}
]
}
POST
https://example.picqer.com/api/v1/products
{
"idvatgroup": 18,
"productcode": "883629-22",
"name": "Hyperkewl Evaporative Cooling Vest Ultra Blue 7-9yr",
"price": 54.46,
"track_lot_numbers": true,
"track_expiration_dates": true
}
HTTP/1.1 201 Created
{
"idproduct": 119692,
"idvatgroup": 18,
"idsupplier": null,
"productcode": "883629-22",
"name": "Hyperkewl Evaporative Cooling Vest Ultra Blue 7-9yr",
"price": 54.46,
"fixedstockprice": 0,
"productcode_supplier": "",
"deliverytime": null,
"description": null,
"barcode": null,
"unlimitedstock": false,
"weight": null,
"length": null,
"width": null,
"height": null,
"minimum_purchase_quantity": 0,
"purchase_in_quantities_of": 0,
"hs_code": null,
"country_of_origin": null,
"show_on_portal": null,
"active": true,
"track_lot_numbers": true,
"track_expiration_dates": true,
"created": "2024-09-12 09:45:16",
"updated": "2024-09-25 08:29:25",
"comment_count": 0,
"analysis_abc_classification": null,
"analysis_pick_amount_per_day": null,
"tags": {},
"productfields": [],
"images": [],
"stock": [
{
"idwarehouse": 6685,
"stock": 0,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 0
},
{
"idwarehouse": 6695,
"stock": 0,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 0
},
{
"idwarehouse": 6832,
"stock": 0,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 0
}
],
"pricelists": []
}
You can update all fields of a product. Two fields are special: active and type.
To make a product inactive: it cannot have stock, cannot be used in compositions and cannot be on open picklists or purchase orders.
To change the type of a product: it cannot have stock, have parts or be on open picklists or purchase orders.
PUT
https://example.picqer.com/api/v1/products/{idproduct}
{
"name": "Hyperkewl Evaporative Cooling Vest Ultra Red",
"price": 51.99,
"track_lot_numbers": true,
"track_expiration_dates": true,
"productfields": [
{
"idproductfield": 11,
"value": "liter"
}
]
}
HTTP/1.1 200 OK
{
"idproduct": 119692,
"idvatgroup": 18,
"idsupplier": null,
"productcode": "883629-22",
"name": "Hyperkewl Evaporative Cooling Vest Ultra Red",
"price": 51.99,
"fixedstockprice": 0,
"productcode_supplier": "",
"deliverytime": null,
"description": null,
"barcode": null,
"unlimitedstock": false,
"assembled": false,
"type": "normal",
"weight": null,
"length": null,
"width": null,
"height": null,
"minimum_purchase_quantity": 0,
"purchase_in_quantities_of": 0,
"hs_code": null,
"country_of_origin": null,
"active": true,
"track_lot_numbers": true,
"track_expiration_dates": true,
"created": "2024-08-13 10:01:06",
"updated": "2024-09-25 10:20:18",
"comment_count": 0,
"analysis_abc_classification": null,
"analysis_pick_amount_per_day": null,
"tags": {},
"productfields": [
{
"idproductfield": 11,
"title": "Eenheid",
"value": "liter"
}
],
"images": [],
"stock": [
{
"idwarehouse": 6685,
"stock": 0,
"reserved": 0,
"reservedbackorders": 0,
"reservedpicklists": 0,
"reservedallocations": 0,
"freestock": 0
}
],
"pricelists": []
}
With this call, you remove the pricelist-specific price from a product.
DELETE
https://example.picqer.com/api/v1/products/{idproduct}/pricelists/{idpricelist}
HTTP/1.1 204 No Content
With a POST request on https://example.picqer.com/api/v1/products/{idproduct}/inactivate you can inactivate a product. A product cannot have stock, be on open picklists, have backorders or be on open purchase orders when you want to inactivate it. You will get an error while trying.
You can also re-activate a product with a POST request on https://example.picqer.com/api/v1/products/{idproduct}/activate
Information about product stock is moved to seperate docs page.
Information about product stock is moved to seperate docs page.
Each product can have different settings per warehouse. You can get the current settings for all warehouses with this request.
GET
https://example.picqer.com/api/v1/products/{idproduct}/warehouses
HTTP/1.1 200 OK
[
{
"idproduct":954712,
"idwarehouse":18,
"stock_level_order":3,
"stock_level_desired":5,
"stock_level_maximum":0,
"picking_stock_replenish_trigger":null,
"picking_stock_replenish_to":null,
"stock_location":"AB.291"
},
{
"idproduct":954712,
"idwarehouse":1389,
"stock_level_order":2,
"stock_level_desired":0,
"stock_level_maximum":0,
"picking_stock_replenish_trigger":null,
"picking_stock_replenish_to":null,
"stock_location":"EK.928"
}
]
You can update the product warehouses settings on a per-warehouse basis with this request.
The stock_location field is deprecated but will remain available for backwards compatibility. It is replaced by dedicated locations, and you can link products to existing locations. If you enter a location in stock_location that does not exist yet, we will create it for you. You can enter multiple locations by separating them by a comma: "A.12, A.21".
PUT
https://example.picqer.com/api/v1/products/{idproduct}/warehouses/{idwarehouse}
{
"stock_level_order":5,
"stock_level_desired":10,
"stock_level_maximum":0,
"picking_stock_replenish_trigger":2,
"picking_stock_replenish_to":25,
"stock_location":"AB.221"
}
HTTP/1.1 200 OK
{
"idproduct":954712,
"idwarehouse":18,
"stock_level_order":5,
"stock_level_desired":10,
"stock_level_maximum":0,
"picking_stock_replenish_trigger":2,
"picking_stock_replenish_to":25,
"stock_location":"AB.221"
}
GET
https://example.picqer.com/api/v1/products/{idproduct}/images
HTTP/1.1 200 OK
[
{
"idproduct_image": 12123,
"idproduct": 1105343,
"url": "https://cdn.example.com/3123/1e7af8e2/original.jpg",
"contenttype": "image/jpeg",
"size": 7210
},
{
"idproduct_image": 12222,
"idproduct": 1105343,
"url": "https://cdn.example.com/3123/a1b483f2/original.jpg",
"contenttype": "image/jpeg",
"size": 67210
}
]
Only JPEG and PNG images are allowed. Encode them as a base64 string to feed to the API.
POST
https://example.picqer.com/api/v1/products/{idproduct}/images
{
"image": "--base64 encoded image--"
}
HTTP/1.1 201 Created
{
"idproduct_image": 12124,
"idproduct": 1105345,
"url": "https://cdn.example.com/3123/1e7af8e2/original.jpg",
"contenttype": "image/jpeg",
"size": 7210
}
DELETE
https://example.picqer.com/api/v1/products/{idproduct}/images/{idproduct_image}
HTTP/1.1 204 No Content
A product can be located at none, one or more locations.
The mentioned stock is for this specific location, a product can have stock on other locations and on "no specific location". Use stock endpoint for complete information all stock of a product.
For accounts with access to traceability, product location responses also include lot_number and expiration_date. Either field can be null when no value is recorded. Expiration dates use Y-m-d format.
GET
https://example.picqer.com/api/v1/products/{idproduct}/locations
HTTP/1.1 200 OK
[
{
"idlocation": 4,
"idwarehouse": 13,
"parent_idlocation": 3,
"type": "location",
"name": "A.1.1.A",
"remarks": null,
"unlink_on_empty": false,
"location_type": {
"idlocation_type": 2,
"name": "Standaard",
"default": true,
"color": "#0000f0"
},
"is_bulk_location": true,
"stock_for_product": {
"stock": 31,
"stock_reserved_picklists": 0
},
"note": "Lorem ipsum dolor sit.",
"is_preferred": true,
"lot_number": "LOT-2026-001",
"expiration_date": "2027-01-15"
}
]
POST
https://example.picqer.com/api/v1/products/{idproduct}/locations
{
"idlocation": 5,
"note": null,
"is_preferred": false
}
HTTP/1.1 201 Created
{
"idlocation": 5,
"idwarehouse": 13,
"parent_idlocation": 3,
"type": "location",
"name": "A.1.1.B",
"remarks": null,
"unlink_on_empty": false,
"location_type": {
"idlocation_type": 2,
"name": "Standaard",
"default": true,
"color": "#0000f0"
},
"is_bulk_location": false,
"stock_for_product": {
"stock": 4,
"stock_reserved_picklists": 1
},
"note": null,
"is_preferred": false,
"lot_number": null,
"expiration_date": null
}
| Name |
Type |
Required |
Description |
| idlocation |
integer |
required |
Linked to resource Locations. |
| note |
string |
optional |
Add a note to this product location. Passing null will remove the note. |
| is_preferred |
boolean |
optional |
Set the provided location as the preferred location for this product.
Only one location per product, per warehouse can be set as the preferred location.
Thus, setting a new location as preferred will unset the existing one.
|
| lot_number |
string |
optional (PUT only) |
Correct the lot number on this product location. Requires account traceability and track_lot_numbers to be enabled. Maximum 255 characters. Omitted or null values leave the lot number unchanged. |
| expiration_date |
string |
optional (PUT only) |
Correct the expiration date on this product location. Requires account traceability and track_expiration_dates to be enabled. Use a valid date in Y-m-d format; past dates are allowed. Omitted or null values leave the date unchanged. |
You can update the note, preferred setting, lot number and expiration date of an existing product location. Correcting lot details replaces the recorded values without changing stock quantities or reservations. The existing permission to link products to locations (LOCATIONS_LINK) is sufficient.
You can correct either lot field independently. Omitted or null lot fields remain unchanged; they cannot be cleared through this endpoint. Empty strings, invalid values or nonempty values for tracking that is not enabled return 422 Unprocessable Entity with field messages in the top-level errors object. Validation happens before any changes to lot details, the note or the preferred setting are saved.
PUT
https://example.picqer.com/api/v1/products/{idproduct}/locations/{idlocation}
{
"note": "Lorem ipsum dolor sit.",
"is_preferred": true,
"lot_number": "LOT-2026-001",
"expiration_date": "2027-01-15"
}
HTTP/1.1 200 OK
{
"idlocation": 5,
"idwarehouse": 13,
"parent_idlocation": 3,
"type": "location",
"name": "A.1.1.B",
"remarks": null,
"unlink_on_empty": false,
"location_type": {
"idlocation_type": 2,
"name": "Standaard",
"default": true,
"color": "#0000f0"
},
"is_bulk_location": false,
"stock_for_product": {
"stock": 4,
"stock_reserved_picklists": 1
},
"note": "Lorem ipsum dolor sit.",
"is_preferred": true,
"lot_number": "LOT-2026-001",
"expiration_date": "2027-01-15"
}
Only locations without stock can be unlinked from a product. Move or remove the stock first before you unlink a location.
Unlinking will remove the note and preferred setting, if applicable.
DELETE
https://example.picqer.com/api/v1/products/{idproduct}/locations/{idlocation}
HTTP/1.1 204 No Content
Products can have tags linked to them.
GET
https://example.picqer.com/api/v1/products/{idproduct}/tags
HTTP/1.1 200 OK
[
{
"idtag":11,
"title":"Winter",
"color":"#03008a",
"inherit":false,
"textColor":"#FFFFFF"
},
{
"idtag":13,
"title":"Hoeden",
"color":"#03008a",
"inherit":false,
"textColor":"#FFFFFF"
}
]
POST
https://example.picqer.com/api/v1/products/{idproduct}/tags
{
"idtag": 223
}
HTTP/1.1 201 Created
{
"idtag":223,
"title":"Zomer",
"color":"#03008a",
"inherit":false,
"textColor":"#FFFFFF"
}
DELETE
https://example.picqer.com/api/v1/products/{idproduct}/tags/{idtag}
HTTP/1.1 204 No Content
GET
https://example.picqer.com/api/v1/products/{idproduct}/pricehistory
HTTP/1.1 200 OK
[
{
"oldprice": 0,
"pricechange": 5.23,
"newprice": 5.23,
"iduser": 13089,
"date": "2022-04-08 12:34:59"
},
{
"oldprice": 5.23,
"pricechange": 0.13,
"newprice": 5.36,
"iduser": 20603,
"date": "2022-07-12 16:35:09"
},
{
"oldprice": 5.36,
"pricechange": 0.39,
"newprice": 5.75,
"iduser": 13089,
"date": "2023-01-02 16:49:15"
},
{
"oldprice": 5.75,
"pricechange": 0.24,
"newprice": 5.99,
"iduser": 20603,
"date": "2023-11-22 11:23:20"
},
{
"oldprice": 5.99,
"pricechange": -0.19,
"newprice": 5.8,
"iduser": 13089,
"date": "2024-01-02 13:35:27"
},
{
"oldprice": 5.8,
"pricechange": -0.05,
"newprice": 5.75,
"iduser": 13089,
"date": "2024-01-02 16:36:36"
}
]
GET
https://example.picqer.com/api/v1/products/{idproduct}/fixedstockpricehistory
HTTP/1.1 200 OK
[
{
"old_fixedstockprice": 4.23,
"fixedstockprice_change": 0.22,
"new_fixedstockprice": 4.45,
"iduser": 13089,
"date": "2023-12-21 09:02:49"
},
{
"old_fixedstockprice": 4.45,
"fixedstockprice_change": -0.24,
"new_fixedstockprice": 4.21,
"iduser": 20603,
"date": "2023-12-30 11:01:57"
},
{
"old_fixedstockprice": 4.21,
"fixedstockprice_change": 0.54,
"new_fixedstockprice": 4.75,
"iduser": 13089,
"date": "2024-01-02 09:11:05"
},
{
"old_fixedstockprice": 4.75,
"fixedstockprice_change": 0.07,
"new_fixedstockprice": 4.82,
"iduser": 13089,
"date": "2024-01-03 08:28:14"
}
]
Gives you all the outstanding purchase order lines for this product, in order of expected arrival date. The amount_to_receive gives the amount that is to receive at this moment.
GET
https://example.picqer.com/api/v1/products/{idproduct}/expected
HTTP/1.1 200 OK
[
{
"idpurchaseorder": 19,
"idpurchaseorder_product": 321,
"idwarehouse": 1,
"amount_to_receive": 4,
"delivery_date": "2023-12-01"
},
{
"idpurchaseorder": 19,
"idpurchaseorder_product": 334,
"idwarehouse": 1,
"amount_to_receive": 1,
"delivery_date": "2023-12-01"
},
{
"idpurchaseorder": 6,
"idpurchaseorder_product": 34,
"idwarehouse": 1,
"amount_to_receive": 2,
"delivery_date": "2023-12-06"
},
{
"idpurchaseorder": 20,
"idpurchaseorder_product": 344,
"idwarehouse": 1,
"amount_to_receive": 1,
"delivery_date": null
},
{
"idpurchaseorder": 21,
"idpurchaseorder_product": 345,
"idwarehouse": 2,
"amount_to_receive": 1,
"delivery_date": null
}
]
Comments are supported on products.