Attributes require product scopes. Reads use read_products; writes use write_products. Attributes are compound resources: the parent owns name, slug, description, sub_type, and sort_order, while options[] owns option labels, values, swatch colors, image file ids, and option sort order. sub_type is one of standard, swatch, or image; swatch options require colors, image options require upload file ids. Referencing a non-empty option file_id also requires read_files. Attribute option translations are their own Store API endpoints because options are separate translatable records.
Endpoints#
Attribute limits
Fetch Attribute limits, option limits, and list constraints.
Returns parent field limits, option field limits, allowed sub types, reorder caps, list caps, and sort options for Product Attribute endpoints.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
List attributes
List product attributes for the store.
Returns paginated product attributes with their nested options. Use sub_type to filter to standard, swatch, or image attributes; use in_use to filter attributes currently used by variants.
Query parameters
| Name | Type | Description |
|---|---|---|
page
|
integer |
Page number. |
limit
|
integer |
Page size. |
search
|
string |
Search attributes by name or slug. |
sub_type
|
string |
Filter by sub type: standard, swatch, or image. |
in_use
|
boolean |
Filter by whether the attribute is used by variants. |
sort_by
|
string |
Sort field from the Attribute list contract.
Allowed values
namecreated_atupdated_at |
sort_direction
|
string |
Sort direction from the Attribute list contract.
Allowed values
ascdesc |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Search attributes
Search attributes for picker-style suggestions.
Returns lightweight attribute suggestions by query. This endpoint is intended for pickers and simple selection UIs.
Query parameters
| Name | Type | Description |
|---|---|---|
q
|
string |
Search query. |
limit
|
integer |
Suggestion count. |
offset
|
integer |
Result offset. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Get an attribute
Fetch one attribute by id.
Returns the attribute and its nested options if it belongs to the token's store.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Attribute id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400STORE_API_INVALID_ATTRIBUTE_IDAttribute id must be an integer.
-
404ATTRIBUTE_NOT_FOUNDAttribute does not exist in this store.
Create an attribute
Create an attribute with options.
Creates a product attribute. name, sub_type, and at least one option are required. slug is optional on create and is generated from the name when omitted. sub_type controls option shape: standard uses labels/values, swatch options require color, and image options require file_id. Non-empty option file_id values must point to upload files in the same store and require read_files in addition to write_products.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
name
required
|
string |
Attribute name. |
slug
|
string |
Optional slug. Omit to generate from name. |
description
|
string |
Optional plain-text description. |
sub_type
required
|
string |
One of |
sort_order
|
integer |
Store-wide display order. |
options
required
|
array<object> |
Attribute options. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON or does not match the expected shape.
-
400ATTRIBUTE_NAME_REQUIREDName is empty after normalization.
-
400ATTRIBUTE_NAME_TOO_LONGName exceeds the Attribute contract max length.
-
400ATTRIBUTE_SLUG_INVALID_FORMATSlug is not valid for Attribute URLs.
-
400ATTRIBUTE_SUB_TYPE_INVALIDSub type is not standard, swatch, or image.
-
400ATTRIBUTE_SUB_TYPE_IMMUTABLESub type cannot be changed after creation.
-
400ATTRIBUTE_OPTIONS_REQUIREDAt least one option is required.
-
400ATTRIBUTE_OPTIONS_TOO_MANYOption count exceeds the contract max per attribute.
-
400ATTRIBUTE_OPTION_LABEL_TOO_LONGOption label exceeds the contract max length.
-
400ATTRIBUTE_OPTION_VALUE_INVALID_FORMATOption value is not a valid filter identifier.
-
400ATTRIBUTE_OPTION_COLOR_REQUIREDSwatch options require a color.
-
400ATTRIBUTE_OPTION_COLOR_INVALID_FORMATOption color must be #RRGGBB.
-
400ATTRIBUTE_OPTION_IMAGE_REQUIREDImage options require a file_id.
-
400ATTRIBUTE_LIMIT_REACHEDStore attribute cap has been reached.
-
403STORE_ADMIN_TOKEN_RUNTIME_FORBIDDENA non-empty option file_id requires read_files scope in addition to write_products.
-
404ATTRIBUTE_NOT_FOUNDAttribute does not exist in this store.
-
409ATTRIBUTE_DUPLICATEName or slug already exists in this store.
-
409ATTRIBUTE_OPTIONS_IN_USEAn option removed by the update is still used by variants.
Update an attribute
Update an attribute and replace its option set.
Updates provided parent fields and replaces the option array. Omitted parent fields are left unchanged, but options is a full-array replacement when sent by Store Admin clients. sub_type is immutable after create and must match the existing value when included. Existing options keep their id; id: 0 creates a new option. Removing an option used by variants is blocked. Non-empty option file_id values require read_files in addition to write_products.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Attribute id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
name
|
string |
Attribute name. |
slug
|
string |
Optional slug. Omit to generate from name. |
description
|
string |
Optional plain-text description. |
sub_type
required
|
string |
|
sort_order
|
integer |
Store-wide display order. |
options
required
|
array<object> |
Full replacement option array. Existing options include their id; new options use |
Errors
-
400STORE_API_INVALID_ATTRIBUTE_IDAttribute id must be an integer.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON or does not match the expected shape.
-
400ATTRIBUTE_NAME_REQUIREDName is empty after normalization.
-
400ATTRIBUTE_NAME_TOO_LONGName exceeds the Attribute contract max length.
-
400ATTRIBUTE_SLUG_INVALID_FORMATSlug is not valid for Attribute URLs.
-
400ATTRIBUTE_SUB_TYPE_INVALIDSub type is not standard, swatch, or image.
-
400ATTRIBUTE_SUB_TYPE_IMMUTABLESub type cannot be changed after creation.
-
400ATTRIBUTE_OPTIONS_REQUIREDAt least one option is required.
-
400ATTRIBUTE_OPTIONS_TOO_MANYOption count exceeds the contract max per attribute.
-
400ATTRIBUTE_OPTION_LABEL_TOO_LONGOption label exceeds the contract max length.
-
400ATTRIBUTE_OPTION_VALUE_INVALID_FORMATOption value is not a valid filter identifier.
-
400ATTRIBUTE_OPTION_COLOR_REQUIREDSwatch options require a color.
-
400ATTRIBUTE_OPTION_COLOR_INVALID_FORMATOption color must be #RRGGBB.
-
400ATTRIBUTE_OPTION_IMAGE_REQUIREDImage options require a file_id.
-
400ATTRIBUTE_LIMIT_REACHEDStore attribute cap has been reached.
-
403STORE_ADMIN_TOKEN_RUNTIME_FORBIDDENA non-empty option file_id requires read_files scope in addition to write_products.
-
404ATTRIBUTE_NOT_FOUNDAttribute does not exist in this store.
-
409ATTRIBUTE_DUPLICATEName or slug already exists in this store.
-
409ATTRIBUTE_OPTIONS_IN_USEAn option removed by the update is still used by variants.
Delete an attribute
Delete an attribute.
Deletes an attribute only when it is not used by product variants. Variant usage is a hard block; there is no confirmation-and-clear flow because clearing variant attribute data would corrupt variant identity. When deletion is allowed, its options and the translations for both the attribute and those options are deleted in the same transaction. The attribute delete webhook includes the removed option summaries.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Attribute id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400STORE_API_INVALID_ATTRIBUTE_IDAttribute id must be an integer.
-
404ATTRIBUTE_NOT_FOUNDAttribute does not exist in this store.
-
409ATTRIBUTE_IN_USEAttribute is used by variants and cannot be deleted.
Bulk delete attributes
Delete multiple attributes.
Send store-scoped integer attribute ids in attribute_ids. Attributes that are missing, concurrently changed, or used by variants appear in failed; the others appear in deleted. Deleting an attribute also deletes its options and both levels of translations in the same transaction. The envelope succeeds when the batch itself is valid, even when individual ids fail.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
attribute_ids
required
|
array<integer> |
Store-scoped integer attribute ids to delete. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON or does not match the expected shape.
-
400ATTRIBUTE_BULK_NO_IDSNo attribute ids were provided.
-
400ATTRIBUTE_BULK_DELETE_TOO_MANYBatch exceeds the Attribute bulk delete cap.
-
409ATTRIBUTE_BULK_RACEDAn attribute became in-use during deletion and was returned in
failed.
Reorder attributes
Set the order of selected attributes.
Assigns consecutive sort positions, starting at zero, to the supplied attribute ids. Omitted attributes keep their current sort order. Every supplied id must belong to the store and the list cannot contain duplicates.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
attribute_ids
required
|
array<integer> |
Attribute ids in display order. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON or does not match the expected shape.
-
400ATTRIBUTE_REORDER_IDS_REQUIREDAt least one attribute id is required.
-
400ATTRIBUTE_REORDER_DUPLICATE_IDThe reorder list contains duplicate attribute ids.
-
400ATTRIBUTE_REORDER_UNKNOWN_IDSOne or more attribute ids do not belong to this store.
Reorder attribute options
Set the order of selected options within one attribute.
Assigns consecutive sort positions, starting at zero, to the supplied option ids. Omitted options keep their current sort order. Every supplied id must belong to the attribute and the list cannot contain duplicates.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
integer |
Attribute id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
option_ids
required
|
array<integer> |
Option ids in display order. |
Errors
-
400STORE_API_INVALID_ATTRIBUTE_IDAttribute id must be an integer.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON or does not match the expected shape.
-
400ATTRIBUTE_OPTION_REORDER_IDS_REQUIREDAt least one option id is required.
-
400ATTRIBUTE_OPTION_REORDER_DUPLICATE_IDThe reorder list contains duplicate option ids.
-
400ATTRIBUTE_OPTION_REORDER_UNKNOWN_IDSOne or more option ids do not belong to this attribute.
-
404ATTRIBUTE_NOT_FOUNDAttribute does not exist in this store.
Fields#
Field |
Kind |
Create |
Update |
Required |
Translatable |
|---|---|---|---|---|---|
|
text |
Yes |
Yes |
create |
Yes |
|
slug |
Yes |
Yes |
Yes |
|
|
textarea |
Yes |
Yes |
Yes |
|
|
select |
Yes |
Yes |
create, update |
No |
|
integer |
Yes |
Yes |
No |
|
|
attribute_options |
Yes |
Yes |
create, update |
No |
|
integer |
No |
No |
No |
|
|
boolean |
No |
No |
No |
|
|
datetime |
No |
No |
No |
|
|
datetime |
No |
No |
No |
Admin CSV shape#
CSV import, update, and export are Store Admin bulk-job features, not Store API JSON endpoints. They are shown here because the same Attribute registry contract owns the field shape and permissions. Attributes use one row per option: the parent attribute columns identify the attribute, while the option columns describe the nested option on that row.
Mode |
Columns |
Required columns |
|---|---|---|
Import |
|
|
Update |
|
|
Export |
|
Create import example#
| Name | Slug | Sub Type | Description | Sort Order | Option Label | Option Value | Option Color | Option Image URL | Option Sort |
|---|---|---|---|---|---|---|---|---|---|
| Acme | acme | swatch | Acme makes durable outdoor gear. | 10 | Red | red | #ef4444 | https://cdn.example.com/red.png | 10 |
Update options example#
| ID | Name | Slug | Sub Type | Description | Sort Order | Option ID | Option Label | Option Value | Option Color | Option Image URL | Option Sort |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | Acme | acme | swatch | Acme makes durable outdoor gear. | 10 | 41 | Red | red | #ef4444 | https://cdn.example.com/red.png | 10 |
Webhook events#
Attribute webhook events are declared by the Attribute resource contract. The event cards below include the topic, subscription scope, store permission, payload schema, and sample payload.
Attribute created
Fired when a product attribute is created.
Payload fields
| Field | Type | Description |
|---|---|---|
attribute.id |
integer |
Always present |
attribute.store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.name |
string |
Can be removed/added via the Payload builder |
attribute.slug |
string |
Can be removed/added via the Payload builder |
attribute.description |
string |
Can be removed/added via the Payload builder |
attribute.sub_type |
string |
Can be removed/added via the Payload builder |
attribute.sort_order |
integer |
Can be removed/added via the Payload builder |
attribute.in_use |
boolean |
Can be removed/added via the Payload builder |
attribute.variant_usage_count |
integer |
Can be removed/added via the Payload builder |
attribute.created_at |
string |
Can be removed/added via the Payload builder |
attribute.updated_at |
string |
Can be removed/added via the Payload builder |
attribute.options[*].id |
integer |
Always present |
attribute.options[*].store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].attribute_id |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].label |
string |
Can be removed/added via the Payload builder |
attribute.options[*].value |
string |
Can be removed/added via the Payload builder |
attribute.options[*].color |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_id |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_url |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_cdn_url |
string |
Can be removed/added via the Payload builder |
attribute.options[*].sort_order |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].created_at |
string |
Can be removed/added via the Payload builder |
Attribute updated
Fired when a product attribute is updated.
Payload fields
| Field | Type | Description |
|---|---|---|
attribute.id |
integer |
Always present |
attribute.store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.name |
string |
Can be removed/added via the Payload builder |
attribute.slug |
string |
Can be removed/added via the Payload builder |
attribute.description |
string |
Can be removed/added via the Payload builder |
attribute.sub_type |
string |
Can be removed/added via the Payload builder |
attribute.sort_order |
integer |
Can be removed/added via the Payload builder |
attribute.in_use |
boolean |
Can be removed/added via the Payload builder |
attribute.variant_usage_count |
integer |
Can be removed/added via the Payload builder |
attribute.created_at |
string |
Can be removed/added via the Payload builder |
attribute.updated_at |
string |
Can be removed/added via the Payload builder |
attribute.options[*].id |
integer |
Always present |
attribute.options[*].store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].attribute_id |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].label |
string |
Can be removed/added via the Payload builder |
attribute.options[*].value |
string |
Can be removed/added via the Payload builder |
attribute.options[*].color |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_id |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_url |
string |
Can be removed/added via the Payload builder |
attribute.options[*].file_cdn_url |
string |
Can be removed/added via the Payload builder |
attribute.options[*].sort_order |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].created_at |
string |
Can be removed/added via the Payload builder |
Attribute deleted
Fired when a product attribute is deleted. Payload carries the attribute plus the options that cascaded with it.
Payload fields
| Field | Type | Description |
|---|---|---|
attribute.id |
integer |
Always present |
attribute.store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.name |
string |
Can be removed/added via the Payload builder |
attribute.slug |
string |
Can be removed/added via the Payload builder |
attribute.sub_type |
string |
Can be removed/added via the Payload builder |
attribute.options[*].id |
integer |
Always present |
attribute.options[*].store_seq_id |
integer |
Can be removed/added via the Payload builder |
attribute.options[*].label |
string |
Can be removed/added via the Payload builder |
attribute.options[*].value |
string |
Can be removed/added via the Payload builder |
Attributes reordered
Fired when the sort order of attributes is changed. Payload carries the ordered id list.
Payload fields
| Field | Type | Description |
|---|---|---|
attribute_ids |
array |
Always present |
Attribute option created
Fired when a new option is added to an attribute.
Payload fields
| Field | Type | Description |
|---|---|---|
option.id |
integer |
Always present |
option.store_seq_id |
integer |
Can be removed/added via the Payload builder |
option.attribute_id |
integer |
Can be removed/added via the Payload builder |
option.label |
string |
Can be removed/added via the Payload builder |
option.value |
string |
Can be removed/added via the Payload builder |
option.color |
string |
Can be removed/added via the Payload builder |
option.file_id |
string |
Can be removed/added via the Payload builder |
option.file_url |
string |
Can be removed/added via the Payload builder |
option.file_cdn_url |
string |
Can be removed/added via the Payload builder |
option.sort_order |
integer |
Can be removed/added via the Payload builder |
option.created_at |
string |
Can be removed/added via the Payload builder |
Attribute option updated
Fired when an existing attribute option is updated.
Payload fields
| Field | Type | Description |
|---|---|---|
option.id |
integer |
Always present |
option.store_seq_id |
integer |
Can be removed/added via the Payload builder |
option.attribute_id |
integer |
Can be removed/added via the Payload builder |
option.label |
string |
Can be removed/added via the Payload builder |
option.value |
string |
Can be removed/added via the Payload builder |
option.color |
string |
Can be removed/added via the Payload builder |
option.file_id |
string |
Can be removed/added via the Payload builder |
option.file_url |
string |
Can be removed/added via the Payload builder |
option.file_cdn_url |
string |
Can be removed/added via the Payload builder |
option.sort_order |
integer |
Can be removed/added via the Payload builder |
option.created_at |
string |
Can be removed/added via the Payload builder |
Attribute option deleted
Fired when an attribute option is removed.
Payload fields
| Field | Type | Description |
|---|---|---|
option.id |
integer |
Always present |
option.store_seq_id |
integer |
Can be removed/added via the Payload builder |
option.label |
string |
Can be removed/added via the Payload builder |
option.value |
string |
Can be removed/added via the Payload builder |
Attribute options reordered
Fired when the sort order of options within an attribute changes. Payload carries the attribute_id plus the ordered option_id list.
Payload fields
| Field | Type | Description |
|---|---|---|
attribute_id |
integer |
Always present |
option_ids |
array |
Always present |