Get Attributes
About
The attributes query returns a cursor-paginated list of every product attribute in the catalog, each with its configuration, its selectable options, and its per-locale names. Use it to:
- Discover which attributes exist and which of them are filterable or configurable
- Cache an attribute-code to option-ID map that a client reuses across screens
- Read swatch settings before rendering colour or image pickers
- Read attribute and option labels in every locale a store supports
The list is not category-aware. To build a filter sidebar for one category, use Category Attribute Filters, which returns only the attributes that belong on that category. To read a single attribute, use Get Attribute.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
first | Int | ❌ No | Number of attributes to return from the start (forward pagination). Default: 10 |
after | String | ❌ No | Cursor to start after for forward pagination. Take it from the previous response's endCursor. |
last | Int | ❌ No | Number of attributes to return from the end (backward pagination). Default: 10 |
before | String | ❌ No | Cursor to start before for backward pagination. |
There is no argument to filter the list — by code, by type, or by the filterable flag. Fetch the page and narrow it in the client, or use the category-scoped query instead.
Possible Returns
| Field | Type | Description |
|---|---|---|
edges | [AttributeEdge] | Attribute edges for the current page. |
edges.node | Attribute | A single attribute — fields below. |
edges.cursor | String! | Cursor for this attribute, used as after on the next request. |
pageInfo | AttributePageInfo! | Pagination metadata. |
pageInfo.hasNextPage | Boolean | Whether more attributes follow the current page. |
pageInfo.hasPreviousPage | Boolean | Whether attributes precede the current page. |
pageInfo.startCursor | String | Cursor of the first attribute on the page. |
pageInfo.endCursor | String | Cursor of the last attribute on the page. |
totalCount | Int! | Total attributes in the catalog. |
Attribute Fields
The is* and valuePer* flags come back as the strings "1" / "0", not as GraphQL booleans.
| Field | Type | Description |
|---|---|---|
id | ID! | IRI-style identifier (/api/shop/attributes/23). |
_id | Int! | Numeric attribute ID. |
code | String! | Machine-readable code — sku, color, size. This is the key a product filter expects. |
adminName | String! | Admin-facing name. Use translation for the shopper-facing label. |
type | String! | Input type — see Attribute Types. |
swatchType | String | Swatch style for this attribute's options, or null when it uses none. |
position | Int | Sort order among attributes. |
isRequired | String! | "1" when the attribute is mandatory on the product form. |
isUnique | String! | "1" when values must be unique across products. |
isFilterable | String! | "1" when the attribute can drive layered navigation. |
isComparable | String! | "1" when the attribute appears on the compare page. |
isConfigurable | String! | "1" when the attribute can define configurable-product variants. |
isUserDefined | String! | "1" for a merchant-created attribute, "0" for a system one. |
isVisibleOnFront | String! | "1" when the attribute is shown on the product page. |
valuePerLocale | String! | "1" when the value differs per locale. |
valuePerChannel | String! | "1" when the value differs per channel. |
defaultValue | Int | Default option ID, when the attribute defines one. |
validation | String | Validation rule applied to the value, e.g. decimal. null when none is set. |
validations | String | Additional validation metadata as a string, e.g. { required: true }. |
regex | String | Regular expression the value must match, when configured. |
columnName | String | Underlying storage column, when applicable. |
enableWysiwyg | String! | "1" when the admin editor uses a rich-text field. |
createdAt | String | ISO 8601 creation timestamp. |
updatedAt | String | ISO 8601 timestamp of the last change. |
options | AttributeOptionCursorConnection | Selectable values. Empty for text, textarea, price, date, and boolean attributes. |
translation | AttributeTranslation | The attribute's name in the current locale. |
translations | AttributeTranslationCursorConnection | The attribute's name in every locale. |
Option Fields
Each node in an attribute's options connection:
| Field | Type | Description |
|---|---|---|
id | ID! | IRI-style option identifier. |
_id | Int! | Numeric option ID. This is the value to send when filtering products. |
adminName | String | Admin-facing option name. Use translation for the shopper-facing label. |
sortOrder | Int | Display order within the attribute. |
swatchValue | String | Hex colour for a colour swatch, or the text value. |
swatchValueUrl | String | URL of the swatch image, for image swatches. |
translation | AttributeOptionTranslation | The option's label in the current locale. |
translations | AttributeOptionTranslationCursorConnection | The option's label in every locale. |
Translation Fields
| Field | Type | Description |
|---|---|---|
id | ID! | IRI-style translation identifier. |
_id | Int! | Numeric translation ID. |
locale | String! | Locale code, e.g. en, ar. |
attributeId | String! | Parent attribute ID, on an attribute translation. |
attributeOptionId | String! | Parent option ID, on an option translation. |
name | String | Attribute name in that locale. |
label | String | Option label in that locale. |
Attribute Types
| Type | Control | Carries options |
|---|---|---|
text | Single-line text input | No |
textarea | Multi-line text, optionally rich-text when enableWysiwyg is "1" | No |
select | Dropdown, one value | Yes |
multiselect | Multiple values | Yes |
checkbox | Multiple values as checkboxes | Yes |
boolean | Yes/No toggle | No |
date / datetime | Date picker | No |
price | Decimal amount | No |
image / file | Uploaded asset | No |
Only the option-carrying types return anything in their options connection; the rest come back empty.
Use Cases
1. Discovering the filterable attributes
There is no filter argument, so page the list and select the ones flagged filterable in the client:
query filterableAttributes {
attributes(first: 100) {
edges {
node {
_id
code
adminName
type
swatchType
isFilterable
translation {
name
}
}
}
totalCount
}
}Keep the nodes whose isFilterable equals the string "1".
2. Caching an option-ID to label map
Attribute values on a product come back as option IDs. Fetch the attributes with their options once and cache the mapping, rather than resolving labels product by product:
query attributeOptionMap {
attributes(first: 100) {
edges {
node {
code
options(first: 100) {
edges {
node {
_id
translation {
label
}
}
}
}
}
}
}
}3. Paging through the full list
query nextAttributes($after: String) {
attributes(first: 10, after: $after) {
edges {
node {
_id
code
adminName
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}Repeat with the returned endCursor while hasNextPage is true.
Best Practices
- Request a large
firstwhen caching — the default page is 10 attributes, and a client that wants the whole set otherwise pays several round trips - Compare the flags against strings —
isFilterableand its siblings return"1"/"0", so testing the raw string for truthiness treats"0"as true - Page the nested
optionsconnection too — it is a connection in its own right with its own default of 10, so a brand attribute with hundreds of values is silently truncated - Select only the locales you need — asking for
translationson both the attribute and every option multiplies the response, whiletranslationreturns just the current locale - Use the category-scoped query for a filter sidebar — Category Attribute Filters returns only what belongs on that category, with the price range attached
- Never pass a made-up cursor — an
aftervalue that did not come from a previous response fails the request rather than returning an empty page
Error Scenarios
| Scenario | Cause |
|---|---|
| Invalid cursor | The after or before value is not a cursor returned by a previous response. |
Related Resources
- Get Attribute - One attribute with its options
- Attribute Options - Option values across every attribute
- Category Attribute Filters - Filterable attributes for one category
- List Products - Apply an attribute filter
- Pagination Guide - Cursor pagination documentation
- Shop API Overview - Overview of Shop API resources

