Value lists

The tenant's own vocabularies in the customers app — payment terms, address types, company and contact lifecycle stages, activity and recipient types — plus the vocabulary discovery routes every commerce app publishes.

Six things a merchant configures rather than a release changes: how a company pays, what an address is for, where a company and a person stand in the pipeline, what kinds of activity a timeline records, and which document each recipient type receives.

Each is an ordinary CRUD resource with a stable key, a localized label and a position.

ListBase pathSeeded with
Payment terms/v1/customers/payment-termsprepayment, direct_debit, net_7, net_14, net_30, net_60, net_90
Address types/v1/customers/address-typesbilling, shipping
Lifecycle stages/v1/customers/lifecycle-stagesThe tenant's own pipeline stages
Contact lifecycle stages/v1/customers/contact-lifecycle-stagessubscriber, lead, mql, sql, opportunity, customer
Activity types/v1/customers/contact-event-kindsnote, call, email, meeting, visit, task
Recipient types/v1/customers/contact-point-kindsinvoice, order_confirmation, shipping_notice, dunning

Every one supports GET (list), POST (add), GET/PUT/DELETE by id. The PUT route renames an entry or moves it in the order; the DELETE route removes an entry nothing uses.

Beside the examples on this page, these calls exist:

OperationWhat it does
GET /v1/customers/address-typesLists the address types this tenant keeps.
POST /v1/customers/address-typesAdds an address type.
GET /v1/customers/lifecycle-stagesLists the company lifecycle stages this tenant keeps.
POST /v1/customers/lifecycle-stagesAdds a company lifecycle stage.
GET /v1/customers/contact-event-kindsLists the activity types this tenant keeps.
POST /v1/customers/contact-event-kindsAdds an activity type.
GET /v1/customers/contact-lifecycle-stagesLists the contact lifecycle stages this tenant keeps.
POST /v1/customers/contact-lifecycle-stagesAdds a contact lifecycle stage.
PUT /v1/customers/contact-lifecycle-stages/{id}Edits a contact lifecycle stage. Described on the Contacts page.
DELETE /v1/customers/contact-lifecycle-stages/{id}Removes a contact lifecycle stage. Described on the Contacts page, with its 409 cases.
GET /v1/customers/contact-point-kindsLists the recipient types this tenant keeps.
POST /v1/customers/contact-point-kindsAdds a recipient type.
GET /v1/customers/payment-termsLists the payment terms this tenant keeps.
POST /v1/customers/payment-termsAdds a payment term.

Every list takes an active flag. On GET (query), true answers only the values still on offer and false only the retired ones; left out, every value comes back. On POST (body) it defaults to true. On PUT (body), active: false retires a value: records that carry it keep it, and pickers stop offering it. The default cannot be retired, so make another entry the default first. An inactive value cannot be made the default, on create or on edit (409 inactive_cannot_be_default), and the current default cannot be marked inactive until another value holds the default (409 default_must_stay_active).

Request
curl https://api.revenexx.com/v1/customers/payment-terms \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..."
Request
curl -X POST https://api.revenexx.com/v1/customers/address-types \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..." \
  -H "Content-Type: application/json" \
  -d '{"code":"works_entrance","labels":{"en":"Works entrance","de":"Werkstor"},"position":30}'

That is the point of these being data: a merchant adds a works entrance or a central accounts office as an address type without waiting for a release.

One value by id

These routes take the value's id, which is not its code: records store the code. Contact lifecycle stages have their own by-id routes, described on the Contacts page.

ListReadRename or moveRemove
Payment termsGET /v1/customers/payment-terms/{id}PUT /v1/customers/payment-terms/{id}DELETE /v1/customers/payment-terms/{id}
Address typesGET /v1/customers/address-types/{id}PUT /v1/customers/address-types/{id}DELETE /v1/customers/address-types/{id}
Company lifecycle stagesGET /v1/customers/lifecycle-stages/{id}PUT /v1/customers/lifecycle-stages/{id}DELETE /v1/customers/lifecycle-stages/{id}
Activity typesGET /v1/customers/contact-event-kinds/{id}PUT /v1/customers/contact-event-kinds/{id}DELETE /v1/customers/contact-event-kinds/{id}
Recipient typesGET /v1/customers/contact-point-kinds/{id}PUT /v1/customers/contact-point-kinds/{id}DELETE /v1/customers/contact-point-kinds/{id}

