Catalog API Upsert Issue

When using the Catalog API upsertCatalogObject method in Node I am not getting the functionality I would expect.

I have an item in my catalog with ID CAUFD6BBHZE63RGIGTJU6ORQ that I would like to update the description of using this API. The structure of this item looks like this in JSON:

{
“type”: “ITEM”,
“id”: “CAUFD6BBHZE63RGIGTJU6ORQ”,
“updated_at”: “2020-10-26T16:30:25.541Z”,
“version”: 1603729825541,
“is_deleted”: false,
“present_at_all_locations”: true,
“item_data”: {
“name”: “Drop Active”,
“description”: “Yes”,
“visibility”: “PRIVATE”,
“category_id”: “EOJCMON33WUYJLDB2NF4D65A”,
“tax_ids”: [
“36YOFLOLDTTPOP6PTI4LPRYN”
],
“variations”: [
{
“type”: “ITEM_VARIATION”,
“id”: “P7IURR4HYFJPDWVIBDXBGAH7”,
“updated_at”: “2020-10-26T16:30:25.541Z”,
“version”: 1603729825541,
“is_deleted”: false,
“present_at_all_locations”: true,
“item_variation_data”: {
“item_id”: “CAUFD6BBHZE63RGIGTJU6ORQ”,
“name”: “Regular”,
“ordinal”: 1,
“pricing_type”: “VARIABLE_PRICING”
}
}
],
“product_type”: “REGULAR”,
“skip_modifier_screen”: false,
“legacy_tax_ids”: [
“36YOFLOLDTTPOP6PTI4LPRYN”
]
}

When I call the upsertCatalogObject method with the request body below, it does not directly change the description in the object above as I would expect. Instead it adds ANOTHER object with the same ID with the new description. So there are TWO objects with the same ID in my catalog. This also makes the item disappear on my catalog in the web GUI Items page. However making a listCatalog API call I can see both items with the same ID available.

Here are the request body:

{
“idempotency_key”: “f9b110a3810acb14a5729850dd459b8a60f85c3a3493”,
“object”: {
“id”: “CAUFD6BBHZE63RGIGTJU6ORQ”,
“version”: 1603675647315,
“type”: “ITEM”,
“item_data”: {
“description”: “Sold Out”,
“name”: “Drop Active”,
“category_id”: “EOJCMON33WUYJLDB2NF4D65A”
}
}
}

Here is an example of two of the same objects being in my catalog after the upsertCatalogObject API call (this is a partial output of a listCatalog API call:
{
“type”: “ITEM”,
“id”: “T5QOW5ABZRXK56LKSFBELE3M”,
“updated_at”: “2020-10-26T16:02:58.064Z”,
“version”: 1603728178064,
“is_deleted”: false,
“present_at_all_locations”: true,
“item_data”: {
“name”: “Drop Active”,
“description”: “Yes”,
“visibility”: “PRIVATE”,
“category_id”: “EOJCMON33WUYJLDB2NF4D65A”,
“tax_ids”: [
“36YOFLOLDTTPOP6PTI4LPRYN”
],
“product_type”: “REGULAR”,
“skip_modifier_screen”: false,
“legacy_tax_ids”: [
“36YOFLOLDTTPOP6PTI4LPRYN”
]
}
}
{
“type”: “ITEM”,
“id”: “T5QOW5ABZRXK56LKSFBELE3M”,
“updated_at”: “2020-10-26T16:13:42.119Z”,
“version”: 1603728822119,
“is_deleted”: false,
“present_at_all_locations”: true,
“item_data”: {
“name”: “Drop Active”,
“description”: “Sold Out”,
“visibility”: “PRIVATE”,
“category_id”: “EOJCMON33WUYJLDB2NF4D65A”,
“product_type”: “REGULAR”
}
}

I imagine there is some additional information in the request body that I am missing - however the API documentation does not indicate anything else that is mandatory in the request.

Can somebody help me out here?

Thank you!

Hi @Blawkyy welcome to the forums!

When upserting catalog objects, you must upsert the entire object, and change whatever you want to change. Anything that you leave out (like the variations), will be removed/deleted from the item. So, it’s most likely not creating another object with the same id, but probably deleting a lot of the object when you update it. For instance, an item will only appear in the Dashboard UI when it has variations, yet your request didn’t include the variations, so it most likely was deleted from the item.

Typically, we suggest calling RetrieveCatalogObject to receive the whole object, and then manipulate the object changing what you need, and pushing the entire object to UpsertCatalogObject. Please let me know if you have any additional questions or concerns, I’m happy to help!

Haha, wow. I spent way too much time trying to figure this one out for it to be that simple. Sure enough, as soon as I physically copied the exact object and directly edited the description field to set up my request body it worked perfectly.

Thanks for the really fast response @sjosey! I will be sure to come back to this forum as soon as I run into other issues like this :slight_smile:

1 Like

How do I manipulate the object? It is read only.
And using the builder functionality seems very cumbersome since I will have to init all the new fields with the fields of the existing object.

      var item = GetItem(itemID); // Get Item info from Square
            var object1 = new CatalogObject.Builder(type: "ITEM", id: itemID)
              .PresentAtAllLocations(false)
              .AbsentAtLocationIds(locationList)
              .ItemData(item.ItemData) // assigning existing item information to newly built object
              .CategoryData(item.CategoryData) // assigning existing item information to newly built object
              //more fields need to be added here
              .Build();

Hi @dmbrewing, The returned object isn’t read only however as previously mentioned we recommend the following when updating an item:

I am using the .NET SDK and it is read-only. Looks like the developer over-zealously used the builder pattern which needlessly complicates everything. Documentation is pretty much non-existing either. Unfortunately, I am locked in using .NET.

This seems to work for me with the .NET SDK:

RetrieveCatalogObjectResponse retrieveResponse = await catalogApi.RetrieveCatalogObjectAsync(objectId);

CatalogObject catalogObject = retrieveResponse.MObject.ToBuilder()
                    .AbsentAtLocationIds(locationList) // field or fields you want to change
                    .Build();

UpsertCatalogObjectRequest upsertRequest = new UpsertCatalogObjectRequest.Builder(Guid.NewGuid().ToString(), catalogObject)
                    .Build();

UpsertCatalogObjectResponse upsertResponse = await catalogApi.UpsertCatalogObjectAsync(upsertRequest);

My application is a web app so I’m using the Async methods, but that’s not necessary depending on the type of application you’re developing. It should be the same with the non-async methods (and the awaits omitted of course).