Customers and organizations
Organizations
The buying company — commercial terms, access flags, addresses and the buying-metrics projection.
Contacts
The people inside a company, the activity timeline, and the registration approve/reject flow.
Roles and permissions
Editing the role ledger, reading a contact's effective grants, and how the gateway resolves a principal.
Segments
Named groups of organizations — hand-picked, rule-materialised, or both.
Value lists
Payment terms, address types, lifecycle stages, activity kinds — the tenant's own vocabularies.
Sales reps
The rep roster, which rep looks after which customer, the responsible rep, and the acting-for log.
Storefront accounts
Register, login, me, logout and recovery — the passthrough a shop front-end calls.
The customers app is the largest in the commerce domain: 13 entities and 72 capability routes under https://api.revenexx.com/v1/customers.
The shape of the domain
It is B2B-first, and two entities carry the weight:
- An organization is the buying company — the unit a contract, a credit limit and a price list belong to.
- A contact is a person, and the unit that logs in: one login identity, one email, one role inside its organization.
A contact without an organization is a standalone buyer, not an error — that is how B2C works here. Deleting an organization sets its contacts' organization_id to null and keeps the people.
Both are mirrored into platform auth: an organization gets an external_team_id, a contact an external_user_id. Both are written by the platform and ignored on any write you send.
Events
Publishing is automatic for the records: organization.created, .updated and .deleted, the same three for contact and address, and contact_event.created for each timeline row. The app adds contact.registered, contact.registration_approved, contact.registration_rejected, contact.blocked, organization.blocked and segment.recomputed. A rejection publishes only contact.registration_rejected, never contact.blocked as well. Copy the exact topic strings from the topic list in Cockpit's webhook endpoint form (Event types).
Two separate axes, deliberately
New integrators collapse these and it goes wrong quietly:
| Column | Is about | Values |
|---|---|---|
organizations.status | Access — may this company's people log in | active, blocked |
organizations.lifecycle_stage | Sales pipeline — how far along the company is | One of the tenant's own stages |
organizations.delivery_block | Shipments only — they may order, nothing ships | boolean |
contacts.status | Whether the person may act | invited, active, blocked |
contacts.registration_status | Where their application stands | pending, approved, rejected |
contacts.role | The only input to permissions | One of the tenant's roles |
A prospect that may log in and a customer that may not are both ordinary states; one column cannot express that. And job_title is free text with no authority attached — the ladder is role.
Routes at a glance
| Area | Base path |
|---|---|
| Companies and people | /v1/customers/organizations, /contacts, /addresses |
| Buying metrics | /v1/customers/organization_metrics, /refresh, /freshness |
| Timeline | /v1/customers/contact_events, POST /contacts/{id}/events, POST /organizations/{id}/events |
| Registration decisions | POST /v1/customers/contacts/{id}/registration/approve and /reject |
| Roles | GET /v1/customers/roles, PUT /roles/{key}/permissions, GET /contacts/{id}/permissions, POST /principal/resolve |
| Segments | /v1/customers/segments, /segment_members, /segments/{id}/rules/preview, /rules/recompute |
| Value lists | /v1/customers/payment-terms, /address-types, /lifecycle-stages, /contact-event-kinds, /vocabularies |
| Storefront accounts | /v1/customers/auth/register, /login, /logout, /me, /recovery |
In this group
- Organizations — the company row and its metrics.
- Contacts — people, timeline, registration.
- Roles and permissions — the grant model.
- Segments — grouping companies.
- Value lists — the tenant's own vocabularies.
- Storefront accounts — what a shop front-end calls.