Vocabularies

A vocabulary is a value set your app publishes and a merchant can extend — where it appears in the Cockpit, how to read one over the gateway, and when to use one instead of a fixed enum.

A vocabulary is a named set of values your app publishes, which a merchant can extend at runtime. It is the answer to the most common gap in an admin UI: a list of statuses, conditions, reasons or categories that you cannot possibly enumerate correctly for every customer.

A value a merchant adds shows up in the form, in the filter and in the badge label without you shipping a new version.

Reading one over the gateway

Every app that publishes vocabularies serves them on the public gateway:

Request
curl "https://api.revenexx.com/v1/serials/vocabularies/device_conditions" \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..."
text
GET /v1/{app}/vocabularies/{name}

{app} is the app that owns the vocabulary and {name} is the vocabulary name — the part after the dot in its qualified id. The platform's own commerce apps expose the same shape, which is how a storefront or an integration renders a value the merchant invented after the integration was written.

The CLI has it per app too:

CLI
revenexx products vocabularies-list
revenexx products vocabularies-get --name conditions

Where it appears in the Cockpit

Two places, and both are one field:

A settings key takes its options from a vocabulary instead of a fixed list:

settings.json
"default_condition": {
  "title": { "en": "Default device condition" },
  "type": "select",
  "scope": "tenant",
  "vocabulary": "device_conditions"
}

A column or a field resolves a stored value to its human label:

cockpit.json
{ "name": "condition", "label": { "en": "Condition" }, "type": "badge", "vocabulary": "device_conditions" }

Without the vocabulary, a badge shows the raw stored value — refurb_a rather than "Refurbished (grade A)" — and a hardcoded options list cannot offer a value the merchant created after you wrote the file. That is the practical reason to reach for it: it is one key that keeps a screen correct as the business changes.

Vocabulary or enum_values

Both constrain a value to a list. The difference is who owns the list, and it is a design decision:

UseWhen
enum_valuesYour code branches on the value. Three rounding modes are three code paths, and a fourth one a merchant invents cannot work.
A vocabularyThe value is data your code passes through — a label, a classification, a reason.

The test is one question: would a value you have never seen break your handler?

If yes, it is enum_values, and a merchant needing a fourth option is a feature request. If it would flow through your code untouched into a column, a label and a report, it is a vocabulary — and a merchant knowing their own categories better than you do is the normal case, not the exception.

Where you genuinely need both — a fixed set your code understands and room for the merchant's own detail — model them as two columns: a kind you branch on with enum_values, and a classification from a vocabulary that you only ever store and display.

Handling merchant-extended values

Once a set is extensible, your code has to be honest about not knowing it:

Never assume the set you shipped is the set you will read. No switch with a default that throws, and no exhaustive mapping that silently drops the unknown value.

Render the raw value when a label is missing rather than an empty cell. An operator seeing refurb_c can act on it; a blank badge tells them the app is broken.

Do not validate against a snapshot. If a value has to be a member of the vocabulary, check against the vocabulary as it is now, not against a constant in your source.

Keep the stored value stable. A vocabulary entry's label is what a merchant changes; the value your rows hold should not move underneath them.

Next steps

Was this page helpful?