Skip to main content

Overview

Attributes let you add custom fields to CXF objects — Contacts, Orders, Documents, Content Instances, and more — without changing any schema. Each attribute has a type that is validated automatically, can hold a single value or an array, can be grouped into nested structures, and can be scoped to a specific Template or Profile. For the mental model of how custom fields fit the shared object model, see Core concepts.

Where to find it

Attributes are configured inside a Template or Profile — for example, in a Content Template, an Order Template, or a Contact Profile. In the UI, an object’s Properties (its fixed fields) and its Attributes (custom fields) are shown as separate groups.

Properties

An attribute definition has the following configurable properties:
PropertyTypeRequiredDefaultDescription
titlestringYesDisplay name of the field.
slugstringYesIdentifier, unique within its object type, Template, and parent group.
object_typeenumYesThe type of object the field extends — see Object types.
data_typeenumYesThe kind of data the field holds (see Attribute types).
appearanceenumYesHow the field is presented and validated within its data type.
descriptionstringNoInternal description of the field.
help_textstringNoGuidance shown to the person filling the field.
placeholderstringNoPlaceholder text for the input.
is_requiredbooleanNofalseWhether a value is mandatory.
is_arraybooleanNofalseWhether the field holds multiple values.
is_editablebooleanNotrueWhether the value can be changed after creation.
is_visiblebooleanNotrueWhether the field is shown in the UI.
is_searchablebooleanNotrueWhether the field can be searched.
is_listablebooleanNotrueWhether the field appears in list views.
is_disabledbooleanNofalseWhether the field is turned off.
is_unboundbooleanNofalseWhether the field is exposed in the unbound view (see the note below).
is_systembooleanNofalseMarks a built-in field — visible, but protected from edit and deletion.
has_indexbooleanNofalseWhether the field is indexed for faster search and filtering.
allow_facetsbooleanNofalseWhether the field can be used as a search facet.
optionsarrayNoAllowed values, for the list appearance.
validationsobjectNoConfigurable validation rules for the type — see Configurable rules.
parent_idreferenceNoParent group, for nested fields.
template_idreferenceConditionalThe Template this field is scoped to, for template-based object types.
Unbound fields. An authenticated user who opens a record they don’t own sees only its unbound fields — the public, non-sensitive subset. Mark an attribute is_unbound: true to include it in that view; otherwise it stays private and requires ownership. Profile and Template scoping still apply.

Attribute types

Each attribute’s type — the combination of its data_type and appearance — determines how its value is presented and validated, and which extra rules you can configure. See the full list on its own page:

Attribute types

Every data type and appearance, with validation and configurable rules.
Short-text fields on Content Instances and Documents can also use an auto-incremental naming convention — a year/month/counter pattern that generates the value when the record is created.

Behaviour & rules

  • Fields must be defined first. You can only set a custom field that exists as an attribute definition for that object type (and matching Template or Profile). Setting an undefined field is rejected with The attribute <slug> is not allowed.
  • Type-safe validation. Every value is validated against its type (see Attribute types). Invalid values are rejected with a clear message, for example:
    • The attribute <slug> must be a number.
    • The attribute <slug> must be one of: active, inactive, pending.
    • The attribute <slug> must be an image.
  • Required and array rules are enforced from is_required and is_array.
  • Groups validate recursively — a group attribute validates each nested child against its own type, up to 3 levels deep.
  • Indexing for search. Fields marked has_index are indexed for faster search and filtering. Only text, number, boolean, and location types can be indexed.
  • In-use fields are protected. An attribute whose Template already has instances (or whose Profile already has associated records) is treated as in use and can’t be deleted.

Relationships

  • Host object — every attribute extends one object type: Contacts, Organizations, Users, Orders, Documents, Content Instances, and Content Versions.
  • Scoping — attributes are scoped by Templates (Content Instances, Content Versions, Orders, Documents) or Profiles (Contacts, Organizations, Users), which controls exactly which fields apply to a given record.
  • Media attributes reference assets in the DAM.
  • Group attributes contain nested child attributes.
Attributes vs Properties. Properties are the fixed, built-in fields CXF defines for an object — its base structure, the minimum it needs to exist. Attributes are the custom fields you add on top to extend it. Their values live side by side on the object; the UI usually presents them as separate groups.

Seeds

This object can be moved between environments with Seeds:
Seed typeSupportedNotes
StructuralYesAttribute definitions travel as structural configuration.
InstanceNoAttributes define structure, not template instances.

An attribute in a seed

In a structural seed, each attribute is one item with object_type: "attributes" and a data object holding its fields. Create the group first, then have each child field reference it through parent_id (resolved by the getAttributeGroup helper) and use a dotted full_slug:
[
  {
    "object_type": "attributes",
    "data": {
      "title": "Default",
      "slug": "default",
      "data_type": "group",
      "appearance": "default",
      "object_type": "content_versions",
      "template_type": "stories",
      "template_id": "{{getRecordAttribute('content_templates', 'slug', 'blog')}}",
      "full_slug": "default"
    }
  },
  {
    "object_type": "attributes",
    "data": {
      "title": "Cover Image",
      "slug": "cover_image",
      "data_type": "media",
      "appearance": "image",
      "is_required": true,
      "object_type": "content_versions",
      "template_type": "stories",
      "template_id": "{{getRecordAttribute('content_templates', 'slug', 'blog')}}",
      "parent_id": "{{getAttributeGroup('content_versions', 'default', 'blog', 'stories')}}",
      "full_slug": "default.cover_image"
    }
  }
]

Governance & permissions

  • Who can manage attributes. Only a super admin or Master can create, edit, or delete attribute definitions. There are no per-module permissions.
  • Scoping isolates fields. Template- and Profile-based scoping keeps each Template’s or Profile’s attributes separate.
  • Visibility and editability are controlled by is_visible, is_editable, and is_disabled.
  • System attributes (is_system) are protected from edit and deletion.
  • In-use attributes can’t be deleted (see Behaviour & rules).

API access

Attribute definitions are created and managed in the CXF UI (within a Template or Profile) — they cannot currently be created through the API. The attribute values on a record are read and written like any other field on that object through the API reference.

Limits & quotas

  • Nested group attributes are validated up to 3 levels deep. Aside from that, there’s no fixed limit on the number of attributes per object or on the length of an array attribute.

Profiles

Group attributes into Profiles for Contacts, Organizations, and Users.

DAM

Where media and image attributes get their assets.

API reference

Manage attributes and values programmatically.