Categories require product scopes. Reads use read_products; writes use write_products. Categories support parent_id, name, slug, description, seo_title, seo_description, image_id, and template_handle fields. slug is optional on create and generated from the name when omitted; on update, omit it to keep the current slug or send an empty string to regenerate it from the name. parent_id builds the category hierarchy. Assigning a non-empty image_id also requires read_files for the referenced upload image. On create, omitting template_handle assigns default_category. Use default_category for the default Category template, or pass an alternate Category template handle configured for the store. Omit template_handle on update to leave the current assignment unchanged; an empty string is invalid. AI translation is not exposed through the Store API.
Endpoints#
Category limits
Fetch Category limits and per-field constraints.
Returns the per-field maximum lengths, hierarchy depth, and request caps that apply to Category endpoints. Useful for clients to validate inputs before sending them and to size UIs. max_per_store is this store's plan cap, count is how many exist now, and usage is the localized label.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
List categories
List categories for the store.
Returns paginated categories. With tree=true and no search or filters, limit paginates root categories; the selected roots and their descendants are then expanded into one nested page. Expansion is deterministic and ancestor-first, with siblings ordered by name and then id, and is capped at request_caps.tree_max_limit total category nodes across the whole root page, including the roots, and at the 512 KiB reply budget. When more nodes exist or the next node would pass the budget, the response returns the prefix that fits and sets truncated: true; later descendants or entire later root subtrees can therefore be absent even when has_next is false. has_next, has_previous, next_cursor, previous_cursor, and total describe root-category pagination only and do not describe omitted descendants. To retrieve every category, use the flat list (tree=false) with cursor pagination; add ancestor_id when a complete flat listing of one category's descendants is needed. Any search or filter also switches the response to the ordinary flat, cursor-paginated list, where truncated is false. A flat page holds at most list_max_limit (100) categories with every field, description included. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.
Query parameters
| Name | Type | Description |
|---|---|---|
cursor
|
string |
Opaque cursor from a previous |
limit
|
integer |
Page size, 1-100 (default 50). Larger values return |
tree
|
boolean |
When true and no search or filters are active, paginate roots by |
search
|
string |
Search categories by name or slug. Maximum 200 characters. |
parent_id
|
string |
|
ancestor_id
|
integer |
Filter to descendants of this ancestor category id. Must be a positive integer. |
has_children
|
boolean |
Filter categories by whether they have subcategories. Accepted values: true, false. |
has_images
|
boolean |
Filter categories by whether they have an image. Accepted values: true, false. |
sort_by
|
string |
Sort field. Allowed values: name, product_count, created_at, updated_at.
Allowed values
nameproduct_countcreated_atupdated_at |
sort_direction
|
string |
Sort direction. Allowed values: asc, desc.
Allowed values
ascdesc |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400CATEGORY_LIST_INVALID_LIMITLimit must be within the documented list range.
-
400INVALID_INPUTCursor is malformed or does not match the current list state.
-
400CATEGORY_SEARCH_TOO_LONGSearch exceeds the configured maximum length.
-
400CATEGORY_LIST_INVALID_SORT_BYSort_by is not one of the documented fields.
-
400CATEGORY_LIST_INVALID_SORT_DIRECTIONSort_direction is not asc or desc.
-
400CATEGORY_LIST_INVALID_PARENT_IDParent_id is neither null nor a positive integer.
-
400CATEGORY_LIST_INVALID_ANCESTOR_IDAncestor_id is not a positive integer.
-
400CATEGORY_LIST_INVALID_BOOLEANA boolean list filter is not true or false.
-
400LIST_RESPONSE_TOO_LARGEThe page would be larger than the 512 KiB reply budget (long descriptions or many options). Request it again with a lower
limit;error.params.fitestimates how many rows fit.
Search categories
Search categories for picker-style suggestions.
Returns lightweight category suggestions by query. This endpoint is intended for pickers and simple selection UIs.
Query parameters
| Name | Type | Description |
|---|---|---|
q
|
string |
Search query. Maximum 200 characters. |
limit
|
integer |
Suggestion count. Defaults to 10. Maximum 50. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400CATEGORY_LIST_INVALID_LIMITLimit must be within the documented suggestion range.
-
400CATEGORY_SEARCH_TOO_LONGQ exceeds the configured maximum length.
Get a category
Fetch one category by id.
Returns the category if it belongs to the token's store. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Category id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400STORE_API_INVALID_CATEGORY_IDId is not an integer.
-
404CATEGORY_NOT_FOUNDCategory does not exist in this store.
List category metafields
List a category's custom-data values visible to the calling app.
Returns a paginated list. Definitions are filtered through the calling app's access rules; private app-owned definitions are visible only to their owner. Values are addressed by namespace and key.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Category id. |
Query parameters
| Name | Type | Description |
|---|---|---|
page
|
integer |
Page number (default 1). |
limit
|
integer |
Page size; capped by the metafield list limit. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400STORE_API_INVALID_CATEGORY_IDId is not a positive integer.
-
400VALIDATION_LIST_INVALID_PAGEPage must be at least 1.
-
400VALIDATION_LIST_INVALID_LIMITLimit is outside the supported range.
-
404NOT_FOUNDCategory does not exist in this store.
Set category metafields
Create, update, or delete category custom-data values.
Send namespace-and-key entries. A string value creates or replaces a value; null or an empty string deletes it. Definition access, type, constraint, reference, translation-staleness, search-index, audit, and webhook rules are applied in the same transaction.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Category id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
metafields
required
|
array<object> |
Entries shaped as |
Errors
-
400STORE_API_INVALID_CATEGORY_IDId is not a positive integer.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400METAFIELD_NO_WRITESAt least one metafield entry is required.
-
400METAFIELD_DUPLICATE_WRITEThe request contains the same namespace and key more than once.
-
400PRODUCT_METAFIELD_DEF_NOT_FOUNDThe namespace and key do not identify a definition visible to the token. For an app token only its own definitions count: merchant-owned and other apps' definitions return this code.
-
403METAFIELD_WRITE_MERCHANT_READ_ONLYThe app-owned definition does not allow Store Admin writes.
-
404NOT_FOUNDCategory does not exist in this store. A file reference names a file that does not exist in this store.
-
400METAFIELD_VALUE_TOO_LONGThe value exceeds its size limit: the definition's max_value_length, or the platform value size limit for the type.
-
400METAFIELD_VALUE_STRING_TOO_LONGA string value exceeds the definition's max_value_length or the platform string limit.
-
400METAFIELD_VALUE_TOO_SHORTA string value is shorter than the definition's min_length rule.
-
400METAFIELD_VALUE_PATTERN_MISMATCHA string value does not match the definition's pattern rule.
-
400METAFIELD_VALUE_INTEGER_INVALIDAn integer value is not a whole number in the 64-bit range.
-
400METAFIELD_VALUE_INTEGER_TOO_LONGAn integer value has more digits than the definition or the platform integer limit allows.
-
400METAFIELD_VALUE_DECIMAL_INVALIDA decimal value is not a finite decimal number.
-
400METAFIELD_VALUE_DECIMAL_TOO_LONGA decimal value, written out in full, is longer than the definition or the platform decimal limit allows.
-
400METAFIELD_VALUE_BELOW_MINAn integer or decimal value is below the definition's min rule.
-
400METAFIELD_VALUE_ABOVE_MAXAn integer or decimal value is above the definition's max rule.
-
400METAFIELD_VALUE_BOOLEAN_INVALIDA boolean value is not true or false.
-
400METAFIELD_VALUE_DATE_INVALIDA date value is not a calendar date in YYYY-MM-DD form.
-
400METAFIELD_VALUE_DATETIME_INVALIDA datetime value is not YYYY-MM-DDTHH:mm, YYYY-MM-DDTHH:mm:ss or an RFC 3339 timestamp.
-
400METAFIELD_VALUE_JSON_INVALIDA json value is not valid JSON.
-
400METAFIELD_VALUE_JSON_UNSAFE_LINKA json value contains a link whose scheme is not http, https, mailto or tel.
-
400METAFIELD_VALUE_URL_INVALIDA url value, or an item of a list.url value, is not an absolute URL with a host.
-
400METAFIELD_VALUE_URL_SCHEMEA url value, or an item of a list.url value, does not use http or https.
-
400METAFIELD_VALUE_URL_TOO_LONGA url value, or an item of a list.url value, exceeds the definition's max_value_length or the platform URL limit.
-
400METAFIELD_VALUE_NOT_IN_CHOICESA single_select value is not one of the definition's choice keys.
-
400METAFIELD_LIST_CHOICE_INVALIDAn item of a list.single_select value is not one of the definition's choice keys; the message names the item.
-
400METAFIELD_LIST_STRINGS_INVALIDA list.string or list.single_select value is not a JSON array of strings.
-
400METAFIELD_LIST_URLS_INVALIDA list.url value is not a JSON array of strings.
-
400METAFIELD_LIST_FILES_INVALIDA list.file_reference value is not a JSON array of strings.
-
400METAFIELD_LIST_IDS_INVALIDA list.product_reference or list.variant_reference value is not a JSON array of integers.
-
400METAFIELD_LIST_EMPTYA list value other than list.string is an empty array. Send null or an empty string to remove the value instead.
-
400METAFIELD_LIST_TOO_MANYA list value has more items than the definition's max_list_items or the platform list limit for the type.
-
400METAFIELD_LIST_ITEM_EMPTYAn item of a list.string value is empty or only whitespace; the message names the item.
-
400METAFIELD_LIST_ITEM_TOO_LONGAn item of a list.string value exceeds the definition's max_value_length or the platform string limit; the message names the item.
-
400METAFIELD_VALUE_FILE_UUID_INVALIDA file_reference value, or an item of a list.file_reference value, is not a file UUID.
-
400METAFIELD_VALUE_ID_INVALIDA product_reference or variant_reference value is not an integer ID.
-
400METAFIELD_VALUE_ID_POSITIVEA product_reference or variant_reference value is not a positive integer.
-
400METAFIELD_VALUE_ID_TOO_LONGA product_reference or variant_reference value exceeds the platform reference ID limit.
-
400METAFIELD_LIST_ITEMS_POSITIVEAn item of a list.product_reference or list.variant_reference value is not a positive integer.
-
400METAFIELD_REFERENCE_PRODUCT_MISSINGA product reference names a product that does not exist in this store.
-
400METAFIELD_REFERENCE_VARIANT_MISSINGA variant reference names a variant that does not exist in this store.
-
400INVALID_INPUTA file reference names a file that is not an uploaded file.
Create a category
Create a category.
Creates a category. name is required; optional text fields, hierarchy assignment, image assignment, and template assignment follow the Category resource contract. If image_id is non-empty, it must point to an upload image in the same store and the token must also have read_files. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Idempotency-Key
|
string |
Optional key, up to 255 characters, that makes this create safe to retry. Repeating the request with the same key and body within 24 hours returns the original response instead of creating again; the same key with a different body returns |
Body parameters
| Name | Type | Description |
|---|---|---|
name
required
|
string |
Category name. |
slug
|
string |
Optional slug. Omit to generate from name. |
parent_id
|
integer |
Optional parent category id. Omit or send 0 for a root category. |
description
|
string |
Optional plain-text description. |
seo_title
|
string |
Optional SEO title. Omit or send an empty string to let the storefront fall back to the Category name. |
seo_description
|
string |
Optional SEO description. Omit or send an empty string to let the storefront fall back to the Category description. |
image_id
|
string |
Optional Media-library upload image UUID. Non-empty values require |
template_handle
|
string |
Category template assignment. Omit this field, send an empty string, or send |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400STORE_API_CREATE_REDIRECT_UNSUPPORTEDCreate_redirect is only supported on update.
-
400CATEGORY_NAME_REQUIREDName is empty after normalization.
-
400CATEGORY_NAME_INVALID_CHARSName contains forbidden control characters.
-
400CATEGORY_NAME_TOO_LONGName exceeds the Category contract max length.
-
400CATEGORY_SLUG_INVALID_FORMATSlug is not valid for Category URLs.
-
400CATEGORY_SLUG_TOO_LONGSlug exceeds the Category contract max length.
-
400CATEGORY_SLUG_GENERATION_FAILEDA slug could not be generated from the supplied name.
-
400CATEGORY_UNIQUE_SLUG_GENERATION_FAILEDA unique generated slug could not be allocated.
-
400CATEGORY_DESCRIPTION_INVALID_CHARSDescription contains forbidden control characters.
-
400CATEGORY_DESCRIPTION_TOO_LONGDescription exceeds the Category contract max length.
-
400CATEGORY_SEO_TITLE_INVALID_CHARSSEO title contains forbidden control characters.
-
400CATEGORY_SEO_TITLE_TOO_LONGSEO title exceeds the Category contract max length.
-
400CATEGORY_SEO_DESCRIPTION_INVALID_CHARSSEO description contains forbidden control characters.
-
400CATEGORY_SEO_DESCRIPTION_TOO_LONGSEO description exceeds the Category contract max length.
-
400CATEGORY_DEPTH_EXCEEDEDParent assignment would exceed the category hierarchy depth limit.
-
400CATEGORY_CANNOT_BE_OWN_PARENTA category cannot be its own parent.
-
400CATEGORY_CANNOT_BE_DESCENDANT_PARENTParent assignment would create a cycle.
-
400CATEGORY_PARENT_NOT_FOUNDParent category does not exist in this store.
-
400TEMPLATE_HANDLE_INVALIDTemplate handle is not valid for Category templates.
-
400TEMPLATE_HANDLE_NOT_FOUNDTemplate handle does not exist on the store's primary active theme for Category.
-
400INVALID_INPUTImage_id is malformed, is not an image, or is not a merchant upload.
-
403STORE_API_SCOPE_REQUIREDA non-empty image_id requires read_files scope in addition to write_products.
-
404NOT_FOUNDImage_id does not reference a file in this store.
-
404CATEGORY_NOT_FOUNDCategory does not exist in this store.
-
409CATEGORY_DUPLICATEName already exists under the same parent, or slug already exists in this store.
-
409TRANSLATION_SOURCE_FIELD_HAS_TRANSLATIONSA source field cannot be cleared while translations still exist.
-
400CATEGORY_PLAN_LIMIT_REACHEDThe store has as many categories as its plan allows; the message states the maximum. Fetch
/categories/limitsfor the store's current cap and usage. -
400CATALOG_REQUEST_KEY_TOO_LONGIdempotency-Keyis longer than 255 characters. -
403PLAN_UNKNOWNThe store has no active plan, so nothing can be created until one is chosen.
-
409CATALOG_REQUEST_KEY_CONFLICTIdempotency-Keywas already used with a different request body.
Bulk create categories
Create multiple categories by name.
Creates multiple root categories from names. Slugs are generated automatically; existing names are skipped and reported in skipped. The plan cap applies per row: when the batch would pass it, the rows that fit are created and the response is still 200, with each refused name in row_errors (code CATEGORY_PLAN_LIMIT_REACHED, a localized message and args.max). Check row_errors on every response. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Idempotency-Key
|
string |
Optional key, up to 255 characters, that makes this create safe to retry. Repeating the request with the same key and body within 24 hours returns the original response instead of creating again; the same key with a different body returns |
Body parameters
| Name | Type | Description |
|---|---|---|
names
required
|
array<string> |
Category names to create. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400CATEGORY_BULK_NO_NAMESNo names were provided.
-
400CATEGORY_BULK_CREATE_TOO_MANYBatch exceeds the Category bulk create cap.
-
400CATEGORY_NAME_INVALID_CHARSOne name contains forbidden control characters.
-
400CATEGORY_NAME_TOO_LONGOne name exceeds the Category contract max length.
-
400CATEGORY_SLUG_GENERATION_FAILEDA slug could not be generated from one name.
-
400CATEGORY_UNIQUE_SLUG_GENERATION_FAILEDA unique generated slug could not be allocated.
-
409CATEGORY_BULK_DUPLICATEOne of the names in the batch was just created by another request.
-
400CATALOG_REQUEST_KEY_TOO_LONGIdempotency-Keyis longer than 255 characters. -
403PLAN_UNKNOWNThe store has no active plan, so nothing can be created until one is chosen.
-
409CATALOG_REQUEST_KEY_CONFLICTIdempotency-Keywas already used with a different request body.
Update a category
Update a category.
Updates provided Category fields. Omitted fields are left unchanged. Sending parent_id: 0 moves the category to the root. Sending an empty image_id clears the image; sending a non-empty image_id requires read_files and the referenced file must be an upload image in the same store. Sending create_redirect can create a slug redirect when the slug changes. storefront_url is the canonical absolute URL on the store's primary domain. storefront_path is the domain-independent baseline route; join it to the storefront address you are targeting. Hosted storefront responses apply translated slugs and locale/country prefixes.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Category id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
name
|
string |
New Category name. Omit to leave it unchanged; an empty value is invalid. |
slug
|
string |
New slug. Omit to leave the current slug unchanged; send an empty string to regenerate it from the current Category name. |
parent_id
|
integer |
New parent category id. Omit to leave it unchanged; send 0 to move the Category to the root. |
description
|
string |
New plain-text description. Omit to leave it unchanged; send an empty string to clear it. |
seo_title
|
string |
New SEO title. Omit to leave it unchanged; send an empty string to clear it and restore the storefront Category-name fallback. |
seo_description
|
string |
New SEO description. Omit to leave it unchanged; send an empty string to clear it and restore the storefront Category-description fallback. |
image_id
|
string |
New Media-library upload image UUID. Omit to leave the image unchanged; send an empty string to clear it. A non-empty value requires |
template_handle
|
string |
New Category template assignment. Omit to leave it unchanged, send |
create_redirect
|
boolean |
When slug changes, create a redirect from the previous slug. |
Errors
-
409CATEGORY_CHANGED_DURING_EDITThe category changed since this edit began. Read it again before saving.
-
400STORE_API_INVALID_CATEGORY_IDId is not an integer.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400CATEGORY_NAME_REQUIREDName is empty after normalization.
-
400CATEGORY_NAME_INVALID_CHARSName contains forbidden control characters.
-
400CATEGORY_NAME_TOO_LONGName exceeds the Category contract max length.
-
400CATEGORY_SLUG_INVALID_FORMATSlug is not valid for Category URLs.
-
400CATEGORY_SLUG_TOO_LONGSlug exceeds the Category contract max length.
-
400CATEGORY_SLUG_GENERATION_FAILEDA slug could not be generated from the supplied name.
-
400CATEGORY_UNIQUE_SLUG_GENERATION_FAILEDA unique generated slug could not be allocated.
-
400CATEGORY_DESCRIPTION_INVALID_CHARSDescription contains forbidden control characters.
-
400CATEGORY_DESCRIPTION_TOO_LONGDescription exceeds the Category contract max length.
-
400CATEGORY_SEO_TITLE_INVALID_CHARSSEO title contains forbidden control characters.
-
400CATEGORY_SEO_TITLE_TOO_LONGSEO title exceeds the Category contract max length.
-
400CATEGORY_SEO_DESCRIPTION_INVALID_CHARSSEO description contains forbidden control characters.
-
400CATEGORY_SEO_DESCRIPTION_TOO_LONGSEO description exceeds the Category contract max length.
-
400CATEGORY_DEPTH_EXCEEDEDParent assignment would exceed the category hierarchy depth limit.
-
400CATEGORY_CANNOT_BE_OWN_PARENTA category cannot be its own parent.
-
400CATEGORY_CANNOT_BE_DESCENDANT_PARENTParent assignment would create a cycle.
-
400CATEGORY_PARENT_NOT_FOUNDParent category does not exist in this store.
-
400TEMPLATE_HANDLE_INVALIDTemplate handle is not valid for Category templates.
-
400TEMPLATE_HANDLE_NOT_FOUNDTemplate handle does not exist on the store's primary active theme for Category.
-
400INVALID_INPUTImage_id is malformed, is not an image, or is not a merchant upload.
-
403STORE_API_SCOPE_REQUIREDA non-empty image_id requires read_files scope in addition to write_products.
-
404NOT_FOUNDImage_id does not reference a file in this store.
-
404CATEGORY_NOT_FOUNDCategory does not exist in this store.
-
409CATEGORY_DUPLICATEName already exists under the same parent, or slug already exists in this store.
-
409TRANSLATION_SOURCE_FIELD_HAS_TRANSLATIONSA source field cannot be cleared while translations still exist.
Delete a category
Delete a category.
Deletes a category. Subcategories and assigned products block deletion. If collection rules, discounts, or menu items require confirmation, retry with the returned confirmation token.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Category id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
confirmed
|
boolean |
On a confirmation retry, set this to true and send the returned confirmation_token. Omit it on the first request. |
confirmation_token
|
string |
Token from the CONFIRMATION_REQUIRED response. Omit it on the first request and resend the exact same id selection when using it. |
Errors
-
400STORE_API_INVALID_CATEGORY_IDId is not an integer.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400CATEGORY_CONFIRMATION_INVALIDConfirmation token is missing, expired, or mismatched.
-
400CATEGORY_BULK_DELETE_TOO_MANYBatch exceeds the Category bulk delete cap.
-
404CATEGORY_NOT_FOUNDCategory does not exist in this store.
-
409CONFIRMATION_REQUIREDDelete requires confirmation because dependent records will be changed.
-
409CATEGORY_HAS_PRODUCTSCategory has assigned products and cannot be deleted.
-
409CATEGORY_HAS_SUBCATEGORIESCategory has subcategories and cannot be deleted.
Bulk delete categories
Delete multiple categories.
Send store-scoped integer category ids in category_ids. Categories with subcategories or assigned products are not deleted and appear in failed. If deleting the remaining categories will remove collection rules, discount references, or menu items, the API returns CONFIRMATION_REQUIRED; retry the same ids with confirmed: true and its confirmation_token. The response lists successful ids in deleted. All database changes for those ids commit together.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
category_ids
required
|
array<integer> |
Store-scoped integer category ids to delete. |
confirmed
|
boolean |
On a confirmation retry, set this to true and send the returned confirmation_token. Omit it on the first request. |
confirmation_token
|
string |
Token from the CONFIRMATION_REQUIRED response. Omit it on the first request and resend the exact same id selection when using it. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400CATEGORY_BULK_NO_IDSNo category_ids were provided.
-
409CATEGORY_BULK_RACEDA category changed during deletion; retry from fresh data.
-
400CATEGORY_CONFIRMATION_INVALIDConfirmation token is missing, expired, or mismatched.
-
400CATEGORY_BULK_DELETE_TOO_MANYBatch exceeds the Category bulk delete cap.
-
404CATEGORY_NOT_FOUNDCategory does not exist in this store.
-
409CONFIRMATION_REQUIREDDelete requires confirmation because dependent records will be changed.
-
409CATEGORY_HAS_PRODUCTSCategory has assigned products and cannot be deleted.
-
409CATEGORY_HAS_SUBCATEGORIESCategory has subcategories and cannot be deleted.
Fields#
Field |
Type |
Create |
Update |
Required |
Translatable |
|---|---|---|---|---|---|
|
id |
No |
No |
No |
|
|
text |
No |
No |
No |
|
|
text |
Yes |
Yes |
create |
Yes |
|
slug |
Yes |
Yes |
Yes |
|
|
integer |
Yes |
Yes |
No |
|
|
textarea |
Yes |
Yes |
Yes |
|
|
text |
Yes |
Yes |
Yes |
|
|
textarea |
Yes |
Yes |
Yes |
|
|
image |
Yes |
Yes |
No |
|
|
text |
No |
No |
No |
|
|
text |
No |
No |
No |
|
|
template |
Yes |
Yes |
No |
|
|
boolean |
No |
Yes |
No |
|
|
text |
No |
No |
No |
|
|
boolean |
No |
No |
No |
|
|
integer |
No |
No |
No |
|
|
datetime |
No |
No |
No |
|
|
datetime |
No |
No |
No |
|
|
url |
No |
No |
No |
No |
|
string |
No |
No |
No |
No |
Webhook events#
Subscribe to these events to keep your integration in sync with categories. Each event shows the required Store API scope and store permission, the available payload fields, and an example payload. Subscription setup is validated against those permissions; delivery is always restricted to the subscription's store.
Metafield events are filtered for every subscriber. An app receives events for definitions it owns. With the event's required scope, it also receives merchant-owned definitions and definitions shared by another app through app_access: shared; another app's private definitions are not delivered. A store-level webhook endpoint receives merchant-owned definitions and app-owned definitions unless merchant_access is hidden. If an event cannot identify the definition owner or its access settings, Tringify does not deliver it.
Category created
Fired when a product category is created.
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.parent_id |
integer |
Selectable in the Payload builder |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
category.description |
string |
Selectable in the Payload builder |
category.seo_title |
string |
Selectable in the Payload builder |
category.seo_description |
string |
Selectable in the Payload builder |
category.image_id |
string |
Selectable in the Payload builder |
category.image_url |
string |
Selectable in the Payload builder |
category.image_cdn_url |
string |
Selectable in the Payload builder |
category.product_count |
integer |
Selectable in the Payload builder |
category.template_handle |
string |
Selectable in the Payload builder |
category.parent_name |
string |
Selectable in the Payload builder |
category.has_children |
boolean |
Selectable in the Payload builder |
category.created_at |
string |
Selectable in the Payload builder |
category.updated_at |
string |
Selectable in the Payload builder |
Category updated
Fired when a product category is updated.
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.parent_id |
integer |
Selectable in the Payload builder |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
category.description |
string |
Selectable in the Payload builder |
category.seo_title |
string |
Selectable in the Payload builder |
category.seo_description |
string |
Selectable in the Payload builder |
category.image_id |
string |
Selectable in the Payload builder |
category.image_url |
string |
Selectable in the Payload builder |
category.image_cdn_url |
string |
Selectable in the Payload builder |
category.product_count |
integer |
Selectable in the Payload builder |
category.template_handle |
string |
Selectable in the Payload builder |
category.parent_name |
string |
Selectable in the Payload builder |
category.has_children |
boolean |
Selectable in the Payload builder |
category.created_at |
string |
Selectable in the Payload builder |
category.updated_at |
string |
Selectable in the Payload builder |
changed_fields |
array |
Always present |
Category deleted
Fired when a product category is deleted.
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
Category metafield value created
Fired when a category metafield value is created.
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
metafield.definition.id |
string |
Selectable in the Payload builder |
metafield.definition.owner_type |
string |
Selectable in the Payload builder |
metafield.definition.namespace |
string |
Selectable in the Payload builder |
metafield.definition.key |
string |
Selectable in the Payload builder |
metafield.definition.name |
string |
Selectable in the Payload builder |
metafield.definition.description |
string |
Selectable in the Payload builder |
metafield.definition.type |
string |
Selectable in the Payload builder |
metafield.definition.is_translatable |
boolean |
Selectable in the Payload builder |
metafield.definition.max_value_length |
integer |
Selectable in the Payload builder |
metafield.definition.max_list_items |
integer |
Selectable in the Payload builder |
metafield.definition.sort_order |
integer |
Selectable in the Payload builder |
metafield.definition.app_id |
string |
Selectable in the Payload builder |
metafield.definition.app_access |
string |
Selectable in the Payload builder |
metafield.definition.merchant_access |
string |
Selectable in the Payload builder |
metafield.definition.created_at |
string |
Selectable in the Payload builder |
metafield.definition.updated_at |
string |
Selectable in the Payload builder |
metafield.definition.usage_count |
integer |
Selectable in the Payload builder |
metafield.value |
string |
Selectable in the Payload builder |
metafield.display_value |
string |
Selectable in the Payload builder |
metafield.display_value_map |
object |
Selectable in the Payload builder |
metafield.created_at |
string |
Selectable in the Payload builder |
metafield.updated_at |
string |
Selectable in the Payload builder |
Category metafield value updated
Fired when a category metafield value changes.
Possible changed_fields values
The changed_fields array names exactly which of these changed in this event — use it to skip processing updates your integration doesn't care about.
value
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
previous.definition.id |
string |
Selectable in the Payload builder |
previous.definition.owner_type |
string |
Selectable in the Payload builder |
previous.definition.namespace |
string |
Selectable in the Payload builder |
previous.definition.key |
string |
Selectable in the Payload builder |
previous.definition.name |
string |
Selectable in the Payload builder |
previous.definition.description |
string |
Selectable in the Payload builder |
previous.definition.type |
string |
Selectable in the Payload builder |
previous.definition.is_translatable |
boolean |
Selectable in the Payload builder |
previous.definition.max_value_length |
integer |
Selectable in the Payload builder |
previous.definition.max_list_items |
integer |
Selectable in the Payload builder |
previous.definition.sort_order |
integer |
Selectable in the Payload builder |
previous.definition.app_id |
string |
Selectable in the Payload builder |
previous.definition.app_access |
string |
Selectable in the Payload builder |
previous.definition.merchant_access |
string |
Selectable in the Payload builder |
previous.definition.created_at |
string |
Selectable in the Payload builder |
previous.definition.updated_at |
string |
Selectable in the Payload builder |
previous.definition.usage_count |
integer |
Selectable in the Payload builder |
previous.value |
string |
Selectable in the Payload builder |
previous.display_value |
string |
Selectable in the Payload builder |
previous.display_value_map |
object |
Selectable in the Payload builder |
previous.created_at |
string |
Selectable in the Payload builder |
previous.updated_at |
string |
Selectable in the Payload builder |
current.definition.id |
string |
Selectable in the Payload builder |
current.definition.owner_type |
string |
Selectable in the Payload builder |
current.definition.namespace |
string |
Selectable in the Payload builder |
current.definition.key |
string |
Selectable in the Payload builder |
current.definition.name |
string |
Selectable in the Payload builder |
current.definition.description |
string |
Selectable in the Payload builder |
current.definition.type |
string |
Selectable in the Payload builder |
current.definition.is_translatable |
boolean |
Selectable in the Payload builder |
current.definition.max_value_length |
integer |
Selectable in the Payload builder |
current.definition.max_list_items |
integer |
Selectable in the Payload builder |
current.definition.sort_order |
integer |
Selectable in the Payload builder |
current.definition.app_id |
string |
Selectable in the Payload builder |
current.definition.app_access |
string |
Selectable in the Payload builder |
current.definition.merchant_access |
string |
Selectable in the Payload builder |
current.definition.created_at |
string |
Selectable in the Payload builder |
current.definition.updated_at |
string |
Selectable in the Payload builder |
current.definition.usage_count |
integer |
Selectable in the Payload builder |
current.value |
string |
Selectable in the Payload builder |
current.display_value |
string |
Selectable in the Payload builder |
current.display_value_map |
object |
Selectable in the Payload builder |
current.created_at |
string |
Selectable in the Payload builder |
current.updated_at |
string |
Selectable in the Payload builder |
changed_fields |
array |
Selectable in the Payload builder |
Category metafield value deleted
Fired when a category metafield value is deleted.
Payload fields
| Field | Type | Description |
|---|---|---|
category.id |
integer |
Always present |
category.name |
string |
Selectable in the Payload builder |
category.slug |
string |
Selectable in the Payload builder |
metafield.definition.id |
string |
Selectable in the Payload builder |
metafield.definition.owner_type |
string |
Selectable in the Payload builder |
metafield.definition.namespace |
string |
Selectable in the Payload builder |
metafield.definition.key |
string |
Selectable in the Payload builder |
metafield.definition.name |
string |
Selectable in the Payload builder |
metafield.definition.description |
string |
Selectable in the Payload builder |
metafield.definition.type |
string |
Selectable in the Payload builder |
metafield.definition.is_translatable |
boolean |
Selectable in the Payload builder |
metafield.definition.max_value_length |
integer |
Selectable in the Payload builder |
metafield.definition.max_list_items |
integer |
Selectable in the Payload builder |
metafield.definition.sort_order |
integer |
Selectable in the Payload builder |
metafield.definition.app_id |
string |
Selectable in the Payload builder |
metafield.definition.app_access |
string |
Selectable in the Payload builder |
metafield.definition.merchant_access |
string |
Selectable in the Payload builder |
metafield.definition.created_at |
string |
Selectable in the Payload builder |
metafield.definition.updated_at |
string |
Selectable in the Payload builder |
metafield.definition.usage_count |
integer |
Selectable in the Payload builder |
metafield.value |
string |
Selectable in the Payload builder |
metafield.display_value |
string |
Selectable in the Payload builder |
metafield.display_value_map |
object |
Selectable in the Payload builder |
metafield.created_at |
string |
Selectable in the Payload builder |
metafield.updated_at |
string |
Selectable in the Payload builder |