Categories

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, a supplied slug must be non-empty and valid. 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

GET read_products

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.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

List categories

GET read_products

List categories for the store.

Returns paginated categories. Use tree=true for hierarchical roots with children. Pagination, sorting, tree limits, and search validation are enforced by the product service.

Query parameters

Name Type Description
page integer

Page number. Defaults to 1.

Example: 1
limit integer

Page size. Defaults to 50. Maximum 200.

Example: 20
tree boolean

When true and no search or filters are active, return paginated root categories with nested children. Search or filter parameters return the flat paginated list. Accepted values: true, false.

Example: false
search string

Search categories by name or slug. Maximum 200 characters.

Example: apparel
parent_id string

null for root categories, or a positive parent category id.

Example: null
ancestor_id integer

Filter to descendants of this ancestor category id. Must be a positive integer.

Example: 12
has_children boolean

Filter categories by whether they have subcategories. Accepted values: true, false.

Example: true
has_images boolean

Filter categories by whether they have an image. Accepted values: true, false.

Example: true
sort_by string

Sort field. Allowed values: name, product_count, created_at, updated_at.

Allowed values
nameproduct_countcreated_atupdated_at
Example: name
sort_direction string

Sort direction. Allowed values: asc, desc.

Allowed values
ascdesc
Example: asc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 CATEGORY_LIST_INVALID_PAGE

    page must be at least 1.

  • 400 CATEGORY_LIST_INVALID_LIMIT

    limit must be within the documented list range.

  • 400 CATEGORY_SEARCH_TOO_LONG

    search exceeds the configured maximum length.

  • 400 CATEGORY_LIST_INVALID_SORT_BY

    sort_by is not one of the documented fields.

  • 400 CATEGORY_LIST_INVALID_SORT_DIRECTION

    sort_direction is not asc or desc.

  • 400 CATEGORY_LIST_INVALID_PARENT_ID

    parent_id is neither null nor a positive integer.

  • 400 CATEGORY_LIST_INVALID_ANCESTOR_ID

    ancestor_id is not a positive integer.

  • 400 CATEGORY_LIST_INVALID_BOOLEAN

    A boolean list filter is not true or false.

Search categories

GET read_products

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.

Example: apparel
limit integer

Suggestion count. Defaults to 10. Maximum 50.

Example: 10

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 CATEGORY_LIST_INVALID_LIMIT

    limit must be within the documented suggestion range.

  • 400 CATEGORY_SEARCH_TOO_LONG

    q exceeds the configured maximum length.

Get a category

GET read_products

Fetch one category by id.

Returns the category if it belongs to the token's store.

Path parameters

Name Type Description
id required integer

Category id.

Example: 7

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 STORE_API_INVALID_CATEGORY_ID

    id is not an integer.

  • 404 CATEGORY_NOT_FOUND

    Category does not exist in this store.

Create a category

POST write_products

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.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
name required string

Category name.

Example: Apparel
slug string

Optional slug. Omit to generate from name.

Example: apparel
parent_id integer

Optional parent category id. Omit or send 0 for a root category.

Example: 12
description string

Optional plain-text description.

Example: Clothing and fashion.
seo_title string

Optional SEO title.

Example: Shop Apparel
seo_description string

Optional SEO description.

Example: Browse clothing, shoes, and accessories.
image_id string

Optional upload image file id. Non-empty values require read_files access to the referenced file.

Example: f_8f2a1c2b9d4e
template_handle string

Template assignment. On create, omitting this field or sending an empty string assigns default_category. Use default_category for the default Category template, or pass an alternate Category template handle configured for the store. On update, omit template_handle to leave the assignment unchanged, use default_category to reset it to default, and do not send an empty string.

