Value lists
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.
| 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 |
| Contact lifecycle stages | /v1/customers/contact-lifecycle-stages | subscriber, lead, mql, sql, opportunity, customer |
| Activity types | /v1/customers/contact-event-kinds | note, call, email, meeting, visit, task |
| Recipient types | /v1/customers/contact-point-kinds | invoice, 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:
| Operation | What it does |
|---|---|
GET /v1/customers/address-types | Lists the address types this tenant keeps. |
POST /v1/customers/address-types | Adds an address type. |
GET /v1/customers/lifecycle-stages | Lists the company lifecycle stages this tenant keeps. |
POST /v1/customers/lifecycle-stages | Adds a company lifecycle stage. |
GET /v1/customers/contact-event-kinds | Lists the activity types this tenant keeps. |
POST /v1/customers/contact-event-kinds | Adds an activity type. |
GET /v1/customers/contact-lifecycle-stages | Lists the contact lifecycle stages this tenant keeps. |
POST /v1/customers/contact-lifecycle-stages | Adds 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-kinds | Lists the recipient types this tenant keeps. |
POST /v1/customers/contact-point-kinds | Adds a recipient type. |
GET /v1/customers/payment-terms | Lists the payment terms this tenant keeps. |
POST /v1/customers/payment-terms | Adds 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).
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.
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.
| List | Read | Rename or move | Remove |
|---|---|---|---|
| Payment terms | GET /v1/customers/payment-terms/{id} | PUT /v1/customers/payment-terms/{id} | DELETE /v1/customers/payment-terms/{id} |
| Address types | GET /v1/customers/address-types/{id} | PUT /v1/customers/address-types/{id} | DELETE /v1/customers/address-types/{id} |
| Company lifecycle stages | GET /v1/customers/lifecycle-stages/{id} | PUT /v1/customers/lifecycle-stages/{id} | DELETE /v1/customers/lifecycle-stages/{id} |
| Activity types | GET /v1/customers/contact-event-kinds/{id} | PUT /v1/customers/contact-event-kinds/{id} | DELETE /v1/customers/contact-event-kinds/{id} |
| Recipient types | GET /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
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.
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-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:
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 | All lists | One 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.