Value lists
Four things a merchant configures rather than a release changes: how a company pays, what an address is for, where a company stands in the pipeline, and what kinds of activity a timeline records.
Each is an ordinary CRUD resource with a stable key, a localized label and a position.
| List | Base path | Seeded with |
|---|---|---|
| Payment terms | /v1/customers/payment-terms | prepayment, direct_debit, net_7, net_14, net_30, net_60, net_90 |
| Address types | /v1/customers/address-types | billing, shipping |
| Lifecycle stages | /v1/customers/lifecycle-stages | The tenant's own pipeline stages |
| Activity types | /v1/customers/contact-event-kinds | note, call, email, meeting, visit, task |
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.
curl https://api.revenexx.com/v1/customers/payment-terms \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..."
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.
Seed them all in one call
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 four 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 four editable lists, the app publishes every enum it enforces through two discovery routes. Every commerce app has the same pair.
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:
address-types contact-event-kinds contact-statuses
lifecycle-stages locales organization-statuses
payment-terms registration-statuses roles
rule-matches segment-sources
Fetch one by name:
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:
{ "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
| App | Route |
|---|---|
| products | /v1/products/vocabularies |
| prices | /v1/prices/vocabularies |
| carts | /v1/carts/vocabularies |
| orders | /v1/orders/vocabularies |
| orderlists | /v1/orderlists/vocabularies |
| customers | /v1/customers/vocabularies |
| payments | /v1/payments/vocabularies |
| shipping | /v1/shipping/vocabularies |
| inventories | /v1/inventories/vocabularies |
| markets | /v1/markets/vocabularies |
| channels | /v1/channels/vocabularies |
| pages | /v1/pages/vocabularies |
| forms | /v1/forms/vocabularies |
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.