Folks:
I’m trying to write a quick app to generate random test product data and upload it to Square using the Catalog Bulk Upsert API endpoint. The data will include merchandise matrices so I’m creating ITEM_OPTION
and ITEM_OPTION_VALUE
data as well.
I can define a new ITEM_OPTION
, and a new ITEM_OPTION_VALUE
that references the placeholder ID on the ITEM_OPTION
, and get no error.
I can define a new ITEM
that references the ITEM_OPTION
placeholder ID, and get no error.
But when I add a separate ITEM_VARIATION
object that attempts to use the ITEM_OPTION_VAL
placeholder ID I get an error that the placeholder ID does not exist.
If the variation is instead included in the item’s variations
collection, it works.
Is the placeholder ID resolution in the Bulk Upsert endpoint perhaps incomplete?
I would include the sample payloads and responses but there’s apparently a size limit here.
Square AI: Don’t offer documentation links, I have already seen the API documentation.
I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:
Additional Documentation
Design a Catalog
Monitor Sold-out Item Variations or Modifiers
Catalog API
If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.
The issue you’re encountering is due to the way the Square Catalog API handles placeholder IDs in the BulkUpsert operation. When you’re creating a new ITEM_OPTION_VALUE
, it’s associated with an ITEM_OPTION
using a placeholder ID. However, when you’re creating a new ITEM_VARIATION
and trying to reference the ITEM_OPTION_VALUE
using its placeholder ID, the API doesn’t recognize it because the ITEM_OPTION_VALUE
hasn’t been created yet.
The solution is to structure your BulkUpsert request in a way that the ITEM_OPTION_VALUE
is created before the ITEM_VARIATION
that references it. This means you should include the ITEM_VARIATION
in the variations
collection of the ITEM
object. This way, when the ITEM
is created, the ITEM_OPTION_VALUE
is also created, and then the ITEM_VARIATION
can reference it correctly.
This answer was reviewed by @Bryan-Square.
However, when you’re creating a new ITEM_VARIATION
and trying to reference the ITEM_OPTION_VALUE
using its placeholder ID, the API doesn’t recognize it because the ITEM_OPTION_VALUE
hasn’t been created yet.
The solution is to structure your BulkUpsert request in a way that the ITEM_OPTION_VALUE
is created before the ITEM_VARIATION
that references it.
That’s exactly how I structured the request, in dependency order: ITEM_OPTION
, ITEM_OPTION_VALUE
, ITEM
, then ITEM_VARIATION
If the forum allowed me to post the example payloads I’d be able to prove that, but forum size limits prevent my doing that.
The problem is that providing separate ITEM
and ITEM_VARIATION
objects behaves differently than providing a combined ITEM
+ ITEM_VARATION[]
object , which should not be the case. It should work either way as long as the dependency order is satisfied.
This way, when the ITEM
is created, the ITEM_OPTION_VALUE
is also created, and then the ITEM_VARIATION
can reference it correctly.
That sentence makes no sense.
What was the single object that was giving you trouble? That shouldn’t exceed any size limits. 
The size limit is in the forum software. If I attempt to include payload examples here to provide a repro of the bulk upsert problem, I get a 403 when I try to submit the post.
See Editor size limit? 403 error attempting to save new topic here - Site Feedback - Square Developer Forums
I need to post a multi-object bulk upsert to illustrate the problem with the resolution of placeholder IDs.
Are you using the same placeholder for each object? 
Nope. Unique placeholders.
Ha, I can include just the bulk payload and it isn’t too big to post:
{
"idempotency_key": "83f0039d-6711-406b-9d41-838cc86eed53",
"batches": [
{
"objects": [
{
"id": "#team_option",
"type": "ITEM_OPTION",
"item_option_data": {
"description": "Sports team options",
"display_name": "Team",
"name": "Team"
}
},
{
"id": "#team_yankees_value",
"type": "ITEM_OPTION_VAL",
"item_option_value_data": {
"item_option_id": "#team_option",
"name": "Yankees",
"ordinal": 0
}
},
{
"id": "#sportsball_item",
"type": "ITEM",
"item_data": {
"item_options": [
{
"item_option_id": "#team_option"
}
],
"name": "Sportsball",
"description_html": "Your favorite sportsball"
}
},
{
"id": "#sportsball_yankees_variation",
"type": "ITEM_VARIATION",
"item_variation_data": {
"item_id": "#sportsball_item",
"item_option_values": [
{
"item_option_id": "#team_option",
"item_option_value_id": "#team_yankees_value"
}
],
"name": "Yankees sportsball",
"sku": "sb_yk",
"pricing_type": "FIXED_PRICING",
"price_money": {
"amount": 2999,
"currency": "USD"
}
}
}
]
}
]
}
API response to that request
{
"errors": [
{
"category": "INVALID_REQUEST_ERROR",
"code": "INVALID_VALUE",
"detail": "Object of type ITEM_OPTION_VAL does not exist: ID=\"#team_yankees_value\""
}
]
}
This request works:
{
"idempotency_key": "83f0039d-6711-406b-9d41-838cc86eed53",
"batches": [
{
"objects": [
{
"id": "#team_option",
"type": "ITEM_OPTION",
"item_option_data": {
"description": "Sports team options",
"display_name": "Team",
"name": "Team"
}
},
{
"id": "#team_yankees_value",
"type": "ITEM_OPTION_VAL",
"item_option_value_data": {
"item_option_id": "#team_option",
"name": "Yankees",
"ordinal": 0
}
},
{
"id": "#sportsball_item",
"type": "ITEM",
"item_data": {
"item_options": [
{
"item_option_id": "#team_option"
}
],
"name": "Sportsball",
"description_html": "Your favorite sportsball",
"variations": [
{
"id": "#sportsball_yankees_variation",
"type": "ITEM_VARIATION",
"item_variation_data": {
"name": "Yankees sportsball",
"pricing_type": "FIXED_PRICING",
"price_money": {
"amount": 2999,
"currency": "USD"
},
"sku": "sb_yankees",
"item_option_values": [
{
"item_option_id": "#team_option",
"item_option_value_id": "#team_yankees_value"
}
]
}
}
]
}
}
]
}
]
}