Attributes
Global attributes, pointwise options, attribute sets and groups of the catalog. The split lets you reuse attributes across sets, organize how they appear in the admin and update a single option without resubmitting all options of an attribute.
Overview
This page covers three blocks of the attribute API: the global attribute (catalog-wide), its pointwise options and the organizational structure of sets and groups. Listing endpoints support deterministic pagination and filtering by frontend_input. Write endpoints follow the standard Yep REST API response pattern.
page, limit and include_pagination.General rules
Conventions shared by the attribute endpoints. Base URL used in the examples: /api2. Protected endpoints require Authorization: Bearer {{token}} and Content-Type: application/json on POST/PATCH/DELETE verbs with a body.
- Listings accept filters via query string or JSON body. When the same field appears in both, the query string value wins.
- Default pagination:
page=1,limit=20, max200. Useinclude_pagination=trueto receivetotal,last_pageandhas_next. - Pointwise option management (
/api2/attribute/option) is only allowed for attributes whosefrontend_inputisselectormultiselectand that do not use a customsource_model. Any other case returns400. - Errors follow the API standard:
{"error": "message"}together with the proper HTTP status.
| Status | Use |
|---|---|
200 | Query, update or removal completed. |
201 | Attribute, option, set or group created. |
400 | Invalid parameter, invalid JSON or operation incompatible with the attribute. |
401 | Missing or invalid token. |
404 | Attribute, option, set or group not found. |
409 | Duplicate or attempt to remove an option in use by products. |
Global attributes — Listing
Queries the attributes registered in the catalog. When an attribute has options, the response includes options with option_id, value, label, sort_order and is_default.
List attributes with pagination and filters.
text, select, multiselect, etc.). Accepts a string or a list.Paginated listing
GET /api2/attribute
Authorization: Bearer {{token}}
Content-Type: application/json
{
"page": 1,
"limit": 20,
"include_pagination": true,
"frontend_input": ["select", "multiselect"],
"store_id": 0
}
Fetch a single attribute by code or by ID.
id.attribute_code.By code
{
"attribute_code": "tipo_material",
"store_id": 0
}
By ID
{
"id": 123,
"store_id": 0
}
Global attributes — Create and update
Attributes reusable across multiple sets. They support different types (text, select, multiselect, etc.) and flags like is_filterable, used_in_product_listing, is_searchable and apply_to. Required fields on creation: attribute_code, frontend_input and frontend_label.
Create a text-type global attribute.
{
"attribute_code": "codigo_fabricante",
"frontend_input": "text",
"frontend_label": "Manufacturer Code",
"is_global": 1,
"is_required": 0,
"is_unique": 0,
"default_value": null,
"position": 0,
"is_searchable": 1,
"is_visible": 1,
"is_visible_on_front": 1,
"is_visible_in_advanced_search": 0,
"is_comparable": 0,
"is_filterable": 0,
"is_filterable_in_search": 0,
"is_used_for_promo_rules": 0,
"used_in_product_listing": 1,
"used_for_sort_by": 0,
"is_html_allowed_on_front": 0,
"is_wysiwyg_enabled": 0,
"apply_to": ["simple", "configurable"]
}
Create a select attribute with an initial list of options. Each option accepts admin (label), position and default.
{
"attribute_code": "tipo_material",
"frontend_input": "select",
"frontend_label": "Material Type",
"is_global": 1,
"is_required": 1,
"is_configurable": 1,
"is_filterable": 1,
"is_searchable": 1,
"used_in_product_listing": 1,
"options": [
{"admin": "Resina", "position": 0, "default": 1},
{"admin": "Cerâmica", "position": 1},
{"admin": "Zircônia", "position": 2}
]
}
Update attribute settings (flags, position, scope). Send only the fields that changed.
{
"attribute_code": "tipo_material",
"is_required": 1,
"is_filterable": 0,
"used_for_sort_by": 1
}
Sync the full list of options of the attribute. Options missing from the payload may be removed. To change a single option in isolation, use the Pointwise options block.
{
"attribute_code": "tipo_material",
"options": [
{"admin": "Resina", "position": 0},
{"admin": "Cerâmica Premium", "position": 1, "default": 1}
]
}
Sync vs. pointwise
This PATCH with options rewrites the attribute's list. To add, edit or remove a single option without affecting the others (and without cascade-removal risk), prefer the /api2/attribute/option endpoints.
Delete a global attribute.
{
"attribute_code": "tipo_material"
}
Pointwise options New in 2026
Manage one option at a time without resubmitting the attribute's full list. Available only for select/multiselect attributes without a custom source_model. In every other case it returns 400.
Add an option to the attribute. Returns 409 if an option with the same label (case-sensitive) already exists on the attribute.
true/1.Request
{
"attribute_code": "tipo_material",
"admin": "Zircônia",
"position": 2,
"default": false
}
Response
{
"success": true,
"option": {
"option_id": 12345,
"value": "12345",
"label": "Zircônia",
"sort_order": 2,
"is_default": false
}
}
Update label, position or default flag of an option. The option_id must belong to the given attribute.
option.option_id in the attribute lookup).{
"attribute_code": "tipo_material",
"option_id": 12345,
"admin": "Zircônia Premium",
"position": 3,
"default": true
}
Remove an option. Blocks the removal if the option is in use by products — in that case it returns 409 and the products remain unchanged.
{
"attribute_code": "tipo_material",
"option_id": 12345
}
Response
{
"success": true,
"message": "Option removed successfully."
}
Attribute Sets
Sets group attributes that apply to a product type. Creation always starts from an existing skeleton — all groups and attributes from the skeleton are cloned into the new set.
Create a new Attribute Set from a skeleton.
{
"attribute_set_name": "Equipamentos Odontológicos",
"skeleton_set_id": 4
}
Remove an Attribute Set. Use force_products_remove carefully — when true, linked products are removed alongside.
true, also removes the products in the set. Default: false (returns 409 if there are linked products).{
"attribute_set_name": "Equipamentos Odontológicos",
"force_products_remove": true
}
Attribute Groups
Groups organize attributes within a set for admin display (tabs on the product form). Each group is identified by the pair attribute_set_id + group_name.
Create a group within an Attribute Set.
{
"attribute_set_id": 10,
"group_name": "Dados Técnicos"
}
Rename a group. Identify by the current name (group_name) and inform new_group_name.
{
"attribute_set_id": 10,
"group_name": "Dados Técnicos",
"new_group_name": "Informações Técnicas"
}
Remove a group. System groups (created when the set is installed) may not be removable.
{
"attribute_set_id": 10,
"group_name": "Informações Técnicas"
}
Linking attributes to groups
After creating the global attribute and the group, link them so the attribute shows up on the corresponding tab of the set. Use sort_order to control the position within the group.
Link an attribute to a group inside a set.
{
"attribute_code": "codigo_fabricante",
"attribute_set_id": 10,
"attribute_group_name": "Informações Técnicas",
"sort_order": 10
}
Unlink an attribute from a set. The global attribute still exists; only the link to the set is removed.
{
"attribute_code": "codigo_fabricante",
"attribute_set_id": 10
}
Supported usage patterns
Tested and certified combinations for the attribute API.
GET /api2/attribute + page, limit, include_paginationGET /api2/attribute + frontend_input: ["select","multiselect"]GET /api2/attribute + attribute_codeGET /api2/attribute + idPOST /api2/attribute + frontend_input: "text"POST /api2/attribute + options: [...]PATCH /api2/attribute + fields to changePATCH /api2/attribute + options: [...]POST /api2/attribute/option + admin, positionPATCH /api2/attribute/option + option_idDELETE /api2/attribute/option + option_idPOST /api2/catalog/attributeSetPOST/PATCH/DELETE /api2/catalog/attributegroupPOST /api2/catalog/attributeIntegration recommendations
Recommended
- Use the
/api2/attribute/optionendpoints for surgical changes on existing options — they eliminate the cascade-removal risk introduced by the fulloptionsPATCH. - Cache the list of
select/multiselectattributes in your ERP/PIM — registration changes rarely, and each product query can reuse the table. - Before removing an option, validate whether it is in use by products.
DELETE /api2/attribute/optionalready blocks (409), but a heads-up from your side reads better to the operator. - To create select attributes with many options (>100), prefer creating the attribute empty and then issuing
POST /api2/attribute/optionin parallel — that is more predictable for audit and rollback.
Avoid
- Resubmitting the full
optionslist inPATCH /api2/attributejust to change a single option — missing options can be removed and trigger rewrites on linked products. - Trying to create options for attributes that use a custom
source_model(native boolean, status, etc.). Returns400. - Deleting an attribute set that has products without a migration plan —
force_products_remove: trueis destructive.
Incremental PIM sync
Recommended flow for a PIM: (1) sync global attributes via cached GET /api2/attribute + frontend_input; (2) detect new/changed/removed options in the PIM and apply POST/PATCH/DELETE /api2/attribute/option one by one; (3) query attributes again and validate the final table. That keeps audit logs clean and avoids accidental losses.
Common errors
| Status | Body example | When it happens |
|---|---|---|
400 | {"error": "attribute_code is required"} | Required field missing on creation. |
400 | {"error": "Attribute does not support pointwise options"} | Attempt to use /api2/attribute/option on an attribute with a custom source_model or a type other than select/multiselect. |
400 | {"error": "Invalid JSON body"} | Malformed payload. |
401 | {"error": "Unauthorized"} | Authorization missing or token expired. |
404 | {"error": "Attribute not found"} | Unknown attribute_code or id. |
404 | {"error": "Option not found"} | option_id does not belong to the informed attribute. |
409 | {"error": "Option label already exists"} | POST of an option with a duplicate label on the same attribute. |
409 | {"error": "Option is in use by products"} | DELETE of an option referenced by products. |
409 | {"error": "Attribute set has products"} | DELETE of an attribute set without force_products_remove: true. |