Catalog API Overview
- Web
Square Catalog lets developers create and maintain a collection of items (physical or digital) and services available for sale through a Square merchant account. The Catalog v2 API replaces Square's Items Connect V1 API with improved efficiency and expanded functionality, including individual and batch support for:
- Retriev
- Upsert (insert or update)
- Delete
The Catalog API lets developers handle simple tasks with minimal endpoint calls while still providing functionality needed by more sophisticated applications.
Requirements and limitations
- The Catalog API does not provide integrated inventory management. Inventory management is currently handled with the Inventory API (v1)
- All calls must include an authorization token in the header for the targeted merchant account. Anonymous catalog calls are not allowed.
- Applications using the Catalog API must have
ITEMS_READ
andITEMS_WRITE
permissions for the targeted merchant account. - The Catalog API is not supported in sandbox mode at this time.
Catalog object model
The Catalog API packages all its information as a , which is a generalized wrapper for all the classes across Catalog's object model, including:
-
CatalogItem
— core product information; used to configure the top-level entities of a catalog (e.g., Latte). -
CatalogItemVariation
— one or more incarnations of a product; used to represent the actual item being sold with an assigned price and SKU ( Small, Medium, Large). -
CatalogModifier
— information about an individual modifier; used to provide customization information for a product (e.g., Whole Milk, Skim Milk, Almond Milk). -
CatalogModifierList
— a collection of modifiers that have been logically grouped (e.g., milk choices). -
CatalogCategory
— product category information; used to logically group similar products (e.g., pens vs. pencils or hot drinks vs. cold drinks). -
CatalogDiscount
— discount information; used to provide manually defined discounts for goods and services. -
CatalogTax
— taxation information; used to configure tax requirements for items in the catalog.
items, variations, & modifiers
When working with , it's important to understand the distinction between catalog items, variations, and modifiers
- catalog item — the core representation of a thing — in other words, the product — to be sold ( a latte).
- variation — the instantiation of a specific catalog item with an assigned price and SKU ( a medium latte).
- modifier — a product customization applicable to one or more variations that may (or may not) be associated with an additional cost ( a medium latte with whole milk and no foam).
items variations
Catalog items can represent:
- or physical items ( a PDF printable, coffee)
- ( personal training, dog walking)
- and dues ( artistic patronage, club memberships)
A CatalogItem
does not have a price or SKU because it represents the high-level product, not the actual item/service
being sold. For example:
If merchants offer... | Some possible catalog items are... |
---|---|
PDF printables |
|
Coffee |
|
Personal training |
|
Pet care |
|
Donation options |
|
A CatalogItem
must have at least one variation (CatalogItemVariation
) associated with it before it can be added
to a purchase or used in a transaction. Variations represent the specific version of the product being sold (often with
an assigned SKU and price). For example:
If the catalog item is... | Some possible variants are... |
---|---|
PDF printable: Monthly activity tracker, February 2017 |
|
Latte |
|
Personal training session |
|
Dog walking |
|
Patronage/Membership |
|
Exactly where to draw the line between an item and a variation can be nuanced and complicated, and it's entirely dependent on the products being offered.
For example, a merchant providing personal training might offer the following catalog of service-based products:
- On-site training
- In-home training
- Fitness evaluation
- Nutritional evaluation
At first glance, it may seem like only the first two products (on-site training and in-home training) need variations:
Product | Variation |
---|---|
On-site training |
|
In-home training |
|
Fitness evaluation | n/a |
Nutritional evaluation | n/a |
One solution is group "Fitness evaluation" and "Nutritional evaluation" under a common offering — Health evaluation — with two variations: one for fitness level and one for nutrition. For example:
Product | Variation |
---|---|
On-site training |
|
In-home training |
|
Health evaluation |
|
consider a situation where some of the evaluations don't need to be in-person. In this case, it might make more sense to keep the original product listing and add variations based on how the evaluation takes place. For example:
Product | Variation |
---|---|
On-site training |
|
In-home training |
|
Fitness evaluation |
|
Nutritional evaluation |
|
Forcing a product to have at least one variation may seem arbitrary, but it's an important distinction when you add in modifications. Different versions of a given product may have:
- SKUs
- prices
- be offered in specific store locations
- in specific quantities based on location
Differentiating between the idea of a product (CatalogItem
) and its manifestation (CatalogItemVariation
), creates
greater flexibility in distribution chain and inventory management without requiring excessive duplication.
Variations modifiers
Modifiers (CatalogModifier
) are customizations to a product associated with a specific transaction. They are
related to variations in that they have an associated price, but they don't have SKUs. The lack of SKU means they are
product agnostic, but it also means that they cannot have a quantity.
Modifiers can also be grouped into a list (CatalogModifierList
) based on the nature of the customization. For example:
Catalog Modifier List | Modifiers |
---|---|
Milk type | Whole, 2%, 1%, Almond, Coconut, Soy |
Toppings | Pickles, Lettuce, Onions, Mayo, Mustard, Pesto |
Cover color | Steel, Blue Jay, Barn Red |
Language | English, Spanish, Japanese, German |
The difference between variations and modifications is that modifications are only relevant when a product can be customized as part of an order. For example:
- Selecting a preferred pickup window for a dog walking service ( early morning, afternoon, early evening).
- Selecting a wrapping paper pattern when the purchase is a gift ( blue, green, stripes, polka dots).
- Selecting custom embroidery patterns for a jersey ( bees, gophers, a ham sandwich).
In each of these cases, the specific CatalogItemVariation
— the thing being added to a purchase — is irrelevant
to the customization. For example, a pickup window is equally relevant whether the customer orders a 30-minute walk or
a 60 minute walk, the wrapping paper selected applies regardless of the gift purchased, and the size of the jersey
doesn't affect the custom embroidery selected.
Categories
The CatalogCategory
object provides a basic structure for organizing the items in a catalog. Categories are listed on
the "Categories" page of the Square Dashboard and in the "Categories" tab of the Items applet in the Square Point of
Sale app.
While category names are entirely arbitrary ( "Hot Drinks", "Team Favorites", "Quetzalcoatlus"), they should make sense when displayed in the Dashboard or POS. Categories can be useful for making a large catalog easier to look up and manage, but they should be designed with care as a given catalog item may only belong to one category.
Discounts
The CatalogDiscount
object provides information for reducing the total cost of an order. Discounts are listed on the
"Discounts" page of the Square Dashboard and in the "Discounts" tab of the Items applet in the Square Point of Sale app.
Discounts can be a fixed value, a percentage, or a dynamic value entered at the time of sale. They are applied to the pre-tax total of an entire purchase, not to an individual item in the purchase.
Taxes
The CatalogTax
object provides a basic structure for calculating the appropriate taxes for a CatalogItemVariation
object. Tax values are strictly percentage-based and applied to all of the individual items in a sale associated with
the tax. As part of its configuration, each CatalogItem
specifies the taxes that apply to it by default, although a
merchant can override these defaults at the time of sale. It's important to note that CatalogTax
objects exist in
parallel with CatalogItem
objects. When a new CatalogItem
is created, no taxes apply to it unless an associated
CatalogTax
object is explicitly provided. Taxes are listed on the "Taxes" page of the Square Dashboard.
CatalogTax
can be defined as:
- tax — added on top of the price of items they're applied to. For example, if an additive 10% tax is applied to a $100 item, the total is $110.
- tax — assumed to already be included in the price of the items they apply to. For example, if an inclusive 10% tax is applied to a $100 item, the total is still $100, and the actual base cost of the item is assumed to be $90.91, with $9.09 of the total being the tax amount.
Once defined, taxes are applied to payments during one of the following phases:
- phase — taxes applied during the subtotal phase are applied only to the base cost of applicable items. The vast majority of taxes are applied during this phase.
- phase — taxes applied during the total phase are applied to the base cost of applicable items, and to any tax amounts applied to those items during the subtotal phase.
In the case that a CatalogItem
is subject to both additive and inclusive taxes, the additive tax only applies to the
portion of the price that excludes the inclusive tax. For example, if a $100 item has a 10% inclusive tax and a 5%
additive tax, the 5% additive tax applies to the $90.91 base price of the item (the item price minus the inclusive tax).
Technical Overview
The Catalog API includes bulk endpoints to help reduce the number of API calls required for catalog management and pagination of large result sets to reduce server load. Changes made with the Catalog API are stored in Square's database and immediately visible in the Square Dashboard and Square Point of Sale across all merchant locations.
All exchanges with Catalog endpoints use the CatalogObject data type, which is a generalized wrapper for configuring common parameters (e.g, type, id) and package the entity-specific information for each of the core types in Catalog's object model:
{ "type": "{{ [ITEM | ITEM_VARIATION | MODIFIER | MODIFIER_LIST | CATEGORY | DISCOUNT | TAX] }}", "id": "{{ set by Catalog during object creation }}", "updated_at": "{{ date and time of most recent update }}", "version": {{ version of the CatalogObject }}, "is_deleted": [ true | false ], // set by Catalog "connect_v1_ids": { "catalog_v1_id": "{{ itemID from Catalog v1 }}", "location_id": "{{ location where v1 ID is used }}" }, "present_at_all_locations": [ true | false ], "present_at_location_ids": ["{{ LOCATIONID-1 }}", "{{ LOCATIONID-N }}"], "absent_at_location_ids": ["{{ LOCATIONID-1 }}", "{{ LOCATIONID-N }}"], "item_data": { // populated with a CatalogItem object only if type=ITEM }, "item_variation_data": { // populated with a CatalogItemVariation object only if type=ITEM_VARIATION }, "modifier_data": { // populated with a CatalogModifier object only if type=MODIFIER }, "modifier_list_data": { // populated with a CatalogModifierList object only if type=MODIFIER_LIST }, "category_data": { // populated with a CatalogCategory object only if type=CATEGORY }, "discount_data": { // populated with a CatalogDiscount object only if type=DISCOUNT }, "tax_data": { // populated with a CatalogTax object only if type=TAX } }
What's important to note is that the CatalogObject
is a generalized wrapper, it doesn't inherently imply anything
about the data inside, and CatalogObject
s are nested.
For example, consider a product called "Consulting Detective" with two variations called "Sherlock Holmes" and "Shawn
Spencer". This would be represented as a CatalogObject
of type ITEM
that contained two child CatalogObject
entries
of type ITEM_VARIATION
:
{ "type": "ITEM", "id": "W62UWFY35CWMYGVWK6TWJDNI", "updated_at": "2016-11-16T22:25:24.878Z", "version": 1479335124878, "is_deleted": false, "present_at_all_locations": true, "item_data": { "name": "Consulting Detective", "description": "Solver of difficult mysteries; often with excessive ego", "category_id": "BJNQCF2FJ6S6UIDT65ABHLRX", "tax_ids": [ "HURXQOOAIC4IZSI2BEXQRYFY" ], "variations": [ { "type": "ITEM_VARIATION", "id": "2TZFAOHWGG7PAK2QEXWYPZSP", "updated_at": "2016-11-16T22:25:24.878Z", "is_deleted": false, "present_at_all_locations": true, "item_variation_data": { "item_id": "W62UWFY35CWMYGVWK6TWJDNI", "name": "Sherlock Holmes", "ordinal": 0, "pricing_type": "FIXED_PRICING", "price_money": { "amount": 1500, "currency": "USD" } } }, { "type": "ITEM_VARIATION", "id": "2TZFAOHWGG7PAK2QEXWYPZSP", "updated_at": "2016-11-16T22:25:24.878Z", "is_deleted": false, "present_at_all_locations": true, "item_variation_data": { "item_id": "W62UWFY35CWMYGVWK6TWJDNI", "name": "Shawn Spencer", "ordinal": 1, "pricing_type": "FIXED_PRICING", "price_money": { "amount": 5000, "currency": "USD" } } } ] } }
Idempotency Keys
Idempotency keys are strings that are unique across all change requests made by an application to and required for any transaction that could alter data in the catalog. If an identical request is issued, with an unchanged idempotency key, the server will return the same response that it returned for the original request.
Keys should only be reused when it makes sense to retry an identical request. All attempts to reuse an idempotency key with a new (or altered) request will fail. Square stores request and response bodies for a reasonable amount of time, but applications should not plan on being able to retry a request from days or weeks in the past.
Pagination
All endpoints that have the potential to return a large number of objects employ pagination. For large result sets, the endpoint returns an initial subset ( the first page) of objects and a pagination cursor. The pagination cursor is either set to a string that represents the current place in the result set or the empty string if the current page is the final page of results. To fetch the next page, the cursor is appended to the original query request before calling the endpoint again.