Update Storefront Block
Sparse-update one draft widget on a storefront (Creator page). Omitted keys
are left unchanged. Unknown keys at any nesting level return 422.
Do not send type, order, or id — they are not allowed, even when the
value matches the stored widget. type cannot change; hide the old widget
and create a new one.
layout swaps the layout token only. Stored config is left as-is — titles,
photos, and product ids are not re-seeded. The token must be in the
allowlist for the stored type.
layout of "" or null returns 422; omit the key to leave the stored
token.
config is sparse-merged onto the stored config for that type (the same
keys as create). Nested objects
merge; items and fields replace when sent.
An empty body {} returns 200; nothing changes. { "config": {} } is a
write. Hide a widget with is_hidden: true — there is no delete. Hidden
widgets stay on GET so they can be unhidden.
Some widget types are read-only and cannot be updated, including with {}.
They are still returned by GET. See Block.
The response includes a fresh preview_url of the saved draft. Visitors still
see the last published page at public_url until
Publish Storefront.
Request
PATCH /storefronts/{storefrontId}/blocks/{id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
storefrontId | string | Yes | Storefront UUID |
id | string | Yes | Block UUID |
Request Body
All fields are optional. Only include the keys you want to change. Unknown keys are rejected.
| Parameter | Type | Description |
|---|---|---|
layout | string | Layout token for the stored type. Omit to leave. Must be in that type's allowlist. "" and null return 422. Swaps the token only. |
is_hidden | boolean | Omit to leave. true takes the widget off the public page. |
is_hidden_on_mobile | boolean | Omit to leave. Independent of is_hidden. |
config | object | Sparse object merged onto stored config. Nested objects merge; items / fields replace. {} still counts as a write. See Config keys. |
product_id / items[].product_id must be a product UUID of this store, or
"". list_uuid must be a UUID or "". null on those identifiers and on
URL strings clears to "".
Example Requests
Hide a widget:
curl -X PATCH "https://cart.easy.tools/api/v1/storefronts/b10f5980-d653-4494-ad1c-6a9d68c96d19/blocks/372a48fe-9035-4b1c-9257-1aa1fdff415d" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"is_hidden": true
}'
Swap layout without touching config:
curl -X PATCH "https://cart.easy.tools/api/v1/storefronts/b10f5980-d653-4494-ad1c-6a9d68c96d19/blocks/372a48fe-9035-4b1c-9257-1aa1fdff415d" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"layout": "6x3"
}'
Response
Success Response (200)
Returns the widget plus a fresh preview_url. A later
GET of the same widget omits preview_url.
{
"id": "372a48fe-9035-4b1c-9257-1aa1fdff415d",
"type": "product",
"layout": "6x3",
"order": 3,
"is_hidden": true,
"is_hidden_on_mobile": false,
"config": {
"use_block_padding": true,
"use_block_surface": true,
"is_block_highlighted": false,
"product_id": "3288e647-aab0-4289-957f-dac92e9b3ffe",
"photo": {
"media_type": "image",
"src_url": "",
"alt": "",
"video_src_url": "",
"video_autoplay": true,
"video_controls": false,
"video_loop": true,
"iframe_src_url": "",
"is_hidden": false,
"fit": "cover"
},
"title": "Product title",
"price": { "value": "$0.00", "is_hidden": false },
"old_price": { "value": "", "is_hidden": false },
"description": { "value": "Product description", "is_hidden": false },
"link": "",
"cta_label": { "value": "Buy now", "is_hidden": false },
"ownership_status": "show_all",
"owned_cta_label": "Open"
},
"preview_url": "https://cart.easy.tools/storefront-preview/b10f5980-d653-4494-ad1c-6a9d68c96d19?expires=1788349464&signature=901c177ef43e5bbd6857afc112bbf8acad9d475dd62f1a95a8bb65949b97559f"
}
preview_url is a fresh signature on every write, including {}. See
Draft preview.
Response Fields
Block fields are documented on the Block object. Updates
add preview_url:
| Field | Type | Nullable | Description |
|---|---|---|---|
preview_url | string | No | Temporary signed URL of the saved draft. Expires after about one hour. |
Error Responses
Bad Request (400)
Returned when {storefrontId} or {id} is not a UUID. Both path values are checked
before existence.
{
"message": "Invalid storefront ID"
}
{
"message": "Invalid block ID"
}
Not Found Error (404)
Returned when the storefront UUID does not exist, belongs to another store, or
points at a deleted storefront (Storefront not found), or when the block UUID
does not exist on this storefront (Block not found).
{
"message": "Storefront not found"
}
{
"message": "Block not found"
}
Validation Error (422 Unprocessable Entity)
Returned for an unknown key (including type, order, and id), a layout
that is not allowed for the stored type (including "" and null), an
unknown config key, a product_id that is not a product UUID of this store,
an email that is not a valid address, or a read-only widget type
(This block type cannot be updated via this API.).
{
"message": "The type field is not allowed.",
"errors": {
"type": [
"The type field is not allowed."
]
}
}
Unauthorized (401)
{
"message": "Unauthenticated."
}
Forbidden (403)
Returned when your API key has not been granted access to the requested store.
{
"message": "You do not have API access to the requested store."
}
Too Many Requests (429)
Returned when you exceed the rate limit. The Retry-After response header gives
the number of seconds to wait.
{
"message": "Too many requests. Please retry after 60 seconds."
}