What is the minimal JSON neccessary for updating a product via the API?
The documentation states:
you must enter all fields that exist and enter the ID of product which you want update
Is the solution to load the existing product object from the API and use that for modifications?
API: JSON for product update
Friday, December 27, 2024 8:35:20 PM
Hi,
There are two ways. First is not efficient, second is better. First is available out of the box, second not. So, first: You can make a GET request and get all products from your store. Then find the specified one, take its ID and use to GET by ID request. It will show you the whole JSON for product update.
Better option is to extend API with a plugin and add PUT request which will allow you to update only particular fields from product. Thank you for suggestion, we will add this request out of the box. I've added it to our roadmap, here is an work item.
There are two ways. First is not efficient, second is better. First is available out of the box, second not. So, first: You can make a GET request and get all products from your store. Then find the specified one, take its ID and use to GET by ID request. It will show you the whole JSON for product update.
Better option is to extend API with a plugin and add PUT request which will allow you to update only particular fields from product. Thank you for suggestion, we will add this request out of the box. I've added it to our roadmap, here is an work item.
Best regards,
Patryk
GrandNode Team
Patryk
GrandNode Team
0
Thx for feedback.
OK, so we’re trying the simple solution first: Update using POST to our store API http://[OUR_DOMAIN]/odata/product , with similar JSON as received from GET.
However, the POST gives a 400 Bad Request result. We have not implemented SSL yet so just using http.
I have looked at the API source code and understand that the product’s Id should be specified in the JSON, and not be part of the url, and that it needs to be POST and not PUT.
Authorization is OK using Bearer, and have checked that JSON syntax is valid. I have tried to “wrap” the JSON in different ways with curly braces and labels, but have not been able to get this to work.
I’m pasting the raw request and response from Fiddler below. Any suggestions that can help us solve this are appreciated.
Note: I have not included the contents of the Categories / Manufacturers arrays (etc) in the bottom in the request.
[code]
===========================================
REQUEST (RAW)
===========================================
POST http://[----SNIP---].no/odata/product HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I[----SNIP----]gFN-i7WaIrY6sxLieM
Content-Type: application/json; charset=utf-8
Content-Length: 3977
Host: [----SNIP---].no
{
"ProductType": "SimpleProduct",
"ParentGroupedProductId": null,
"VisibleIndividually": true,
"Name": "CONTINENTALLLLL PREMIUMCONTACT 5",
"SeName": "fahrenheit-451-by-ray-bradbury",
"ShortDescription": "TESTVINNER!",
"FullDescription": "<h4>CONTINENTAL CONTIPREMIUMCONTACT5 </h4>\r\n<ul>\r\n<li>2. plass i ADAC sommerdekktest 2018</li>\r\n<li>Testvinner GTÜ sommerdekktest 2017</li>\r\n<li>Andreplass Aftonbladets sommerdekktest 2017</li>\r\n<li>Testvinner ADAC sommerdekktest 2016</li>\r\n<li>Tredjeplass på sommerdekktestet til NAF 2016</li>\r\n</ul>",
"AdminComment": null,
"ProductTemplateId": "5c6697123945712d04312bdf",
"VendorId": null,
"ShowOnHomePage": false,
"MetaKeywords": null,
"MetaDescription": null,
"MetaTitle": null,
"AllowCustomerReviews": true,
"ApprovedRatingSum": 4,
"NotApprovedRatingSum": 0,
"ApprovedTotalReviews": 1,
"NotApprovedTotalReviews": 0,
"ExternalId": null,
"Sku": "TTPAH45-0S11S",
"ManufacturerPartNumber": null,
"Gtin": null,
"IsGiftCard": false,
"GiftCardType": "Virtual",
"OverriddenGiftCardAmount": null,
"RequireOtherProducts": false,
"RequiredProductIds": null,
"AutomaticallyAddRequiredProducts": false,
"IsDownload": false,
"DownloadId": null,
"UnlimitedDownloads": false,
"DownloadActivationType": "WhenOrderIsPaid",
"MaxNumberOfDownloads": 0,
"DownloadExpirationDays": null,
"HasSampleDownload": false,
"SampleDownloadId": null,
"HasUserAgreement": false,
"UserAgreementText": null,
"IsRecurring": false,
"RecurringCycleLength": 0,
"RecurringTotalCycles": 0,
"RecurringCyclePeriod": "Days",
"IncBothDate": false,
"Interval": 0,
"IntervalUnitType": "Minute",
"IsShipEnabled": true,
"IsFreeShipping": true,
"ShipSeparately": false,
"AdditionalShippingCharge": 0,
"DeliveryDateId": null,
"IsTaxExempt": false,
"TaxCategoryId": "5c66970e3945712d0430e81e",
"IsTelecommunicationsOrBroadcastingOrElectronicServices": false,
"UseMultipleWarehouses": false,
"WarehouseId": null,
"StockQuantity": 9996,
"ManageInventoryMethod": "ManageStock",
"DisplayStockAvailability": true,
"DisplayStockQuantity": false,
"MinStockQuantity": 0,
"LowStock": false,
"LowStockActivity": "DisableBuyButton",
"NotifyAdminForQuantityBelow": 1,
"BackorderMode": "NoBackorders",
"AllowBackInStockSubscriptions": false,
"OrderMinimumQuantity": 1,
"OrderMaximumQuantity": 10000,
"AllowedQuantities": null,
"AllowAddingOnlyExistingAttributeCombinations": false,
"NotReturnable": false,
"DisableBuyButton": false,
"DisableWishlistButton": false,
"AvailableForPreOrder": false,
"PreOrd
OK, so we’re trying the simple solution first: Update using POST to our store API http://[OUR_DOMAIN]/odata/product , with similar JSON as received from GET.
However, the POST gives a 400 Bad Request result. We have not implemented SSL yet so just using http.
I have looked at the API source code and understand that the product’s Id should be specified in the JSON, and not be part of the url, and that it needs to be POST and not PUT.
Authorization is OK using Bearer, and have checked that JSON syntax is valid. I have tried to “wrap” the JSON in different ways with curly braces and labels, but have not been able to get this to work.
I’m pasting the raw request and response from Fiddler below. Any suggestions that can help us solve this are appreciated.
Note: I have not included the contents of the Categories / Manufacturers arrays (etc) in the bottom in the request.
[code]
===========================================
REQUEST (RAW)
===========================================
POST http://[----SNIP---].no/odata/product HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6I[----SNIP----]gFN-i7WaIrY6sxLieM
Content-Type: application/json; charset=utf-8
Content-Length: 3977
Host: [----SNIP---].no
{
"ProductType": "SimpleProduct",
"ParentGroupedProductId": null,
"VisibleIndividually": true,
"Name": "CONTINENTALLLLL PREMIUMCONTACT 5",
"SeName": "fahrenheit-451-by-ray-bradbury",
"ShortDescription": "TESTVINNER!",
"FullDescription": "<h4>CONTINENTAL CONTIPREMIUMCONTACT5 </h4>\r\n<ul>\r\n<li>2. plass i ADAC sommerdekktest 2018</li>\r\n<li>Testvinner GTÜ sommerdekktest 2017</li>\r\n<li>Andreplass Aftonbladets sommerdekktest 2017</li>\r\n<li>Testvinner ADAC sommerdekktest 2016</li>\r\n<li>Tredjeplass på sommerdekktestet til NAF 2016</li>\r\n</ul>",
"AdminComment": null,
"ProductTemplateId": "5c6697123945712d04312bdf",
"VendorId": null,
"ShowOnHomePage": false,
"MetaKeywords": null,
"MetaDescription": null,
"MetaTitle": null,
"AllowCustomerReviews": true,
"ApprovedRatingSum": 4,
"NotApprovedRatingSum": 0,
"ApprovedTotalReviews": 1,
"NotApprovedTotalReviews": 0,
"ExternalId": null,
"Sku": "TTPAH45-0S11S",
"ManufacturerPartNumber": null,
"Gtin": null,
"IsGiftCard": false,
"GiftCardType": "Virtual",
"OverriddenGiftCardAmount": null,
"RequireOtherProducts": false,
"RequiredProductIds": null,
"AutomaticallyAddRequiredProducts": false,
"IsDownload": false,
"DownloadId": null,
"UnlimitedDownloads": false,
"DownloadActivationType": "WhenOrderIsPaid",
"MaxNumberOfDownloads": 0,
"DownloadExpirationDays": null,
"HasSampleDownload": false,
"SampleDownloadId": null,
"HasUserAgreement": false,
"UserAgreementText": null,
"IsRecurring": false,
"RecurringCycleLength": 0,
"RecurringTotalCycles": 0,
"RecurringCyclePeriod": "Days",
"IncBothDate": false,
"Interval": 0,
"IntervalUnitType": "Minute",
"IsShipEnabled": true,
"IsFreeShipping": true,
"ShipSeparately": false,
"AdditionalShippingCharge": 0,
"DeliveryDateId": null,
"IsTaxExempt": false,
"TaxCategoryId": "5c66970e3945712d0430e81e",
"IsTelecommunicationsOrBroadcastingOrElectronicServices": false,
"UseMultipleWarehouses": false,
"WarehouseId": null,
"StockQuantity": 9996,
"ManageInventoryMethod": "ManageStock",
"DisplayStockAvailability": true,
"DisplayStockQuantity": false,
"MinStockQuantity": 0,
"LowStock": false,
"LowStockActivity": "DisableBuyButton",
"NotifyAdminForQuantityBelow": 1,
"BackorderMode": "NoBackorders",
"AllowBackInStockSubscriptions": false,
"OrderMinimumQuantity": 1,
"OrderMaximumQuantity": 10000,
"AllowedQuantities": null,
"AllowAddingOnlyExistingAttributeCombinations": false,
"NotReturnable": false,
"DisableBuyButton": false,
"DisableWishlistButton": false,
"AvailableForPreOrder": false,
"PreOrd
0
[continued]
...
"PreOrderAvailabilityStartDateTimeUtc": null,
"CallForPrice": false,
"Price": 727,
"OldPrice": 830,
"CatalogPrice": 830,
"ProductCost": 0,
"CustomerEntersPrice": false,
"MinimumCustomerEnteredPrice": 0,
"MaximumCustomerEnteredPrice": 0,
"BasepriceEnabled": false,
"BasepriceAmount": 0,
"BasepriceUnitId": "5c66970e3945712d0430e819",
"BasepriceBaseAmount": 0,
"BasepriceBaseUnitId": "5c66970e3945712d0430e819",
"UnitId": null,
"MarkAsNew": false,
"MarkAsNewStartDateTimeUtc": null,
"MarkAsNewEndDateTimeUtc": null,
"Weight": 2,
"Length": 2,
"Width": 2,
"Height": 2,
"AvailableStartDateTimeUtc": null,
"AvailableEndDateTimeUtc": null,
"StartPrice": 0,
"AuctionEnded": false,
"DisplayOrder": 0,
"DisplayOrderCategory": 0,
"DisplayOrderManufacturer": 0,
"Published": true,
"CreatedOnUtc": "2019-02-15T10,40,22.78Z",
"UpdatedOnUtc": "2019-03-16T06,03,28.991Z",
"Sold": 4,
"Viewed": 10,
"OnSale": 0,
"Flag": null,
"Id": "5c6697163945712d04312e7a",
"Categories": [],
"Manufacturers": [],
"Pictures": [],
"SpecificationAttribute": [],
"TierPrices": [],
"WarehouseInventory": [],
"AttributeMappings": [],
"AttributeCombinations": []
}
===========================================
RESULT (RAW)
===========================================
HTTP/1.1 400 Bad Request
Date: Thu, 21 Mar 2019 15:47:13 GMT
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
X-Powered-By: GrandNode
OData-Version: 4.0
X-Content-Type-Options: nosniff
77
{"error":{"code":"","message":"The input was not valid.","details":[{"code":"","message":"The input was not valid."}]}}
0
...
"PreOrderAvailabilityStartDateTimeUtc": null,
"CallForPrice": false,
"Price": 727,
"OldPrice": 830,
"CatalogPrice": 830,
"ProductCost": 0,
"CustomerEntersPrice": false,
"MinimumCustomerEnteredPrice": 0,
"MaximumCustomerEnteredPrice": 0,
"BasepriceEnabled": false,
"BasepriceAmount": 0,
"BasepriceUnitId": "5c66970e3945712d0430e819",
"BasepriceBaseAmount": 0,
"BasepriceBaseUnitId": "5c66970e3945712d0430e819",
"UnitId": null,
"MarkAsNew": false,
"MarkAsNewStartDateTimeUtc": null,
"MarkAsNewEndDateTimeUtc": null,
"Weight": 2,
"Length": 2,
"Width": 2,
"Height": 2,
"AvailableStartDateTimeUtc": null,
"AvailableEndDateTimeUtc": null,
"StartPrice": 0,
"AuctionEnded": false,
"DisplayOrder": 0,
"DisplayOrderCategory": 0,
"DisplayOrderManufacturer": 0,
"Published": true,
"CreatedOnUtc": "2019-02-15T10,40,22.78Z",
"UpdatedOnUtc": "2019-03-16T06,03,28.991Z",
"Sold": 4,
"Viewed": 10,
"OnSale": 0,
"Flag": null,
"Id": "5c6697163945712d04312e7a",
"Categories": [],
"Manufacturers": [],
"Pictures": [],
"SpecificationAttribute": [],
"TierPrices": [],
"WarehouseInventory": [],
"AttributeMappings": [],
"AttributeCombinations": []
}
===========================================
RESULT (RAW)
===========================================
HTTP/1.1 400 Bad Request
Date: Thu, 21 Mar 2019 15:47:13 GMT
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
X-Powered-By: GrandNode
OData-Version: 4.0
X-Content-Type-Options: nosniff
77
{"error":{"code":"","message":"The input was not valid.","details":[{"code":"","message":"The input was not valid."}]}}
0
0
Hi,
I tried to send your request and I had the same problem. I found the issue, it's a problem with date format. It's unsupported by OData. It's some kind of bug, we need to fix it and I made a task here. As a workaround, you can use supported date format, I compare them below:
My format: "CreatedOnUtc": "2019-03-16T12:37:49.234+01:00",
Your format: "UpdatedOnUtc": "2019-03-16T06,03,28.991Z",
Hope it will help you.
I tried to send your request and I had the same problem. I found the issue, it's a problem with date format. It's unsupported by OData. It's some kind of bug, we need to fix it and I made a task here. As a workaround, you can use supported date format, I compare them below:
My format: "CreatedOnUtc": "2019-03-16T12:37:49.234+01:00",
Your format: "UpdatedOnUtc": "2019-03-16T06,03,28.991Z",
Hope it will help you.
Best regards,
Patryk
GrandNode Team
Patryk
GrandNode Team
0
Hi, thanks a lot for helping to debug this.
I've been reading up on this, and it seems that both the trailing "Z" and "+01:00" are valid time formats according to ISO 8601. (Z means UTC and +01:00 means UTC plus 1 hour).
What is *not* valid however, is the commas in the dates that I have tried to send.
I'm not sure where/when/why the dots in my test have been replaced by commas (as in "2019-03-16T06,03,28.991Z), but it seems that dates from GN API has the correct format.
Sorry for the inconvenience as this apparently is not a bug after all.
I've been reading up on this, and it seems that both the trailing "Z" and "+01:00" are valid time formats according to ISO 8601. (Z means UTC and +01:00 means UTC plus 1 hour).
What is *not* valid however, is the commas in the dates that I have tried to send.
I'm not sure where/when/why the dots in my test have been replaced by commas (as in "2019-03-16T06,03,28.991Z), but it seems that dates from GN API has the correct format.
Sorry for the inconvenience as this apparently is not a bug after all.
0