Attribute API
Overview
The Attribute API provides endpoints for managing product attributes in your EverShop store. Product attributes define specific characteristics of products, such as color, size, material, or any custom properties you need for your catalog.
Endpoints
Create An Attribute
Creates a new product attribute in the system. Attributes can be assigned to attribute groups and may include multiple options depending on the attribute type.
| Field Name | Field Type | Required | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| attribute_name | string | Yes | |||||||||
| attribute_code | string | Yes | |||||||||
| is_required | integer or string (0, 1, '0', '1') | Yes | |||||||||
| display_on_frontend | integer or string (0, 1, '0', '1') | Yes | |||||||||
| sort_order | string or integer | No | |||||||||
| is_filterable | integer or string (0, 1, '0', '1') | No | |||||||||
| groups | array of string,integer | Yes | |||||||||
| options | array of object | No | |||||||||
| |||||||||||
- cURL
- JavaScript
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
--data-raw '<JSON DATA>'
https://<your domain>/api/attributes
fetch('https://<your domain>/api/attributes', {
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer <admin JWT token>'
},
body: <JSON DATA>
})
.then(response => response.json())
.then(data => {
if(data.error) {
// Handle the error
} else {
// Handle the data
}
})
.catch(error => {
// Handle the error
});
{
"data": {
"attribute_id": 99,
"uuid": "98bd0beea63211edb46b60d819134f39",
"attribute_code": "GTW5s9bqJ7rP3gDrU5HF",
"attribute_name": "Text attribute",
"type": "text",
"is_required": 1,
"display_on_frontend": 1,
"sort_order": 1,
"is_filterable": 0,
"links": [
{
"rel": "attributeGrid",
"href": "/admin/attributes",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "edit",
"href": "/admin/attributes/edit/98bd0beea63211edb46b60d819134f39",
"action": "GET",
"types": [
"text/xml"
]
}
]
}
}
Update an Attribute
Modifies an existing product attribute. You can update the attribute name, settings, associated groups, and options.
This is a true partial update — updateProductAttribute empties the schema's required list, so only the fields you send are written.
attribute_code and type cannot be changedBoth keys are deleted from the payload before the write, so sending them has no effect and raises no error. To change either, delete the attribute and create a new one.
| Field Name | Field Type | Required | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| attribute_name | string | No | |||||||||
| attribute_code | string | No | |||||||||
| is_required | integer or string (0, 1, '0', '1') | No | |||||||||
| display_on_frontend | integer or string (0, 1, '0', '1') | No | |||||||||
| sort_order | string or integer | No | |||||||||
| is_filterable | integer or string (0, 1, '0', '1') | No | |||||||||
| groups | array of string,integer | No | |||||||||
| options | array of object | No | |||||||||
| |||||||||||
- cURL
- JavaScript
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
--data-raw '<JSON DATA>'
https://<your domain>/api/attributes/363ba97f-8be7-4be9-be3f-a9f341f2b89f
fetch('https://<your domain>/api/attributes/363ba97f-8be7-4be9-be3f-a9f341f2b89f', {
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer <admin JWT token>'
},
body: <JSON DATA>
})
.then(response => response.json())
.then(data => {
if(data.error) {
// Handle the error
} else {
// Handle the data
}
})
.catch(error => {
// Handle the error
});
{
"data": {
"attribute_id": 99,
"uuid": "363ba97f-8be7-4be9-be3f-a9f341f2b89f",
"attribute_code": "GTW5s9bqJ7rP3gDrU5HF",
"attribute_name": "Text attribute",
"type": "text",
"is_required": 1,
"display_on_frontend": 1,
"sort_order": 1,
"is_filterable": 0,
"links": [
{
"rel": "attributeGrid",
"href": "/admin/attributes",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "edit",
"href": "/admin/attributes/edit/363ba97f-8be7-4be9-be3f-a9f341f2b89f",
"action": "GET",
"types": [
"text/xml"
]
}
]
}
}
Delete an Attribute
Permanently removes a product attribute from the system. Note that this will also remove all associations of this attribute with products.
- cURL
- JavaScript
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
https://<your domain>/api/attributes/363ba97f-8be7-4be9-be3f-a9f341f2b89f
fetch('https://<your domain>/api/attributes/363ba97f-8be7-4be9-be3f-a9f341f2b89f', {
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer <admin JWT token>'
}
})
.then(response => response.json())
.then(data => {
if(data.error) {
// Handle the error
} else {
// Handle the data
}
})
.catch(error => {
// Handle the error
});
{
"data": {
"attribute_id": 99,
"uuid": "363ba97f-8be7-4be9-be3f-a9f341f2b89f",
"attribute_code": "GTW5s9bqJ7rP3gDrU5HF",
"attribute_name": "Text attribute Updated",
"type": "text",
"is_required": 1,
"display_on_frontend": 1,
"sort_order": 1,
"is_filterable": 0
}
}
Reading Attributes
GET /api/attributes and GET /api/attributes/{uuid} do not exist. The catalog module registers no GET route for attributes — calling either returns a 404.
Read attribute data through GraphQL.
A single attribute is available on both schemas via Query.attribute(id: Int):
query Attribute($id: Int) {
attribute(id: $id) {
attributeId
uuid
attributeCode
attributeName
type
isRequired
displayOnFrontend
sortOrder
isFilterable
options {
attributeOptionId
uuid
optionText
}
}
}
The list query Query.attributes(filters: [FilterInput]) is admin-only — it is defined in an .admin.graphql file and is therefore absent from the storefront schema. Send it to the authenticated endpoint POST /admin/graphql:
query Attributes($filters: [FilterInput]) {
attributes(filters: $filters) {
items {
attributeId
uuid
attributeCode
attributeName
type
isFilterable
}
currentPage
total
}
}
See the GraphQL documentation for filters and the full schema.
Error Handling
All endpoints may return the following error responses:
| Status Code | Description |
|---|---|
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Authentication required |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Attribute doesn't exist |
| 500 | Server Error - Something went wrong |
Error responses follow this format:
{
"error": {
"status": 404,
"message": "Attribute not found"
}
}
Best Practices
- Naming Convention: Use clear, descriptive names for attributes and consistent codes (e.g.,
color,size,material) - Attribute Types: Choose the appropriate attribute type (text, select, multiselect, etc.) based on how the data will be used
- Group Organization: Assign attributes to logical groups to keep your product editing interface organized
- Filterable Attributes: Mark attributes as filterable only when they're useful for customers to filter products by (e.g., color, size, price range)