Catalog API

Build a Simple Catalog

In this guide, you learn the basics of the Square Catalog API by creating a simple product catalog for a cafe that serves coffee in small and large sizes, with skim or whole milk.

To build this catalog, you will call the UpsertCatalogObject endpoint to create the following catalog objects to represent the for-sale item (Coffee) with two variations (Small Coffee or Large Coffee) of the sale item, a CatalogTax object as taxes applied on the coffee item, and two optional modifications (with Skim Milk or Whole Milk):

The steps presented here is generally applicable to creating catalog objects of other types except for uploading an image object. For instructions to upload an image to a catalog and attach it to an item, item variation or category, see Create a Catalog Image.

Prerequisites Permalink Get a link to this section

  • You have a Square account enabled for payment processing. If you have not enabled payment processing on your account (or you are not sure), visit squareup.com/activate.

The following is also assumed:

  • You are familiar with HTTPS. If this is your first time working with HTTPS, see TLS and HTTPS before continuing.

Information you need Permalink Get a link to this section

To use the steps in this topic, you need:

Step 1: Add a coffee item to a catalog Permalink Get a link to this section

Important

When creating an item, you must also specify at least one variation. Otherwise, you get an INVALID_REQUEST error.

To add a coffee item to a catalog as a product offering of a seller, call the UpsertCatalogObject endpoint to create a CatalogItem object to the catalog. This is shown in the following REST API example:

Upsert Catalog Object
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
curl https://connect.squareupsandbox.com/v2/catalog/object \
  -X POST \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "{UNIQUE_KEY}",
    "object": {
      "id": "#coffee",
      "type": "ITEM",
      "item_data": {
        "abbreviation": "Co",
        "description": "Coffee Drink",
        "name": "Coffee",
        "variations": [
          {
            "id": "#small_coffee",
            "type": "ITEM_VARIATION",
            "item_variation_data": {
              "name": "Small",
              "price_money": {
                "amount": 300,
                "currency": "USD"
              },
              "pricing_type": "FIXED_PRICING",
              "item_id": "#coffee"
            }
          },
          {
            "id": "#large_coffee",
            "type": "ITEM_VARIATION",
            "item_variation_data": {
              "name": "Large",
              "price_money": {
                "amount": 350,
                "currency": "USD"
              },
              "pricing_type": "FIXED_PRICING",
              "item_id": "#coffee"
            }
          }
        ]
      }
    }
  }'

In this example, the Coffee item will have two variations (Small and Large).

The #coffee ID is a temporary ID, serving as a placeholder for the permanent ID that is to be generated by the Square API and returned in the response. In the same request payload where the temporary ID is defined, you can use the temporary ID value to reference this to-be-created object. The two variations in this example use #coffee to identify its parent item. If these variations were created in a separate request, you must use their Square-generated permanent ID values to reference them.

Because the UpsertCatalogObject endpoint is used to create other catalog objects, the data object you specify must match the specified type property value. In this example, you must set the item_data property to an appropriate CatalogItem object to match the ITEM type, and set the item_variation_data property to an appropriate CatalogItemVariation object to match the ITEM_VARIATION type. Similarly, to set up a discount to be applied to an order, you must specify an appropriate CatalogDiscount object on the discount_data field while setting the type value to DISCOUNT. In summary, the type property must match the {object_type}_data property.

When the request is successful, you get a 200 OK response with a payload similar to the following:

{
  "catalog_object": {
    "type": "ITEM",
    "id": "FX3LTXC2CCFCGHLGMSFLBSDO",
    "updated_at": "2021-06-15T18:48:16.262Z",
    "version": 1623782896262,
    "is_deleted": false,
    "present_at_all_locations": true,
    "item_data": {
      "name": "Coffee",
      "description": "Coffee Drink",
      "abbreviation": "Co",
      "variations": [
        {
          "type": "ITEM_VARIATION",
          "id": "OXRR3XANRU5TEQ3FQMDW5IJK",
          "updated_at": "2021-06-15T18:48:16.262Z",
          "version": 1623782896262,
          "is_deleted": false,
          "present_at_all_locations": true,
          "item_variation_data": {
            "item_id": "FX3LTXC2CCFCGHLGMSFLBSDO",
            "name": "Small",
            "ordinal": 0,
            "pricing_type": "FIXED_PRICING",
            "price_money": {
              "amount": 300,
              "currency": "USD"
            },
            "stockable": true
          }
        },
        {
          "type": "ITEM_VARIATION",
          "id": "3EFNOI25E4NUK53CU4KMUHXX",
          "updated_at": "2021-06-15T18:48:16.262Z",
          "version": 1623782896262,
          "is_deleted": false,
          "present_at_all_locations": true,
          "item_variation_data": {
            "item_id": "FX3LTXC2CCFCGHLGMSFLBSDO",
            "name": "Large",
            "ordinal": 1,
            "pricing_type": "FIXED_PRICING",
            "price_money": {
              "amount": 350,
              "currency": "USD"
            },
            "stockable": true
          }
        }
      ],
      "product_type": "REGULAR"
    }
  },
  "id_mappings": [
    {
      "client_object_id": "#coffee",
      "object_id": "FX3LTXC2CCFCGHLGMSFLBSDO"
    },
    {
      "client_object_id": "#small_coffee",
      "object_id": "OXRR3XANRU5TEQ3FQMDW5IJK"
    },
    {
      "client_object_id": "#large_coffee",
      "object_id": "3EFNOI25E4NUK53CU4KMUHXX"
    }
  ]
}

Note that the response returns the ID mapping between the temporary ID (id_mappings.client_object_id) value and the Square-generated ID (object_id) value. From now on, you must reference these object by their respective object_id values.

Step 2: Create a CatalogTax object for the coffee drink Permalink Get a link to this section

In most locales, a sales tax must be levied on a product sold. To support taking taxes on an order, you must first create a CatalogTax object to set up the tax to be applied when the payment is made on the order.

The following code example shows how to create a tax object and add it to the catalog.

Upsert Catalog Object
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
curl https://connect.squareupsandbox.com/v2/catalog/object \
  -X POST \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "{UNIQUE_KEY}",
    "object": {
      "id": "#sales_tax",
      "type": "TAX",
      "tax_data": {
        "calculation_phase": "TAX_SUBTOTAL_PHASE",
        "inclusion_type": "ADDITIVE",
        "name": "Drink Tax",
        "percentage": "7.5"
      }
    }
  }'

In this example, the drink tax is 7.5% of the pre-tax subtotal of an order.

When successful, the request returns a 200 OK response with the payload similar to the following:

{
  "catalog_object": {
    "type": "TAX",
    "id": "TEROS7KLG76NDY4J7TYFZVGA",
    "updated_at": "2021-06-15T19:12:49.613Z",
    "version": 1623784369613,
    "is_deleted": false,
    "present_at_all_locations": true,
    "tax_data": {
      "name": "Drink Tax",
      "calculation_phase": "TAX_SUBTOTAL_PHASE",
      "inclusion_type": "ADDITIVE",
      "percentage": "7.5",
      "applies_to_custom_amounts": true,
      "enabled": true
    }
  },
  "id_mappings": [
    {
      "client_object_id": "#sales_tax",
      "object_id": "TEROS7KLG76NDY4J7TYFZVGA"
    }
  ]
}

Alternatively, you can combine the calls to create the Coffee item with the Small and Large variations and the Drink Tax object into a single call to the BatchUpsertCatalogObjects endpoint, as shown:

Batch Upsert Catalog Objects
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
curl https://connect.squareupsandbox.com/v2/catalog/batch-upsert \
  -X POST \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "{UNIQUE_KEY}",
    "batches": [
      {
        "objects": [
          {
            "id": "#coffee",
            "type": "ITEM",
            "item_data": {
              "name": "Coffee",
              "product_type": "REGULAR",
              "variations": [
                {
                  "id": "#small_coffee",
                  "type": "ITEM_VARIATION",
                  "item_variation_data": {
                    "name": "Small",
                    "price_money": {
                      "amount": 300,
                      "currency": "USD"
                    },
                    "pricing_type": "FIXED_PRICING",
                    "item_id": "#coffee"
                  }
                },
                {
                  "id": "#large_coffee",
                  "type": "ITEM_VARIATION",
                  "item_variation_data": {
                    "name": "Large",
                    "price_money": {
                      "amount": 350,
                      "currency": "USD"
                    },
                    "pricing_type": "FIXED_PRICING",
                    "item_id": "#coffee"
                  }
                }
              ]
            }
          },
          {
            "id": "#sales_tax",
            "type": "TAX",
            "tax_data": {
              "calculation_phase": "TAX_SUBTOTAL_PHASE",
              "inclusion_type": "ADDITIVE",
              "name": "Drink Tax",
              "percentage": "7.5"
            }
          }
        ]
      }
    ]
  }'