Example: default_category

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is not valid JSON.

  • 400 STORE_API_CREATE_REDIRECT_UNSUPPORTED

    create_redirect is only supported on update.

  • 400 CATEGORY_NAME_REQUIRED

    Name is empty after normalization.

  • 400 CATEGORY_NAME_INVALID_CHARS

    Name contains forbidden control characters.

  • 400 CATEGORY_NAME_TOO_LONG

    Name exceeds the Category contract max length.

  • 400 CATEGORY_SLUG_INVALID_FORMAT

    Slug is not valid for Category URLs.

  • 400 CATEGORY_SLUG_TOO_LONG

    Slug exceeds the Category contract max length.

  • 400 CATEGORY_SLUG_GENERATION_FAILED

    A slug could not be generated from the supplied name.

  • 400 CATEGORY_UNIQUE_SLUG_GENERATION_FAILED

    A unique generated slug could not be allocated.

  • 400 CATEGORY_DESCRIPTION_INVALID_CHARS

    Description contains forbidden control characters.

  • 400 CATEGORY_DESCRIPTION_TOO_LONG

    Description exceeds the Category contract max length.

  • 400 CATEGORY_SEO_TITLE_INVALID_CHARS

    SEO title contains forbidden control characters.

  • 400 CATEGORY_SEO_TITLE_TOO_LONG

    SEO title exceeds the Category contract max length.

  • 400 CATEGORY_SEO_DESCRIPTION_INVALID_CHARS

    SEO description contains forbidden control characters.

  • 400 CATEGORY_SEO_DESCRIPTION_TOO_LONG

    SEO description exceeds the Category contract max length.

  • 400 CATEGORY_DEPTH_EXCEEDED

    Parent assignment would exceed the category hierarchy depth limit.

  • 400 CATEGORY_CANNOT_BE_OWN_PARENT

    A category cannot be its own parent.

  • 400 CATEGORY_CANNOT_BE_DESCENDANT_PARENT

    Parent assignment would create a cycle.

  • 400 CATEGORY_PARENT_NOT_FOUND

    Parent category does not exist in this store.

  • 400 CATEGORY_LIMIT_REACHED

    Store category cap has been reached.

  • 400 TEMPLATE_HANDLE_INVALID

    Template handle is not valid for Category templates.

  • 400 TEMPLATE_HANDLE_NOT_FOUND

    Template handle does not exist on the store's primary active theme for Category.

  • 400 INVALID_INPUT

    image_id is malformed, is not an image, or is not a merchant upload.

  • 403 STORE_ADMIN_TOKEN_RUNTIME_FORBIDDEN

    A non-empty image_id requires read_files scope in addition to write_products.

  • 404 NOT_FOUND

    image_id does not reference a file in this store.

  • 404 CATEGORY_NOT_FOUND

    Category does not exist in this store.

  • 409 CATEGORY_DUPLICATE

    Name already exists under the same parent, or slug already exists in this store.

  • 409 TRANSLATION_SOURCE_FIELD_HAS_TRANSLATIONS

    A source field cannot be cleared while translations still exist.

Bulk create categories

POST write_products

Create multiple categories by name.

Creates multiple root categories from names. Slugs are generated server-side; existing names are skipped and reported in the response.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
names required array<string>

Category names to create.

Example: Apparel

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is not valid JSON.

  • 400 CATEGORY_BULK_NO_NAMES

    No names were provided.

  • 400 CATEGORY_LIMIT_REACHED

    Batch would exceed the Category store cap.

  • 400 CATEGORY_NAME_INVALID_CHARS

    One name contains forbidden control characters.

  • 400 CATEGORY_NAME_TOO_LONG

    One name exceeds the Category contract max length.

  • 400 CATEGORY_SLUG_GENERATION_FAILED

    A slug could not be generated from one name.

  • 400 CATEGORY_UNIQUE_SLUG_GENERATION_FAILED

    A unique generated slug could not be allocated.

  • 409 CATEGORY_BULK_DUPLICATE

    One of the names in the batch was just created by another request.

Update a category

PUT write_products

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.

Path parameters

Name Type Description
id required integer

Category id.

Example: 7

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
name string

Category name.

Example: Apparel
slug string

Optional slug. Omit to generate from name.

Example: apparel
parent_id integer

Optional parent category id. Omit or send 0 for a root category.

Example: 12
description string

Optional plain-text description.

Example: Clothing and fashion.
seo_title string

Optional SEO title.

Example: Shop Apparel
seo_description string

Optional SEO description.

Example: Browse clothing, shoes, and accessories.
image_id string