The code never changes. A PUT changes the titles, the help text, the badge tone, the position and active, and it can make the value the default. A body with a different code, or with no field at all, is a 400; an edit that would leave the default inactive is a 409 (default_must_stay_active), and so is making an inactive value the default (inactive_cannot_be_default). A rename leaves the code that records store as it is.

DELETE removes a value that nothing uses. It answers 404 when no value has that id. It answers 409 (value_in_use) while any record still carries the code, and a plain 409 when it would empty the set. The activity type system is written by the app itself and answers 409 (value_reserved). For payment terms, only the companies' own payment_terms count as use: a market's default_payment_terms setting is not checked, so change that default before you delete the term it names. To retire a value that records use, move those records onto another value first, then remove it.

Seed them all in one call

Request
curl -X POST https://api.revenexx.com/v1/customers/defaults \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..." \
  -H "Content-Type: application/json" \
  -d '{}'

Fills all six value sets in one call, and is what the app's install event runs. Idempotent by code: a set that already has rows is left completely alone, so a re-delivered event and a merchant's renames both survive.

Vocabularies — reading the enums instead of hard-coding them

Beyond the six editable lists, the app publishes every enum it enforces through two discovery routes. Every commerce app has the same pair.

Request
curl https://api.revenexx.com/v1/customers/vocabularies \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..."

That answers which vocabularies exist — each as a name, a title and a description — and deliberately leaves the values out. In the customers app:

text
address-types             contact-event-kinds       contact-lifecycle-stages
contact-point-kinds       contact-statuses          credit-limit-modes
lead-sources              lifecycle-stages          locales
order-approval-modes      organization-statuses     payment-terms
permissions               registration-statuses     roles
rule-matches              segment-member-types      segment-sources
shipping-advice           shop-access

Fetch one by name:

Request
curl https://api.revenexx.com/v1/customers/vocabularies/contact-statuses \
  -H "X-Revenexx-Tenant: <TENANT_SLUG>" \
  -H "X-Revenexx-Api-Key: rvxk_..."

A client holding the qualified pair customers.<name> builds that URL from the pair alone.

Why this matters for a Cockpit surface

A select field or a badge column with a hard-coded options list cannot offer a value the merchant created after you wrote the manifest. Point it at the vocabulary instead:

cockpit.json
{ "name": "payment_terms", "label": { "en": "Payment terms" },
  "type": "select", "vocabulary": "customers.payment-terms" }

See List views and Forms.

The same pair, in every commerce app

AppAll listsOne list
products/v1/products/vocabularies/v1/products/vocabularies/{name}
prices/v1/prices/vocabularies/v1/prices/vocabularies/{name}
carts/v1/carts/vocabularies/v1/carts/vocabularies/{name}
orders/v1/orders/vocabularies/v1/orders/vocabularies/{name}
orderlists/v1/orderlists/vocabularies/v1/orderlists/vocabularies/{name}
customers/v1/customers/vocabularies/v1/customers/vocabularies/{name}
sales-reps/v1/sales-reps/vocabularies/v1/sales-reps/vocabularies/{name}
payments/v1/payments/vocabularies/v1/payments/vocabularies/{name}
shipping/v1/shipping/vocabularies/v1/shipping/vocabularies/{name}
inventories/v1/inventories/vocabularies/v1/inventories/vocabularies/{name}
markets/v1/markets/vocabularies/v1/markets/vocabularies/{name}
channels/v1/channels/vocabularies/v1/channels/vocabularies/{name}
pages/v1/pages/vocabularies/v1/pages/vocabularies/{name}
forms/v1/forms/vocabularies/v1/forms/vocabularies/{name}
quotes/v1/quotes/vocabularies/v1/quotes/vocabularies/{name}

Where to go next

  • Organizations — where payment terms, lifecycle stages and address types are used.
  • Contacts — where activity types are used.
  • Settings — the other configuration surface, per market.
Was this page helpful?