Step 3: Create a modifier list to contain two modifiers Permalink Get a link to this section

To enable sellers to offer the choices of adding Skim Milk and Whole Milk to the coffee drink, you can create two catalog modifiers to apply to the Coffee item. One way to add the modifiers is to create a modifier list containing individual modifiers as its entries.

The following example shows how to call the UpsertCatalogObject endpoint to create the CatalogModifierList object with two CatalogModifier objects for Skim Milk and Whole Milk:

Upsert Catalog Object
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
curl https://connect.squareupsandbox.com/v2/catalog/object \
  -X POST \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "{UNIQUE_KEY}",
    "object": {
      "id": "#modifier_list",
      "type": "MODIFIER_LIST",
      "modifier_list_data": {
        "name": "Milk Options",
        "modifiers": [
          {
            "id": "#whole_milk",
            "type": "MODIFIER",
            "modifier_data": {
              "modifier_list_id": "#modifier_list",
              "name": "Whole Milk",
              "price_money": {
                "amount": 125,
                "currency": "USD"
              }
            }
          },
          {
            "id": "#skim_milk",
            "type": "MODIFIER",
            "modifier_data": {
              "modifier_list_id": "#modifier_list",
              "name": "Skim Milk",
              "price_money": {
                "amount": 130,
                "currency": "USD"
              }
            }
          }
        ]
      }
    }
  }'

The successful operation returns a 200 OK response with a payload similar to the following:

{
  "catalog_object": {
    "type": "MODIFIER_LIST",
    "id": "ZVSGY6U63IGCZQL4IOPZAKYW",
    "updated_at": "2020-06-15T20:01:39.58Z",
    "version": 1623784369656,
    "is_deleted": false,
    "present_at_all_locations": true,
    "modifier_list_data": {
      "name": "Milk Options",
      "modifiers": [
        {
          "type": "MODIFIER",
          "id": "MNXLZRO2PIBULOX2RX56DG25",
          "updated_at": "2020-06-15T20:01:39.58Z",
          "version": 1623784369656,
          "is_deleted": false,
          "present_at_all_locations": true,
          "modifier_data": {
            "name": "Whole Milk",
            "price_money": {
              "amount": 125,
              "currency": "USD"
            },
            "on_by_default": false,
            "ordinal": 0,
            "modifier_list_id": "ZVSGY6U63IGCZQL4IOPZAKYW"
          }
        },
        {
          "type": "MODIFIER",
          "id": "Q6R5X5VMSZTYVKM37QRHNZWM",
          "updated_at": "2020-06-15T20:01:39.58Z",
          "version": 1623784369656,
          "is_deleted": false,
          "present_at_all_locations": true,
          "modifier_data": {
            "name": "Skim Milk",
            "price_money": {
              "amount": 130,
              "currency": "USD"
            },
            "on_by_default": false,
            "ordinal": 1,
            "modifier_list_id": "ZVSGY6U63IGCZQL4IOPZAKYW"
          }
        }
      ]
    }
  },
  "id_mappings": [
    {
      "client_object_id": "#modifier_list",
      "object_id": "ZVSGY6U63IGCZQL4IOPZAKYW"
    },
    {
      "client_object_id": "#whole_milk",
      "object_id": "MNXLZRO2PIBULOX2RX56DG25"
    },
    {
      "client_object_id": "#skim_milk",
      "object_id": "Q6R5X5VMSZTYVKM37QRHNZWM"
    }
  ]
}

For the modifiers in the modifier list be applied to the Coffee item, you must have the resultant modifier list applied to the Coffee item, as explained in step 4.

Step 4: Apply the modifier list to the Coffee item Permalink Get a link to this section

To apply the modifier list built in step 3, call the UpdateItemModifierLists endpoint as shown in the following example:

Update Item Modifier Lists
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
curl https://connect.squareupsandbox.com/v2/catalog/update-item-modifier-lists \
  -X POST \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{
    "item_ids": [
      "FX3LTXC2CCFCGHLGMSFLBSDO"
    ],
    "modifier_lists_to_enable": [
      "ZVSGY6U63IGCZQL4IOPZAKYW"
    ]
  }'

If successful, the operation returns a 200 OK response with a payload similar to the following:

{
  "updated_at": "2020-06-15T18:36:39.58Z"
}

