Applies to: Catalog API
Learn how to enable item customization with list-based and text-based modifiers.
Modifiers help a seller define fewer, more general kinds of catalog items. The buyer chooses the specific item modifiers at checkout. This is useful when the item is assembled at purchase from many different parts. For example, a seller can have one Hamburger item and let the buyer pick cheeses, condiments, buns, and other options. Without modifiers, the seller needs to define a variation of Hamburger for each combination of options.
When ordering a hamburger, the buyer might add a slice of cheese, such as gorgonzola for $1 or cheddar for $0.75. These cheese options are called modifiers options and are represented by a cheese CatalogModifier in the Catalog API. The seller sets the price for each modifier option. When the item is sold, the total price includes the basic item price and the price of each selected modifier option.
Catalog modifiers are also useful to sellers in other categories:
- Custom printed text - A buyer wants a T-shirt with custom text on the front and back.
- Assembled to order - A buyer orders a personal computer built from a selection of standard components.
Note
Default catalog modifier pricing can be overridden location by location if you set a location_overrides price.
The Square catalog supports two types of modifiers:
- List-based modifiers
- Text-based modifiers
A list of modifier options (CatalogModifierList) lets customers pick options when buying. For example, a restaurant might offer a hamburger (CatalogItem) with optional cheese (CatalogModifier). The customer can choose from cheeses like pepper jack, cheddar, or provolone.
The hamburger might also have other options like bun type, meat-cooking temperature, and sauces. Each of these options can have a list-based modifier. The restaurant can set up these modifier lists in the catalog for customers to personalize their orders.
To enable customization, the correct modifiers must be created and assigned to the product in the catalog. These modifiers are shown to the buyer when ordering. This process is managed using the Catalog API. Showing product modifications is important and built into Square Point of Sale or third-party applications integrated with the Orders API.
This cheese example describes the use of list-based modifiers, which are represented by a list of CatalogModifier objects in a CatalogModifierList object. The data model of list-based modifiers are shown in the following example UpsertCatalogObject
request body:
The requested modifier list has three cheese choices, each adding $.10 to the price of a hamburger if selected. The buyer can only choose one of the cheeses per hamburger.
A seller has two locations it delivers cheese to: one at Point Reyes Station, CA, and one at a research station in Antarctica. The specialty cheese is created in small batches and delivered daily. At the seller's Antarctica location VJN4XSBFTVPK9
, the cheese is significantly more expensive to deliver so the seller is overriding the default price of 20 cents to a dollar per slice.
{
"id": "#modifier-list",
"type": "MODIFIER_LIST",
"modifier_list_data": {
"internal_name": "Hamburger cheese choices",
"modifier_type": "LIST",
"name": "Cheese Choices",
"ordinal": 1,
"selection_type": "SINGLE",
"text_required": false,
"modifiers": [
{
"id": "#cheese-one",
"type": "MODIFIER",
"modifier_data": {
"modifier_list_id": "#modifier-list",
"name": "Toma",
"ordinal": 1,
"price_money": {
"amount": 20,
"currency": "USD"
},
"location_overrides": [
{
"location_id": "VJN4XSBFTVPK9",
"price_money": {
"amount": 100,
"currency": "USD"
}
}
]
}
},
{
"id": "#cheese-two",
"type": "MODIFIER",
"modifier_data": {
"modifier_list_id": "#modifier-list",
"name": "Pepperjack",
"ordinal": 1,
"price_money": {
"amount": 10,
"currency": "USD"
}
}
},
{
"id": "#cheese-three",
"type": "MODIFIER",
"modifier_data": {
"modifier_list_id": "#modifier-list",
"name": "Munster",
"ordinal": 1,
"price_money": {
"amount": 10,
"currency": "USD"
}
}
}
]
}
}
With list-based modifiers, the CatalogModifierList
object contains a non-empty list of CatalogModifier
objects.
A text-based modifier lets the buyer set a text property when buying. For example, a seller offers T-shirts with custom printed phrases. The buyer can choose text to be printed on a shirt. If the shirt supports text on both the front and back, two text modifiers are used.
An example of a text-based modifier is when a buyer chooses custom text to be printed on a T‑shirt sold by a seller. This customization is represented as a CatalogModifierList
object.
Note
Text-based modifiers don't have a modifiers
list property.
The data model of text-based modifiers are shown in the following example UpsertCatalogObject
request body:
{
"id": "#shirt-front-text",
"type": "MODIFIER_LIST",
"modifier_list_data": {
"modifier_type": "TEXT",
"internal_name": "Front of shirt",
"max_length": 20,
"name": "Shirt Front Text",
"ordinal": 0,
"selection_type": "SINGLE",
"text_required": true
}
}
The text modifier is represented by CatalogModifierList
, which means price and other modifier properties cannot be set for it. The selection_type
is always SINGLE
. Any attempt to set MULTIPLE
is ignored. The cost of printing text on the shirt in this example is built into the price of the shirt itself, not on the text modifier.
To enable list-based modifiers, call the BatchUpsertCatalogObjects endpoint to create the following objects:
CatalogModifierList
- Set themodifier_type
property toLIST
. Assign a non-empty list ofCatalogModifier
objects on themodifiers
property.CatalogItem
- Within themodifier_list_info
property (CatalogItemModifierListInfo), reference the modifier list and how the modifier can be selected at the time of sale.
The following example invokes BatchUpsertCatalogObjects
to create the list and item. If you're making two UpsertCatalogObject
calls instead of a batch call, do them in the following order:
- Create a
CatalogModifierList
object - It contains a list of twoCatalogModifier
objects for the gorgonzola cheese and pecorino cheese modifiers. - Create a
CatalogItem
object - This is the cheeseburger item with the two cheese modifiers included as optional add-ons for the buyer to choose from.
Batch upsert catalog objects
The modifiers have their own pricing. In this example, each costs $1. The MULTIPLE
selection type declared within the CatalogModifierList
object means that this hamburger can have more than one type of cheese added to it. If the selection type is SINGLE
, the cheeseburger can have cheddar or pepper jack cheese added to it, but not both.
The number of cheeses a buyer can select when ordering the hamburger is specified by the min_selected_modifiers
and max_selected_modifiers
values within the modifier_list_info
property of the CatalogItem
object. In this example, because min_selected_modifiers=0
and max_selected_modifiers=2
, the buyer can select 0, 1, or 2 cheeses when ordering the hamburger and be charged $7, $8, or $9, respectively. For a $9 hamburger, it can have one of these cheese options:
- One cheddar and one pepper jack
- Two portions of cheddar
- Two portions of pepper jack
When a buyer orders a hamburger, their modifier selections are only recorded in the Order object that's created.
Note
The value of the selection_type property determines the behavior of CatalogItem
modifier_list_info min_selected_modifiers
and max_selected_modifiers
when these properties are both set to -1:
selection_type
is "MULTIPLE" - Allows unlimited selections. This allows anywhere between none and all of the modifiers in the list to be selected.selection_type
is "SINGLE" - Requires the selection of one modifier. Setting the values to1
has the same effect.
To enable text-based modifiers on an item, call the UpsertCatalogObject
or BatchUpsertCatalogObjects
endpoint to create the following catalog objects:
CatalogModifierList
- Set themodifier_type
property toTEXT
. Don't set themodifiers
list property.CatalogItem
- Reference the modifier list in themodifier_list_info
property of the item.
For a text-based modifier, don't specify min_selected_modifiers
and max_selected_modifiers
to define the selectable quantity because they don't apply to any text-based modifier.
The following example invokes BatchUpsertCatalogObjects
to create these catalog objects:
CatalogModifierList
- A text-based modifier with properties specific to text-based modifiers.CatalogItem
- A custom-print T-shirt item with text printed on the front.
Batch upsert catalog objects
In the specification of the text-based modifier (CatalogModifierList
), modifier_list_data
has two properties for text-based modifiers. These are in addition to the standard properties that apply to the CatalogModifierList
object.
max_length
- Sets the limit of the buyer-supplied text, with the default length of 150 unicode characters.text_required
- Determines whether buyer-supplied text can be empty (false
) or not (true
). The default value isfalse
.
The seller might use the internal_name
property for internal custom printing instructions.
If the custom-print T-shirt can have text printed on the front and back, a Back Print
catalog object of the MODIFIER_LIST
type can be inserted after the Front Print
text-based modifier, as shown in this catalog_object
example:
{
"catalog_object": {
"type": "MODIFIER_LIST",
"id": "ICURICUB2KOOL4MEGWJNQUNL",
"updated_at": "2024-09-19T20:43:42.067Z",
"created_at": "2024-09-19T20:43:42.067Z",
"version": 1726778622067,
"is_deleted": false,
"present_at_all_locations": true,
"modifier_list_data": {
"name": "Back Print",
"ordinal": 1,
"selection_type": "SINGLE",
"modifier_type": "TEXT",
"max_length": 150,
"text_required": false,
"internal_name": "Use 48pt font"
}
}
}
Square updates the CatalogObject.item_data.modifier_list_info
list to reference the object IDs of the front and back text modifiers, as shown in the following example:
{
"modifier_list_info": [
{
"modifier_list_id": "KUIOL3JMAZ3MERZQGWJNQUPJ",
"enabled": true
},
{
"modifier_list_id": "ICURICUB2KOOL4MEGWJNQUNL",
"enabled": true
}
]
}
Note
If your application uses BatchUpsertCatalogObjects
to create the shirt catalog item, then the referenced IDs are the temporary IDs you assign in the batch request.
When the second text modifier is added, the buyer provides text for the front when ordering the T-shirt, but might not want text for the back.
Occasionally, a seller might want to reassign different modifier lists to existing catalog items. The assignment is stored in the CatalogItem.modifier_list_info
property. To change it, your application makes an UpsertCatalogObject
call. Because the Catalog API doesn't support sparse updates, you need to fetch the CatalogItem
, update the modifier_list_info
property, and make the update request with the full catalog object body.
The Catalog API provides another way to reassign lists. Using the UpdateItemModifierLists endpoint, provide the ID of the catalog item whose modifier list you want to change. Provide the IDs of the lists you want to enable for the catalog item and those you want to disable. If multiple catalog items need to have the same modifier lists reassigned, you can batch the updates by providing the IDs of each catalog item in a single API call.
When multiple catalog objects are created, you can call UpsertCatalogObject
for each object to be created or call BatchUpsertCatalogObjects
once to create all the required catalog objects.
When making individual UpsertCatalogObject
calls to create a set of related objects, you need to parse the id_mappings
property from each response. This property contains the object IDs that you use in subsequent calls to create related objects.
When using the BatchUpsertCatalogObjects
, you define your own temporary object IDs to be used within the single batch request body. These IDs tell Square how you want new objects to relate to each other. With the batch operation, you don't need to parse each individual response to get the Square-assigned IDs.
Square recommends using the batch pattern because it's more efficient. The seller using your application might make many updates over a short period. In this case, the batch pattern is advised. If your application uses the individual pattern, it can be rate-limited by Square when your seller makes too many updates too often.