Contents
Prices and stock
The two most frequent updates, per product or in bulk by variant SKU (up to 1,000 lines). Only the price lists and locations you send change.
Base URL, authentication and conventions of this API are on the Catalog API page.
/products/{product}/pricesSet prices of a product
One line per variant and price list (up to 500). Price lists not sent do not change.
Path parameters
productstringrequiredProduct id or SKU.
Example:TEE-001
Headers
Idempotency-KeystringAny string of 1–255 printable ASCII characters, unique per change you mean (a UUID is fine). Sending the same request again with the same key within 48 hours returns the first answer without doing the work again (header
Idempotent-Replayed: true). The same key with a different request is a409 idempotency_key_reused; while the first request is still running,409 idempotency_key_in_progresswithRetry-After: 1. Answers429and5xxare not stored: retry them with the same key.max length 255Example:2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44
Request bodyapplication/json
pricesarray of object & PriceInputrequiredmin items 1max items 500Attributes of each item
variant_skustringrequiredSKU of a variant of this product.
price_liststringrequiredPrice list code (
GET /price-lists).pricenumberrequiredmin 0sale_pricenumber | nullDiscounted price on that list.
min 0
Responses
200All variants of the product as they are now, and what happened.application/json
dataarray of VariantrequiredAttributes of each item
idintegerskustringbarcodestring | nulloptionsobjectThe options that tell variants apart: attribute code → option code (
{"size": "m"}). Option codes are normalised, so a size sent asMcomes back asm.coststring | nullweightnumber | nullweight_unitstring | nullpricesarray of objectAttributes of each item
price_liststringcurrencystring | nullpricestring | nullExample:19.90sale_pricestring | null
stockarray of objectAttributes of each item
locationstringavailableintegeron_handinteger
resultWriteResultrequiredChild attributes
statusstringrequiredpartial: some variants could not be written (seeerrors), the rest was.skipped: the key's field rule left nothing to write.One ofcreatedupdatedpartialskippederrorsarray of objectrequiredAttributes of each item
variant_skustring | nullmessagestring
notesarray of stringrequiredFields not written and why (field rule, field owned by another system).
400The request must change:
validation_failed(seedetails, one list of messages per field),invalid_json,invalid_cursor,product_not_written,variant_not_written,not_written,image_not_downloadable. application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
404
product_not_found,variant_not_found,image_not_found,import_not_found,webhook_not_found, ornot_foundfor a path that does not exist.application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
curl -X PUT https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/prices \
-H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
-H 'Idempotency-Key: 2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44' \
-H 'Content-Type: application/json' \
-d '{
"prices": [
{
"variant_sku": "TEE-001-M",
"price_list": "eu",
"price": 19.9,
"sale_price": 15
},
{
"variant_sku": "TEE-001-L",
"price_list": "eu",
"price": 19.9
}
]
}'const res = await fetch("https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/prices", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.NUCLEO_ACCESS_TOKEN}`,
"Idempotency-Key": "2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44",
"Content-Type": "application/json",
},
body: JSON.stringify({
"prices": [
{
"variant_sku": "TEE-001-M",
"price_list": "eu",
"price": 19.9,
"sale_price": 15
},
{
"variant_sku": "TEE-001-L",
"price_list": "eu",
"price": 19.9
}
]
}),
});
const data = await res.json();
console.log(res.status, data);<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/prices', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('NUCLEO_ACCESS_TOKEN'),
'Idempotency-Key' => '2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44',
],
'json' => [
'prices' => [
[
'variant_sku' => 'TEE-001-M',
'price_list' => 'eu',
'price' => 19.9,
'sale_price' => 15,
],
[
'variant_sku' => 'TEE-001-L',
'price_list' => 'eu',
'price' => 19.9,
],
],
],
'http_errors' => false,
]);
echo $response->getStatusCode(), PHP_EOL;
echo $response->getBody();{
"data": [
{
"id": 1,
"sku": "string",
"barcode": "string",
"options": {},
"cost": "string",
"weight": 1.5,
"weight_unit": "string",
"prices": [
{
"price_list": "string",
"currency": "string",
"price": "19.90",
"sale_price": "string"
}
],
"stock": [
{
"location": "string",
"available": 1,
"on_hand": 1
}
]
}
],
"result": {
"status": "created",
"errors": [
{
"variant_sku": "string",
"message": "string"
}
],
"notes": [
"string"
]
}
}{
"error": {
"code": "validation_failed",
"message": "The request is not valid: see details.",
"request_id": "7c0f8a1e-3b2d-4e5f-9a6b-1c2d3e4f5a6b",
"details": {
"variants.0.prices.0.price_list": [
"Unknown price list \"usa\". GET /price-lists lists them."
]
}
}
}{
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {}
}
}/products/{product}/stockSet stock of a product
One line per variant and location (up to 500): available replaces the quantity (and the on-hand
quantity) at that location. Locations not sent do not change.
Path parameters
productstringrequiredProduct id or SKU.
Example:TEE-001
Headers
Idempotency-KeystringAny string of 1–255 printable ASCII characters, unique per change you mean (a UUID is fine). Sending the same request again with the same key within 48 hours returns the first answer without doing the work again (header
Idempotent-Replayed: true). The same key with a different request is a409 idempotency_key_reused; while the first request is still running,409 idempotency_key_in_progresswithRetry-After: 1. Answers429and5xxare not stored: retry them with the same key.max length 255Example:2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44
Request bodyapplication/json
stockarray of object & StockInputrequiredmin items 1max items 500Attributes of each item
variant_skustringrequiredlocationstringrequiredLocation code (
GET /locations).availableintegerrequiredReplaces the quantity at that location.
Responses
200All variants of the product as they are now, and what happened.application/json
dataarray of VariantrequiredAttributes of each item
idintegerskustringbarcodestring | nulloptionsobjectThe options that tell variants apart: attribute code → option code (
{"size": "m"}). Option codes are normalised, so a size sent asMcomes back asm.coststring | nullweightnumber | nullweight_unitstring | nullpricesarray of objectAttributes of each item
price_liststringcurrencystring | nullpricestring | nullExample:19.90sale_pricestring | null
stockarray of objectAttributes of each item
locationstringavailableintegeron_handinteger
resultWriteResultrequiredChild attributes
statusstringrequiredpartial: some variants could not be written (seeerrors), the rest was.skipped: the key's field rule left nothing to write.One ofcreatedupdatedpartialskippederrorsarray of objectrequiredAttributes of each item
variant_skustring | nullmessagestring
notesarray of stringrequiredFields not written and why (field rule, field owned by another system).
400The request must change:
validation_failed(seedetails, one list of messages per field),invalid_json,invalid_cursor,product_not_written,variant_not_written,not_written,image_not_downloadable. application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
404
product_not_found,variant_not_found,image_not_found,import_not_found,webhook_not_found, ornot_foundfor a path that does not exist.application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
curl -X PUT https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/stock \
-H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
-H 'Idempotency-Key: 2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44' \
-H 'Content-Type: application/json' \
-d '{
"stock": [
{
"variant_sku": "TEE-001-M",
"location": "main",
"available": 12
}
]
}'const res = await fetch("https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/stock", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.NUCLEO_ACCESS_TOKEN}`,
"Idempotency-Key": "2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44",
"Content-Type": "application/json",
},
body: JSON.stringify({
"stock": [
{
"variant_sku": "TEE-001-M",
"location": "main",
"available": 12
}
]
}),
});
const data = await res.json();
console.log(res.status, data);<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api-catalog.nucleoplatform.com/api/catalog/v1/products/TEE-001/stock', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('NUCLEO_ACCESS_TOKEN'),
'Idempotency-Key' => '2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44',
],
'json' => [
'stock' => [
[
'variant_sku' => 'TEE-001-M',
'location' => 'main',
'available' => 12,
],
],
],
'http_errors' => false,
]);
echo $response->getStatusCode(), PHP_EOL;
echo $response->getBody();{
"data": [
{
"id": 1,
"sku": "string",
"barcode": "string",
"options": {},
"cost": "string",
"weight": 1.5,
"weight_unit": "string",
"prices": [
{
"price_list": "string",
"currency": "string",
"price": "19.90",
"sale_price": "string"
}
],
"stock": [
{
"location": "string",
"available": 1,
"on_hand": 1
}
]
}
],
"result": {
"status": "created",
"errors": [
{
"variant_sku": "string",
"message": "string"
}
],
"notes": [
"string"
]
}
}{
"error": {
"code": "validation_failed",
"message": "The request is not valid: see details.",
"request_id": "7c0f8a1e-3b2d-4e5f-9a6b-1c2d3e4f5a6b",
"details": {
"variants.0.prices.0.price_list": [
"Unknown price list \"usa\". GET /price-lists lists them."
]
}
}
}{
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {}
}
}/pricesSet prices in bulk
Up to 1,000 lines, each for one variant SKU of any product. The answer has one result per line, in order.
Headers
Idempotency-KeystringAny string of 1–255 printable ASCII characters, unique per change you mean (a UUID is fine). Sending the same request again with the same key within 48 hours returns the first answer without doing the work again (header
Idempotent-Replayed: true). The same key with a different request is a409 idempotency_key_reused; while the first request is still running,409 idempotency_key_in_progresswithRetry-After: 1. Answers429and5xxare not stored: retry them with the same key.max length 255Example:2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44
Request bodyapplication/json
pricesarray of object & PriceInputrequiredmin items 1max items 1000Attributes of each item
skustringrequiredVariant SKU.
price_liststringrequiredPrice list code (
GET /price-lists).pricenumberrequiredmin 0sale_pricenumber | nullDiscounted price on that list.
min 0
Responses
200One result per line, in the order sent.application/json
dataarray of ItemResultrequiredAttributes of each item
indexintegerrequiredPosition in the request, from 0.
skustring | nullrequiredproduct_idinteger | nullstatusstringrequiredinvalid: not written because the input is wrong.failed: nothing could be written.One ofcreatedupdatedpartialskippedfailedinvaliderrorsarray of objectrequiredAttributes of each item
fieldstringFor
invalid, the field in error.variant_skustring | nullmessagestring
notesarray of stringrequired
400The request must change:
validation_failed(seedetails, one list of messages per field),invalid_json,invalid_cursor,product_not_written,variant_not_written,not_written,image_not_downloadable. application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
403
read_only_key: this key cannot write.application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
curl -X PUT https://api-catalog.nucleoplatform.com/api/catalog/v1/prices \
-H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
-H 'Idempotency-Key: 2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44' \
-H 'Content-Type: application/json' \
-d '{
"prices": [
{
"sku": "TEE-001-M",
"price_list": "eu",
"price": 21,
"sale_price": null
},
{
"sku": "TEE-002-S",
"price_list": "us",
"price": 25
}
]
}'const res = await fetch("https://api-catalog.nucleoplatform.com/api/catalog/v1/prices", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.NUCLEO_ACCESS_TOKEN}`,
"Idempotency-Key": "2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44",
"Content-Type": "application/json",
},
body: JSON.stringify({
"prices": [
{
"sku": "TEE-001-M",
"price_list": "eu",
"price": 21,
"sale_price": null
},
{
"sku": "TEE-002-S",
"price_list": "us",
"price": 25
}
]
}),
});
const data = await res.json();
console.log(res.status, data);<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api-catalog.nucleoplatform.com/api/catalog/v1/prices', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('NUCLEO_ACCESS_TOKEN'),
'Idempotency-Key' => '2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44',
],
'json' => [
'prices' => [
[
'sku' => 'TEE-001-M',
'price_list' => 'eu',
'price' => 21,
'sale_price' => null,
],
[
'sku' => 'TEE-002-S',
'price_list' => 'us',
'price' => 25,
],
],
],
'http_errors' => false,
]);
echo $response->getStatusCode(), PHP_EOL;
echo $response->getBody();{
"data": [
{
"index": 1,
"sku": "string",
"product_id": 1,
"status": "created",
"errors": [
{
"field": "string",
"variant_sku": "string",
"message": "string"
}
],
"notes": [
"string"
]
}
]
}{
"error": {
"code": "validation_failed",
"message": "The request is not valid: see details.",
"request_id": "7c0f8a1e-3b2d-4e5f-9a6b-1c2d3e4f5a6b",
"details": {
"variants.0.prices.0.price_list": [
"Unknown price list \"usa\". GET /price-lists lists them."
]
}
}
}{
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {}
}
}/stockSet stock in bulk
Up to 1,000 lines, each for one variant SKU and one location. The answer has one result per line, in order.
Headers
Idempotency-KeystringAny string of 1–255 printable ASCII characters, unique per change you mean (a UUID is fine). Sending the same request again with the same key within 48 hours returns the first answer without doing the work again (header
Idempotent-Replayed: true). The same key with a different request is a409 idempotency_key_reused; while the first request is still running,409 idempotency_key_in_progresswithRetry-After: 1. Answers429and5xxare not stored: retry them with the same key.max length 255Example:2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44
Request bodyapplication/json
stockarray of object & StockInputrequiredmin items 1max items 1000Attributes of each item
skustringrequiredVariant SKU.
locationstringrequiredLocation code (
GET /locations).availableintegerrequiredReplaces the quantity at that location.
Responses
200One result per line, in the order sent.application/json
dataarray of ItemResultrequiredAttributes of each item
indexintegerrequiredPosition in the request, from 0.
skustring | nullrequiredproduct_idinteger | nullstatusstringrequiredinvalid: not written because the input is wrong.failed: nothing could be written.One ofcreatedupdatedpartialskippedfailedinvaliderrorsarray of objectrequiredAttributes of each item
fieldstringFor
invalid, the field in error.variant_skustring | nullmessagestring
notesarray of stringrequired
400The request must change:
validation_failed(seedetails, one list of messages per field),invalid_json,invalid_cursor,product_not_written,variant_not_written,not_written,image_not_downloadable. application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
403
read_only_key: this key cannot write.application/jsonerrorobjectrequiredChild attributes
codestringrequiredStable machine-readable code. Branch on it, not on the message.
messagestringrequiredrequest_idstringrequiredSame as the
X-Request-Idheader. Quote it to support.detailsobject
curl -X PUT https://api-catalog.nucleoplatform.com/api/catalog/v1/stock \
-H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
-H 'Idempotency-Key: 2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44' \
-H 'Content-Type: application/json' \
-d '{
"stock": [
{
"sku": "TEE-001-M",
"location": "main",
"available": 12
},
{
"sku": "TEE-001-L",
"location": "main",
"available": 0
}
]
}'const res = await fetch("https://api-catalog.nucleoplatform.com/api/catalog/v1/stock", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.NUCLEO_ACCESS_TOKEN}`,
"Idempotency-Key": "2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44",
"Content-Type": "application/json",
},
body: JSON.stringify({
"stock": [
{
"sku": "TEE-001-M",
"location": "main",
"available": 12
},
{
"sku": "TEE-001-L",
"location": "main",
"available": 0
}
]
}),
});
const data = await res.json();
console.log(res.status, data);<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://api-catalog.nucleoplatform.com/api/catalog/v1/stock', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('NUCLEO_ACCESS_TOKEN'),
'Idempotency-Key' => '2b5c0d2e-7d2a-4f6e-9a51-0c8a1e7f3b44',
],
'json' => [
'stock' => [
[
'sku' => 'TEE-001-M',
'location' => 'main',
'available' => 12,
],
[
'sku' => 'TEE-001-L',
'location' => 'main',
'available' => 0,
],
],
],
'http_errors' => false,
]);
echo $response->getStatusCode(), PHP_EOL;
echo $response->getBody();{
"data": [
{
"index": 1,
"sku": "string",
"product_id": 1,
"status": "created",
"errors": [
{
"field": "string",
"variant_sku": "string",
"message": "string"
}
],
"notes": [
"string"
]
}
]
}{
"error": {
"code": "validation_failed",
"message": "The request is not valid: see details.",
"request_id": "7c0f8a1e-3b2d-4e5f-9a6b-1c2d3e4f5a6b",
"details": {
"variants.0.prices.0.price_list": [
"Unknown price list \"usa\". GET /price-lists lists them."
]
}
}
}{
"error": {
"code": "string",
"message": "string",
"request_id": "string",
"details": {}
}
}