Product Synchronization
Every product must be known to Paxon before it can be delivered to a warehouse or ordered. Your application, such as a webshop or ERP, is leading for the product details: create new products in Paxon and update the ones that changed. Paxon is leading for the stock, which is described in Stock Level Synchronization.
The sku identifies a product in both systems. Paxon also gives every product its own id, which you need to update the product. Store this id with the product in your application, so you don't have to look it up every time.
All examples below leave out the Authorization header, which is required on every request. See Authenticating.
Creating and updating products
When a product is created or changed in your application, check whether Paxon already knows it. If not, create it; if so, update it.
Looking up products
Use GET v3/products with a filter on sku to find out whether products exist. The filter accepts several comma-separated SKUs, so you can check a batch of products in one request. Each SKU must be URL encoded, because a comma inside a SKU would otherwise split it in two.
GET {host}/v3/products?filter[sku][in]=VDB-400,TSH-000-S HTTP/1.1
Accept: application/json
The response contains a product resource for every SKU that exists. A SKU that's missing from data doesn't exist yet:
{
"data": [
{
"id": 540935,
"type": "product",
"attributes": {
"sku": "VDB-400",
"status": "AVAILABLE",
"stockLevelType": "AVAILABLE",
"name": "Van Dyke Brown - 400ml tube",
"hasBarcode": true,
"barcode": "8719558651276"
},
"links": {
"self": "https://shopapi.activeants.nl/v3/products/540935"
}
}
],
"links": {
"self": "https://shopapi.activeants.nl/v3/products?filter[sku][in]=VDB-400,TSH-000-S"
}
}
The example is shortened; the full set of attributes is described in GET v3/products. If you already stored the id of a product, you can skip the lookup and update it right away.
Creating a product
Create a product that doesn't exist yet with POST v3/products:
POST {host}/v3/products HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"data": {
"type": "product",
"attributes": {
"sku": "TSH-000-S",
"status": "AVAILABLE",
"stockLevelType": "ECONOMIC",
"name": "Dog Shampoo 100ml",
"description": "Gentle shampoo for dogs, with natural ingredients.",
"hasBarcode": true,
"barcode": "8719558651306",
"hasLotNumber": true,
"hasSerialNumber": false,
"hasExpirationDate": false,
"countryOfOrigin": "CN",
"hsCodes": [
{ "country": "XX", "hsCode": "33079011" }
]
}
}
}
The server responds with 201 Created and the new product, including its id. Store the id in your application.
Keep the following in mind:
- The
skuandbarcodemust be unique, and can't have been used before for another product. A duplicate results in409 Conflict. stockLevelTypesets which stock level you use to synchronize the stock of this product:ECONOMICorAVAILABLE. See Stock Level Synchronization.- The
weight,length,widthandheightare measured when the product is first received in a warehouse, and can't be set through the API.
Updating a product
Update an existing product with PUT v3/products/:id, using the id from Paxon:
PUT {host}/v3/products/1267734 HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"data": {
"id": 1267734,
"type": "product",
"attributes": {
"sku": "TSH-000-S",
"status": "AVAILABLE",
"stockLevelType": "ECONOMIC",
"name": "Dog Shampoo 100ml - Sensitive Skin",
"description": "Gentle shampoo for dogs with sensitive skin, with natural ingredients.",
"hasBarcode": true,
"barcode": "8719558651306",
"hasLotNumber": true,
"hasSerialNumber": false,
"hasExpirationDate": false,
"countryOfOrigin": "CN",
"hsCodes": [
{ "country": "XX", "hsCode": "33079011" }
]
}
}
}
PUT replaces the product: always send all attributes, because attributes you leave out may be erased. Some attributes can't be changed and result in 409 Conflict:
- The
skucan never be changed. - The
barcodecan only be changed as long as there's no stock of the product. - The
weight,length,widthandheightare determined by the warehouse.
Retrieving all products
To check that both systems contain the same products, for example during the initial setup or a periodic check, retrieve all your products with GET v3/products. This endpoint uses cursor-based pagination and returns at most 100 products per page, ordered by id.
Start with the first page:
GET {host}/v3/products?page[size]=100 HTTP/1.1
Accept: application/json
The response contains the products and a next link to the following page:
{
"data": [
/** up to 100 products **/
],
"links": {
"self": "https://shopapi.activeants.nl/v3/products?page[size]=100",
"first": "https://shopapi.activeants.nl/v3/products?page[cursor]=0&page[size]=100",
"next": "https://shopapi.activeants.nl/v3/products?page[cursor]=540938&page[size]=100"
}
}
Request the next link to get the following page, and repeat this until a page contains fewer products than the page[size], or has no next link. Use the links as they are, and don't build the cursor yourself:
let url = `${host}/v3/products?page[size]=100`;
while (url) {
const page = await get(url);
for (const product of page.data) {
// Compare with your application, and store the id by sku
}
url = page.data.length < 100 ? null : page.links?.next;
}
Rate limits
The endpoints are rate limited, and exceeding a limit results in 429 Too Many Requests. The current limits are listed with each endpoint: GET v3/products, POST v3/products and PUT v3/products/:id. To stay within the limits:
- Store the
idof each product, so you don't need a lookup before every update. - Look up products in batches with
filter[sku][in], instead of one request per product. - Only send products that changed in your application.