Skip to main content

Customer Types and Attributes

Added in Saleor 3.23.

Customer types let you segment customers and attach structured data to their accounts. A customer type is a named collection of attributes — the same attribute system used by product and page types — so you can model concepts like loyalty tiers, company details for B2B accounts, or onboarding metadata, and have them validated and queryable through the GraphQL API.

Every customer belongs to exactly one customer type. The type determines which attributes can be set on the customer and which attribute values are returned when querying the customer.

note

Customer types apply to all users, including staff. The mutations for setting attribute values described below operate on customers, but the type itself is assigned to any newly created user.

Permissions​

  • MANAGE_CUSTOMER_TYPES_AND_ATTRIBUTES — create, update, and delete customer types, manage which attributes are assigned to them, and create, update, and delete the CUSTOMER_TYPE attributes themselves.
  • MANAGE_USERS — set attribute values on customers and read all of a customer's assigned attributes.
  • Reading customer types via the customerType and customerTypes queries is available to any authenticated staff user or app, or to holders of either permission above. The fields inside are more restricted: CustomerType.attributes omits attributes that are not visible in the storefront unless the requestor holds MANAGE_USERS or MANAGE_CUSTOMER_TYPES_AND_ATTRIBUTES, and CustomerType.availableAttributes requires one of those two permissions outright.
  • Customers can read their own customerType and assigned attributes as the account owner, without any additional permission, but only attributes marked as visible in the storefront (visibleInStorefront) are included. Customers cannot set attribute values themselves — the account* mutations do not accept attributes.

The Default Customer Type​

Exactly one customer type is always marked as the default (isDefault: true). It is created automatically and:

  • is assigned to every newly created user that does not specify a customer type explicitly,
  • cannot be deleted.

To make a different type the default, pass isDefault: true to customerTypeCreate or customerTypeUpdate. The flag is cleared on the previous default automatically — exactly one default always exists.

The default flag cannot be unset directly: passing isDefault: false for the current default returns a CANNOT_UNSET_DEFAULT error. Mark another customer type as the default instead.

Managing Customer Types​

Create a customer type with customerTypeCreate:

mutation {
customerTypeCreate(input: { name: "B2B" }) {
customerType {
id
name
slug
isDefault
}
errors {
field
code
message
}
}
}

The slug is generated from the name when not provided. Use customerTypeUpdate to rename a type and customerTypeDelete to remove one. Deleting a customer type reassigns its users to the default customer type.

List types with the customerTypes query, which supports where filtering, search (by name or slug), and sorting by name or slug. Fetch a single one with customerType. Customer types also support public and private metadata.

Customer type changes trigger the CUSTOMER_TYPE_CREATED, CUSTOMER_TYPE_UPDATED, and CUSTOMER_TYPE_DELETED webhook events.

Customer Attributes​

Customer attributes are regular attributes created with the CUSTOMER_TYPE attribute type. Creating, updating, and deleting them requires the MANAGE_CUSTOMER_TYPES_AND_ATTRIBUTES permission:

mutation {
attributeCreate(
input: {
name: "Loyalty level"
type: CUSTOMER_TYPE
inputType: DROPDOWN
values: [{ name: "Silver" }, { name: "Gold" }]
}
) {
attribute {
id
slug
}
errors {
field
code
message
}
}
}

Assign attributes to a customer type with customerTypeAssignAttributes:

mutation {
customerTypeAssignAttributes(
customerTypeId: "Q3VzdG9tZXJUeXBlOjE="
attributeIds: ["QXR0cmlidXRlOjQ3"]
) {
customerType {
attributes {
id
slug
}
}
errors {
field
code
message
}
}
}

An attribute can be assigned to multiple customer types. Use customerTypeUnassignAttributes to remove attributes from a type and customerTypeReorderAttributes to change their order. The CustomerType.availableAttributes field lists customer attributes not yet assigned to the type.

customerTypeAssignAttributes and customerTypeUnassignAttributes accept at most 100 attribute IDs per call; exceeding the limit returns an INVALID error. All three attribute mutations trigger the CUSTOMER_TYPE_UPDATED webhook event.

Setting Attribute Values on Customers​

Set values through customerCreate and customerUpdate using the attributes field:

mutation {
customerUpdate(
id: "VXNlcjoyMw=="
input: {
customerType: "Q3VzdG9tZXJUeXBlOjE="
attributes: [
{ id: "QXR0cmlidXRlOjQ3", dropdown: { value: "Gold" } }
]
}
) {
user {
id
}
errors {
field
code
message
}
}
}

The attributes you pass must be assigned to the customer type the user ends up with — the type set in the same mutation, or the user's current type when customerType is not provided. Passing an attribute outside that type returns a NOT_FOUND error.

customerBulkUpdate accepts the same customerType and attributes fields, with the same validation applied per customer.

Changing a customer's attribute values triggers the CUSTOMER_UPDATED webhook event.

Reading Attribute Values​

Read a customer's type and attribute values through the User type:

query {
user(id: "VXNlcjoyMw==") {
customerType {
name
}
assignedAttributes {
attribute {
slug
}
}
assignedAttribute(slug: "loyalty-level") {
attribute {
slug
}
}
}
}

assignedAttributes returns the attributes of the user's current customer type together with their values. Staff or apps with MANAGE_USERS see all of them, while the account owner sees only attributes visible in the storefront.

Filtering Customers​

The customers query supports filtering by customer type and by attribute values:

query {
customers(
first: 10
where: {
customerType: { eq: "Q3VzdG9tZXJUeXBlOjE=" }
attributes: [{ slug: "loyalty-level", value: { slug: { eq: "gold" } } }]
}
) {
edges {
node {
email
}
}
}
}

Filtering by the default customer type also matches users that were never explicitly assigned a type.

Attribute Value Lifecycle​

Attribute values are stored independently of the customer type they were written under. Visibility is evaluated at read and filter time against the user's current type:

  • Unassigning an attribute from a customer type hides its values on users of that type, but the values stay in the database. Assigning the attribute back makes them visible again.
  • Switching a user to a different customer type hides values of attributes the new type doesn't have. If the new type shares an attribute with the old one, its values remain visible. Switching back restores the previously hidden values.
  • Deleting a user deletes their per-user attribute values — values of the file, reference, single reference, rich text, plain text, numeric, date, and date time input types, which may contain personal data. Shared choices of dropdown, multiselect, and swatch attributes belong to the attribute and are not affected.

Translations​

Unlike product and page attribute values, values of customer attributes may contain personal data and are excluded from the translations API. They are not returned by translations(kind: ATTRIBUTE_VALUE) or by the translation lookup, and attributeValueTranslate rejects them with an INVALID error. The customer attribute itself is still translatable — only its values are excluded.