Optional upload image file id. Non-empty values require read_files access to the referenced file.

Example: f_8f2a1c2b9d4e
template_handle string

Template assignment. On create, omitting this field or sending an empty string assigns default_category. Use default_category for the default Category template, or pass an alternate Category template handle configured for the store. On update, omit template_handle to leave the assignment unchanged, use default_category to reset it to default, and do not send an empty string.

Example: default_category
create_redirect boolean

When slug changes, create a redirect from the previous slug.

Example: true

Errors

  • 400 STORE_API_INVALID_CATEGORY_ID

    id is not an integer.

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is not valid JSON.

  • 400 CATEGORY_NAME_REQUIRED

    Name is empty after normalization.

  • 400 CATEGORY_NAME_INVALID_CHARS

    Name contains forbidden control characters.

  • 400 CATEGORY_NAME_TOO_LONG

    Name exceeds the Category contract max length.

  • 400 CATEGORY_SLUG_INVALID_FORMAT

    Slug is not valid for Category URLs.

  • 400 CATEGORY_SLUG_TOO_LONG

    Slug exceeds the Category contract max length.

  • 400 CATEGORY_SLUG_GENERATION_FAILED

    A slug could not be generated from the supplied name.

  • 400 CATEGORY_UNIQUE_SLUG_GENERATION_FAILED

    A unique generated slug could not be allocated.

  • 400 CATEGORY_DESCRIPTION_INVALID_CHARS

    Description contains forbidden control characters.

  • 400 CATEGORY_DESCRIPTION_TOO_LONG

    Description exceeds the Category contract max length.

  • 400 CATEGORY_SEO_TITLE_INVALID_CHARS

    SEO title contains forbidden control characters.

  • 400 CATEGORY_SEO_TITLE_TOO_LONG

    SEO title exceeds the Category contract max length.

  • 400 CATEGORY_SEO_DESCRIPTION_INVALID_CHARS

    SEO description contains forbidden control characters.

  • 400 CATEGORY_SEO_DESCRIPTION_TOO_LONG

    SEO description exceeds the Category contract max length.

  • 400 CATEGORY_DEPTH_EXCEEDED

    Parent assignment would exceed the category hierarchy depth limit.

  • 400 CATEGORY_CANNOT_BE_OWN_PARENT

    A category cannot be its own parent.

  • 400 CATEGORY_CANNOT_BE_DESCENDANT_PARENT

    Parent assignment would create a cycle.

  • 400 CATEGORY_PARENT_NOT_FOUND

    Parent category does not exist in this store.

  • 400 CATEGORY_LIMIT_REACHED

    Store category cap has been reached.

  • 400 TEMPLATE_HANDLE_INVALID

    Template handle is not valid for Category templates.

  • 400 TEMPLATE_HANDLE_NOT_FOUND

    Template handle does not exist on the store's primary active theme for Category.

  • 400 INVALID_INPUT

    image_id is malformed, is not an image, or is not a merchant upload.

  • 403 STORE_ADMIN_TOKEN_RUNTIME_FORBIDDEN

    A non-empty image_id requires read_files scope in addition to write_products.

  • 404 NOT_FOUND

    image_id does not reference a file in this store.

  • 404 CATEGORY_NOT_FOUND

    Category does not exist in this store.

  • 409 CATEGORY_DUPLICATE

    Name already exists under the same parent, or slug already exists in this store.

  • 409 TRANSLATION_SOURCE_FIELD_HAS_TRANSLATIONS

    A source field cannot be cleared while translations still exist.

Delete a category

DELETE write_products

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.

Example: 7

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

  • 400 STORE_API_INVALID_CATEGORY_ID

    id is not an integer.

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is not valid JSON.

  • 400 CATEGORY_CONFIRMATION_INVALID

    Confirmation token is missing, expired, or mismatched.

  • 400 CATEGORY_BULK_DELETE_TOO_MANY

    Batch exceeds the Category bulk delete cap.

  • 404 CATEGORY_NOT_FOUND

    Category does not exist in this store.

  • 409 CONFIRMATION_REQUIRED

    Delete requires confirmation because dependent records will be changed.

  • 409 CATEGORY_HAS_PRODUCTS

    Category has assigned products and cannot be deleted.

  • 409 CATEGORY_HAS_SUBCATEGORIES

    Category has subcategories and cannot be deleted.

