Data model

The catalog's shape is data, not schema — attributes, attribute groups and options, families, family attributes, variant structures and measurement families.

Adding a property to a product on revenexx is not a migration. It is a row in attributes and a row in family_attributes. Six entities describe the whole shape of a tenant's catalog, and every one of them is ordinary tenant data a merchant can change.

EntityBase pathAnswers
attribute_groups/v1/products/attribute_groupsWhich section of a form a field appears in
attributes/v1/products/attributesWhat properties exist at all
attribute_options/v1/products/attribute_optionsThe permitted values of a select
families/v1/products/familiesWhich set of attributes a product has
family_attributes/v1/products/family_attributesThe link, plus per-family required and order
family_variants/v1/products/family_variantsHow a family splits into variants
measurement_families/v1/products/measurement_familiesThe units a measure attribute offers

Attributes

Request
curl "https://api.revenexx.com/v1/products/attributes?limit=100" \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..."
FieldMeaning
codeStable identifier, and the key the value is stored under inside attribute_values. Also how a category rule addresses it, as attribute:<code>.
typeWhich editor the value asks for — text, select, metric, price, asset_collection, reference_entity, …
localizableOne value per locale, under locale_specific.<locale>.<code>.
scopableOne value per channel, under channel_specific.<channel>.<code>. Both flags together means channel_locale_specific.
entity_typeWhich kind of record carries it: product, reference_entity, asset, category.
entity_refNarrows entity_type to one reference entity or asset family, by code. Null for a plain product attribute.
group_idThe attribute_groups row it is filed under — the form section. Null renders after every named section.
positionOrder inside the group. A family may override it.
labelsThe field label per language tag. Falls back to English, then to the code.
validationLimits, as a flat object. The seven keys a client can act on: min, max, min_length, max_length, pattern, min_items, max_items.
configType-specific settings. The app reads units (a measure's unit list) and reference_entity (which entity a reference attribute draws options from).
is_filterableOffer this attribute as a filter in a product list. GET /v1/products/grid reports exactly these in its filters array.
usable_in_gridShow it as a column in the grid. GET /v1/products/grid returns a column definition and a per-row value for exactly these.
is_uniqueDeclares the value identifies the product — an EAN, a manufacturer part number. Metadata only: no database index enforces it, because the value lives inside jsonb.

type and entity_type deliberately carry no fixed value list. A tenant or integrator can add a type; GET /v1/products/attribute-schema maps an unknown one onto a text field rather than refusing to answer.

Attribute groups

A group is a section of the product form, not just a label. code is what a resolved field carries as its group, labels is the heading a person sees, and position orders the sections ascending.

Attribute options

The permitted values of a select or multi-select.

Option
{
  "attribute_id": "",
  "code": "matte_black",
  "labels": { "en": "Matte black", "de": "Mattschwarz" },
  "position": 20,
  "swatch": { "hex": "#1b1b1b" }
}

code is what gets stored in the product's attribute_values — never the label. Two tenants may label the same code differently. Deleting the attribute deletes its options with it. Options that tie on position keep whatever order the database returned, so give every option a position if the order matters.

Families

A family answers which attributes does a product of this kind have.

FieldMeaning
codeStable identifier, and what GET /v1/products/attribute-schema?family_code= resolves.
labelsWhat the family is called, per language tag.
label_attributeWhich attribute code carries the display name of a product in this family. Null falls back to the default_label_attribute setting, then to the conventional name.
image_attributeWhich attribute code carries the main image — what a grid thumbnail and a picker read.

A product's name being per-family is the reason POST /v1/products/labels exists: no plain read can answer what a product is called.

Family attributes

One row per (family, attribute). This is the link that makes an attribute part of a family's form.

FieldMeaning
is_requiredThe attribute has to carry a value for a product of this family to count as complete. POST /v1/products/{id}/completeness measures exactly these and nothing else.
positionThe family's own ordering, overriding the attribute's default.
required_channelsNarrows is_required to named channels.
required_channels: null or [] means required everywhere, not nowhere. That is how every required link in the wild is stored. Reading an empty list as "nowhere" reports a fully configured family as demanding nothing.

Deleting either side deletes the link.

Family variants

How a family splits — not which product splits. A family may carry several structures, and a product names the one it follows through family_variant_id.

axes names the attribute codes the split happens on, and two shapes are in the wild; both are read:

axes — flat
{ "code": "shoes_by_colour_size", "axes": ["colour", "size"] }
axes — levelled
{
  "code": "shoes_by_colour_size",
  "axes": [
    { "level": 1, "axes": ["colour"] },
    { "level": 2, "axes": ["size"] }
  ]
}

An attribute named as an axis is read-only on the model and set on each variant.

Measurement families

The unit set a measure attribute offers.

Measurement family
{
  "code": "weight",
  "standard_unit": "KILOGRAM",
  "units": [
    { "code": "KILOGRAM", "symbol": "kg", "convert_factor": 1 },
    { "code": "GRAM", "symbol": "g", "convert_factor": 0.001 }
  ],
  "labels": { "en": "Weight" }
}

convert_factor multiplies a value into standard_unit, so a gram is 0.001 kilograms. Every value is converted to the standard unit before it is compared or sorted. symbol is what a form prints next to the number.

Read the shape in one call

Six entities is five reads and a join. Do not do that — GET /v1/products/attribute-schema answers one ready-to-render field list, ordered by group then by the family's own ordering, with the storage path and fallback order per field. See Completeness.

Where to go next

  • Products — the row these definitions shape.
  • Completenessattribute-schema and the completeness measure.
  • References — where a reference_entity attribute draws its values from.
  • Assets — asset families and their attributes.
Was this page helpful?