Alternatively, you can call the BatchUpsertCatalogObjects endpoint to create a modifier list with appropriate modifier entries and add the modifier list to the Coffee item, together with the required item variations, in a single call to create all related CatalogObject instances at once.

Step 5: Verify the catalog you just built Permalink Get a link to this section

After building your catalog, you can view and verify it by calling the ListCatalog endpoint to inspect the catalog items. The following request shows an example:

List Catalog
  • 1
  • 2
  • 3
  • 4
curl https://connect.squareupsandbox.com/v2/catalog/list \
  -H 'Square-Version: 2021-07-21' \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json'

In response, the payload contains the catalog objects:

{
  "objects": [
    {
      "type": "ITEM",
      "id": "FX3LTXC2CCFCGHLGMSFLBSDO",
      "updated_at": "2021-06-15T18:48:16.262Z",
      "version": 1623782896262,
      "is_deleted": false,
      "present_at_all_locations": true,
      "item_data": {
        "name": "Coffee",
        "description": "Coffee Drink",
        "abbreviation": "Co",
        "modifier_list_info": [
          {
            "modifier_list_id": "ZVSGY6U63IGCZQL4IOPZAKYW",
            "enabled": true
          }
        ],
        "variations": [
          {
            "type": "ITEM_VARIATION",
            "id": "3EFNOI25E4NUK53CU4KMUHXX",
            "updated_at": "2021-06-15T18:48:16.262Z",
            "version": 1623782896262,
            "is_deleted": false,
            "present_at_all_locations": true,
            "item_variation_data": {
              "item_id": "FX3LTXC2CCFCGHLGMSFLBSDO",
              "name": "Large",
              "pricing_type": "FIXED_PRICING",
              "price_money": {
                "amount": 350,
                "currency": "USD"
              }
            }
          },
          {
            "type": "ITEM_VARIATION",
            "id": "OXRR3XANRU5TEQ3FQMDW5IJK",
            "updated_at": "2021-06-15T18:48:16.262Z",
            "version": 1623782896262,
            "is_deleted": false,
            "present_at_all_locations": true,
            "item_variation_data": {
              "item_id": "FX3LTXC2CCFCGHLGMSFLBSDO",
              "name": "Small",
              "pricing_type": "FIXED_PRICING",
              "price_money": {
                "amount": 300,
                "currency": "USD"
              }
            }
          }
        ],
        "product_type": "REGULAR"
      }
    },
    {
      "type": "TAX",
      "id": "TEROS7KLG76NDY4J7TYFZVGA",
      "updated_at": "2021-06-15T19:12:49.613Z",
      "version": 1623784369613,
      "is_deleted": false,
      "present_at_all_locations": true,
      "tax_data": {
        "name": "Drink Tax",
        "calculation_phase": "TAX_SUBTOTAL_PHASE",
        "inclusion_type": "ADDITIVE",
        "percentage": "7.5",
        "applies_to_custom_amounts": true,
        "enabled": true
      }
    },
    {
      "type": "MODIFIER_LIST",
      "id": "ZVSGY6U63IGCZQL4IOPZAKYW",
      "updated_at": "2020-06-15T20:01:39.58Z",
      "version": 1623784369656,
      "is_deleted": false,
      "present_at_all_locations": true,
      "modifier_list_data": {
        "name": "Milk Options",
        "modifiers": [
          {
            "type": "MODIFIER",
            "id": "MNXLZRO2PIBULOX2RX56DG25",
            "updated_at": "2020-06-15T20:01:39.58Z",
            "version": 1623784369656,
            "is_deleted": false,
            "present_at_all_locations": true,
            "modifier_data": {
              "name": "Whole Milk",
              "price_money": {
                "amount": 125,
                "currency": "USD"
              },
              "on_by_default": false,
              "ordinal": 0,
              "modifier_list_id": "ZVSGY6U63IGCZQL4IOPZAKYW"
            }
          },
          {
            "type": "MODIFIER",
            "id": "Q6R5X5VMSZTYVKM37QRHNZWM",
            "updated_at": "2020-06-15T20:01:39.58Z",
            "version": 1623784369656,
            "is_deleted": false,
            "present_at_all_locations": true,
            "modifier_data": {
              "name": "Skim Milk",
              "price_money": {
                "amount": 130,
                "currency": "USD"
              },
              "on_by_default": false,
              "ordinal": 1,
              "modifier_list_id": "ZVSGY6U63IGCZQL4IOPZAKYW"
            }
          }
        ]
      }
    }
  ]
}

Related topics Permalink Get a link to this section