Bulk delete categories

POST write_products

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.

Example: [7, 11]
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

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request body is not valid JSON.

  • 400 CATEGORY_BULK_NO_IDS

    No category_ids were provided.

  • 409 CATEGORY_BULK_RACED

    A category changed during deletion; retry from fresh data.

  • 400 CATEGORY_CONFIRMATION_INVALID

    Confirmation token is missing, expired, or mismatched.

  • 400 CATEGORY_BULK_DELETE_TOO_MANY

    Batch exceeds the Category bulk delete cap.

  • 404 CATEGORY_NOT_FOUND

    Category does not exist in this store.

  • 409 CONFIRMATION_REQUIRED

    Delete requires confirmation because dependent records will be changed.

  • 409 CATEGORY_HAS_PRODUCTS

    Category has assigned products and cannot be deleted.

  • 409 CATEGORY_HAS_SUBCATEGORIES

    Category has subcategories and cannot be deleted.

Fields#

Field

Kind

Create

Update

Required

Translatable

name

text

Yes

Yes

create

Yes

slug

slug

Yes

Yes

Yes

parent_id

integer

Yes

Yes

No

description

textarea

Yes

Yes

Yes

seo_title

text

Yes

Yes

Yes

seo_description

textarea

Yes

Yes

Yes

image_id

image

Yes

Yes

No

template_handle

template

Yes

Yes

No

create_redirect

boolean

No

Yes

No

parent_name

text

No

No

No

has_children

boolean

No

No

No

product_count

integer

No

No

No

created_at

datetime

No

No

No

updated_at

datetime

No

No

No

storefront_url

url

No

No

No

No

Webhook events#

Category webhook events are declared by the Category resource contract. The event cards below include the topic, subscription scope, store permission, payload schema, and sample payload.

Category created

EVENT categories/create write_products products:write

Fired when a product category is created.

Payload fields

Field Type Description
category.id integer Always present
category.parent_id integer Can be removed/added via the Payload builder
category.name string Can be removed/added via the Payload builder
category.slug string Can be removed/added via the Payload builder
category.description string Can be removed/added via the Payload builder
category.seo_title string Can be removed/added via the Payload builder
category.seo_description string Can be removed/added via the Payload builder
category.image_id string Can be removed/added via the Payload builder
category.image_url string Can be removed/added via the Payload builder
category.image_cdn_url string Can be removed/added via the Payload builder
category.product_count integer Can be removed/added via the Payload builder
category.template_handle string Can be removed/added via the Payload builder
category.parent_name string Can be removed/added via the Payload builder
category.has_children boolean Can be removed/added via the Payload builder
category.created_at string Can be removed/added via the Payload builder
category.updated_at string Can be removed/added via the Payload builder

Category updated

EVENT categories/update write_products products:write

Fired when a product category is updated.

Payload fields

Field Type Description
category.id integer Always present
category.parent_id integer Can be removed/added via the Payload builder
category.name string Can be removed/added via the Payload builder
category.slug string Can be removed/added via the Payload builder
category.description string Can be removed/added via the Payload builder
category.seo_title string Can be removed/added via the Payload builder
category.seo_description string Can be removed/added via the Payload builder
category.image_id string Can be removed/added via the Payload builder
category.image_url string Can be removed/added via the Payload builder
category.image_cdn_url string Can be removed/added via the Payload builder
category.product_count integer Can be removed/added via the Payload builder
category.template_handle string Can be removed/added via the Payload builder
category.parent_name string Can be removed/added via the Payload builder
category.has_children boolean Can be removed/added via the Payload builder
category.created_at string Can be removed/added via the Payload builder
category.updated_at string Can be removed/added via the Payload builder

Category deleted

EVENT categories/delete write_products products:write

Fired when a product category is deleted.

Payload fields

Field Type Description
category.id integer Always present
category.name string Can be removed/added via the Payload builder
category.slug string Can be removed/added via the Payload builder