Search for a specific UPC

I am using the .NET SDK. I want to return the item that matches a specific upc. This is my SearchCatalog method. I have NO CLUE why it it hangs on the SearchCatalogObjectsAsync method. Thanks in advance for help!
public async Task SearchCatalog(string upc)
{

    var objectTypes = new List<string>();
    objectTypes.Add("ITEM");
    objectTypes.Add("ITEM_VARIATION");
    var exactQuery = new CatalogQueryExact.Builder(attributeName: "upc", attributeValue: upc).Build();
    var query = new CatalogQuery.Builder()
        .ExactQuery(exactQuery).Build();
    var body = new SearchCatalogObjectsRequest.Builder()
        .ObjectTypes(objectTypes)
        .IncludeDeletedObjects(false)
        .IncludeRelatedObjects(false)
        .Query(query)
        .Limit(10)
        .Build();
    try
    {
        SearchCatalogObjectsResponse result = await client.CatalogApi.SearchCatalogObjectsAsync(body);
        var item = result.Objects.FirstOrDefault();
        Debug.WriteLine($"Item={item.ItemData}");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }

What do you mean by hang? Looking at the request it looks to be correct. :slightly_smiling_face:

The code never returns from await client.CatalogApi.SearchCatalogObjectsAsync(body).

Not sure what is going on.

When I try this in API Explorer, I get a 200 response but no data.

var objectTypes = new List<string>();
objectTypes.Add("ITEM");

var exactQuery = new CatalogQueryExact.Builder(attributeName: "upc", attributeValue: "676979870090")
  .Build();

var query = new CatalogQuery.Builder()
  .ExactQuery(exactQuery)
  .Build();

var body = new SearchCatalogObjectsRequest.Builder()
  .ObjectTypes(objectTypes)
  .IncludeDeletedObjects(false)
  .IncludeRelatedObjects(true)
  .Query(query)
  .Build();

try
{
  var result = await client.CatalogApi.SearchCatalogObjectsAsync(body: body);
}
catch (ApiException e)
{
  Console.WriteLine("Failed to make the request");
  Console.WriteLine($"Response Code: {e.ResponseCode}");
  Console.WriteLine($"Exception: {e.Message}");
}

I should have mentioned - that is a valid UPC in my catalog

The upc is in the ITEM_VARIATION. It looks like what you just provided is looking at just the item which is one level out from the upc. :slightly_smiling_face:

So I should add this code: objectTypes.Add(“ITEM_VARIATION”) - right?

Ok - modified code slightly to this:
public async Task SearchCatalog(string upc)
{

    var objectTypes = new List<string>();
    objectTypes.Add("ITEM");
    objectTypes.Add("ITEM_VARIATION");
    var exactQuery = new CatalogQueryExact.Builder(attributeName: "upc", attributeValue: upc).Build();
    var query = new CatalogQuery.Builder()
        .ExactQuery(exactQuery).Build();
    var body = new SearchCatalogObjectsRequest.Builder()
        .ObjectTypes(objectTypes)
        .IncludeDeletedObjects(false)
        .IncludeRelatedObjects(false)
        .Query(query)
        .Limit(10)
        .Build();
    try
    {
        SearchCatalogObjectsResponse result = await client.CatalogApi.SearchCatalogObjectsAsync(body);

        var item = result.Objects.FirstOrDefault();
        Debug.WriteLine($"Item={item.ItemData}");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

Now the result has an empty Objects collection (there is exactly 1 based on the UPC I gave it). Also - can’t get it to work in API Explorer either - always a null result set

Is the catalog object with that upc in the same environment that this query is calling? :slightly_smiling_face:

Yes. I am able to get all catalog objects. What I don’t seem to be able to do is search for one by it’s UPC.

What’s the application ID and the upc that your searching for? :slightly_smiling_face:

AppId = sandbox-sq0idb-iLzd7nPVafexdk9U74PiyQ

UPC = 000000120001

That upc looks to be a production item upc not a sandbox upc which is why your getting an empty response. If you switch to production and search the upc it’ll should return the results as expected. :slightly_smiling_face:

Ok - am confused. I imported real data from my wife’s store (their actual catalog). Do I have to reimport it to a production sandbox?

When I switch to production, no catalog items are found.

At this time a upc isn’t supported in sandbox through the import which is why your getting empty results in sandbox. If the items would have been created with the API then a upc would be in the object in sandbox. We’re constantly working to improve our features based on feedback like this, so I’ll be sure to share your request to the API product team. For production I just ran:

var objectTypes = new List<string>();
objectTypes.Add("ITEM");
objectTypes.Add("ITEM_VARIATION");

var prefixQuery = new CatalogQueryPrefix.Builder(attributeName: "upc", attributePrefix: "000000120001")
  .Build();

var query = new CatalogQuery.Builder()
  .PrefixQuery(prefixQuery)
  .Build();

var body = new SearchCatalogObjectsRequest.Builder()
  .ObjectTypes(objectTypes)
  .IncludeDeletedObjects(false)
  .IncludeRelatedObjects(true)
  .Query(query)
  .Build();

try
{
  var result = await client.CatalogApi.SearchCatalogObjectsAsync(body: body);
}
catch (ApiException e)
{
  Console.WriteLine("Failed to make the request");
  Console.WriteLine($"Response Code: {e.ResponseCode}");
  Console.WriteLine($"Exception: {e.Message}");
}

and got back:

{
  "objects": [
    {
      "type": "ITEM_VARIATION",
      "id": "KISWM3UUEFHD7V5DE4S3NP4J",
      "updated_at": "2022-10-26T18:06:43.307Z",
      "created_at": "2021-04-21T19:18:16.198Z",
      "version": 1666807603307,
      "is_deleted": false,
      "present_at_all_locations": true,
      "item_variation_data": {
        "item_id": "DGGLQEOSHV4DONXMZNT6UF4T",
        "name": "Regular",
        "sku": "918535L",
        "upc": "000000120001",
        "ordinal": 1,
        "pricing_type": "FIXED_PRICING",
        "price_money": {
          "amount": 149,
          "currency": "USD"
        },
        "location_overrides": [
          {
            "location_id": "LQD712KXKAKJ7",
            "track_inventory": true
          }
        ],
        "sellable": true,
        "stockable": true,
        "item_variation_vendor_info_ids": [
          "NXWQYJ7BKWSQLAG2M6CBB66I"
        ]
      }
    }
  ],
  "related_objects": [
    {
      "type": "ITEM",
      "id": "DGGLQEOSHV4DONXMZNT6UF4T",
      "updated_at": "2022-10-26T18:06:43.307Z",
      "created_at": "2021-04-21T19:18:16.198Z",
      "version": 1666807603307,
      "is_deleted": false,
      "present_at_all_locations": true,
      "item_data": {
        "name": "Unisex Socks",
        "visibility": "PRIVATE",
        "category_id": "OTPEVBSRK362H2SFOSHRLLKK",
        "tax_ids": [
          "4TAGTIBG7JS5YMJD4FGWWCQT"
        ],
        "variations": [
          {
            "type": "ITEM_VARIATION",
            "id": "KISWM3UUEFHD7V5DE4S3NP4J",
            "updated_at": "2022-10-26T18:06:43.307Z",
            "created_at": "2021-04-21T19:18:16.198Z",
            "version": 1666807603307,
            "is_deleted": false,
            "present_at_all_locations": true,
            "item_variation_data": {
              "item_id": "DGGLQEOSHV4DONXMZNT6UF4T",
              "name": "Regular",
              "sku": "918535L",
              "upc": "000000120001",
              "ordinal": 1,
              "pricing_type": "FIXED_PRICING",
              "price_money": {
                "amount": 149,
                "currency": "USD"
              },
              "location_overrides": [
                {
                  "location_id": "LQD712KXKAKJ7",
                  "track_inventory": true
                }
              ],
              "sellable": true,
              "stockable": true,
              "item_variation_vendor_info_ids": [
                "NXWQYJ7BKWSQLAG2M6CBB66I"
              ]
            }
          }
        ],
        "product_type": "REGULAR",
        "skip_modifier_screen": false,
        "ecom_uri": "https://that-one-store.square.site/product/unisex-socks/302",
        "ecom_available": true,
        "ecom_visibility": "VISIBLE"
      }
    }
  ],
  "latest_time": "2022-12-07T19:37:09.495Z"
}

In sandbox you can search by sku which for this item would be 918535L. I confirmed it’s visible in sandbox and is returned if you change upc to sku for testing purposes. :slightly_smiling_face:

Hi Bryan, first off THANK YOU! I have spent HOURS trying to figure this out. In the meantime, can you file a documentation bug on this? This is the first of three projects I am planning. But common to all three projects is to simply scan the product’s UPC code and retrieve all of the product details.

Also - is there a private venue where I could share the planned projects and discover any “gotcha’s” and learn best practices? Can I schedule a 30 minute meeting with a developer advocate?

We’re constantly working to improve our features based on feedback like this, so I’ll be sure to share your request to the API product team.

Also I’m happy to setup some time to go over the integration if you’d like. :slightly_smiling_face:

Fantastic! My email is timbelvin@hotmail.com. Please send me some times that work for you tomorrow (Thursday) or Friday.

I sort of have this working. Next step is to get quantity on hand for a given item/item variation.

My search query (where I also get the ObjectId of the item) is as follows:
public async Task SearchCatalog(string upc)
{

    var objectTypes = new List<string>();
    objectTypes.Add("ITEM");
    objectTypes.Add("ITEM_VARIATION");

    // TODO: change this to upc when they fix sandbox or I point to production

    var exactQuery = new CatalogQueryExact.Builder(attributeName: "sku", attributeValue: upc).Build();
    var query = new CatalogQuery.Builder()
        .ExactQuery(exactQuery).Build();
    var body = new SearchCatalogObjectsRequest.Builder()
        .ObjectTypes(objectTypes)
        .IncludeDeletedObjects(false)
        .IncludeRelatedObjects(false)
        .Query(query)
        .Limit(10)
        .Build();
    try
    {
        SearchCatalogObjectsResponse result = await client.CatalogApi.SearchCatalogObjectsAsync(body);

        var item = result.Objects.FirstOrDefault();
        if (item is not null)
        {
            var searchItem = new SearchItem
            {
                Name = await GetItemName(SearchType.Sku, upc),
                Upc = item.ItemVariationData.Upc,
                Sku = item.ItemVariationData.Sku,
                Price = (double)item.ItemVariationData.PriceMoney.Amount / 100,
                ObjectId = item.Id
            };
            Debug.WriteLine($"ObjectId = {item.Id}");
            return searchItem;

        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
    return null;
}

When I search my catalog for the SKU 918535L. How do I get the CatalogObjectId? The item.id returned is AWEGJGOVOMYJJ2AWBVRSBMEI.

When I try to retrieve quantity on hand with this:
try
{
var result = await client.InventoryApi.RetrieveInventoryCountAsync(catalogObjectId: “AWEGJGOVOMYJJ2AWBVRSBMEI”, locationIds: “”);
}
catch (ApiException e)
{
Console.WriteLine(“Failed to make the request”);
Console.WriteLine($“Response Code: {e.ResponseCode}”);
Console.WriteLine($“Exception: {e.Message}”);
}

I get an empty result. So apparently I get the catalogobjectid somewhere else. Where

Is there a data model definition I can try to figure out the relationships from?

With the Inventory API it’s the item_variation_id that you pass in the request. Not the item_id. Once you have the item sku/upc you should also have the catalog_object_variation_id that you pass to the Inventory API. :slightly_smiling_face: