Understanding companies, contacts and customers
Propeller uses three account entities to model B2B and B2C relationships. Companies and contacts are used for B2B. Customers are used for B2C. Understanding how they relate helps you build registration, checkout and account management features correctly.
Companies
A company is the B2B entity, identified by companyId. A company represents a business organization with its own financial details, addresses and users.
| Field | Description |
|---|---|
name | Company name |
email, phone | Company contact details |
taxNumber | VAT / tax registration number |
cocNumber | Chamber of Commerce number |
debtorId | Financial identifier for invoicing |
notes | Internal notes |
slug | URL-friendly identifier |
tag | Custom tag for grouping or classification |
hidden | Whether the company should only be used for background operations (Y/N) |
A company has contacts (the people who operate within it), addresses (delivery and invoice) and optionally managers (account managers assigned to the company).
Contacts
A contact is a B2B user entity, identified by contactId. A contact is a person who operates within the context of one or more companies.
Contacts carry personal fields (firstName, middleName, lastName, email, phone, mobile, gender, dateOfBirth, primaryLanguage, login) plus B2B-specific fields:
| Field | Description |
|---|---|
parentCompanyId | The primary company this contact belongs to |
company | The primary company entity |
companies | All companies the contact belongs to |
managedCompanies | Companies where this contact is an account manager |
Contacts in multiple companies
A contact can belong to multiple companies. Each company relationship is independent, with its own purchase authorization role and spending limit.
For example, a single contact might belong to three companies:
Contact: Lisa de Vries
├── Brouwer Industrie NL (AUTHORIZATION_MANAGER, no spending limit)
├── Brouwer Industrie DE
└── Brouwer Industrie US
When a contact places an order, the order is associated with both the contact and the company they are ordering for.
Customers
A customer is the B2C user entity, identified by customerId. Customers are standalone accounts that do not belong to a company.
Each customer carries personal details and their own account data:
| Field | Description |
|---|---|
firstName, middleName, lastName | Full name |
email | Email address |
phone, mobile | Phone numbers |
gender | M, F or U (unknown) |
dateOfBirth | Date of birth |
primaryLanguage | Preferred language |
login | The email used for authentication. When null, no account has been linked yet |
debtorId | Financial identifier for invoicing |
expires | Optional expiration date. After this date the account is disabled |
mailingList | Whether the customer is subscribed to mailings (Y/N) |
Customers have their own addresses (home, delivery and invoice) and their own order history.
Addresses
Companies and customers have addresses. Contacts do not have their own addresses. They use the addresses of the company they are ordering for.
There are three address types: delivery, invoice and home.
Each address includes:
| Field | Description |
|---|---|
street, number, numberExtension | Street address |
postalCode, city, region, country | Location |
firstName, middleName, lastName, gender | Addressee |
company | Company name on the address |
phone, mobile, email | Contact details |
isDefault | Whether this is the default address for its type (Y/N) |
type | delivery, invoice or home |
active | Whether the address is active (Y/N) |
icp | Intra-Community Performance flag (Y/N). Used for B2B cross-border orders to determine whether tax should be applied |
code, notes, name | Custom code, delivery notes and a friendly descriptive name |
A company can have multiple addresses per type. For example, a company might have two delivery addresses at different locations, with one marked as default.
Purchase authorization
Purchase authorization controls what contacts are allowed to order within a company. Each contact-company relationship has a PurchaseAuthorizationConfig that defines a role and an optional spending limit.
Roles
| Role | Description |
|---|---|
PURCHASER | Default role. Can place orders but is subject to an authorization limit per order. When the order total exceeds the limit, the order cannot be completed without approval from an authorization manager |
AUTHORIZATION_MANAGER | Manages authorization limits and purchase requests for purchasers. Has no spending limit |
Authorization limit
The authorizationLimit field sets the maximum amount a purchaser can spend per order. When null (for authorization managers), there is no limit.
A contact has a separate configuration per company they belong to. This means the same person can have different roles and limits at different companies.
For example, within a single company:
Brouwer Industrie NL
├── Lisa de Vries — AUTHORIZATION_MANAGER (no limit)
├── Tom Hendriks — PURCHASER (limit: €0, all orders require approval)
├── Eva Mulder — PURCHASER (limit: €250)
└── Jan Brouwer — no config (no limit)
When Eva places an order above €250, it requires authorization from Lisa before it can be processed. Contacts without a purchase authorization config, like Jan, can order without restrictions.
How this relates to orderlists
Orderlists are customer-specific catalogs that control which products and clusters are visible and orderable for specific accounts. An orderlist can be assigned to companies or individual users (contacts or customers). Each orderlist has a code, descriptions, optional validity dates (validFrom, validTo) and an active flag.
When an orderlist is assigned, only the products and clusters in that list are available to the account.
How this relates to pricesheets
Pricesheets provide customer-specific pricing. A pricesheet can be assigned to companies, contacts or customers. Each pricesheet has a code, localized names and descriptions, a priority (to determine which applies when multiple match) and a readonly flag.
For example, a company might have a "Premium customers" pricesheet assigned at the company level, giving all contacts within that company access to special pricing.
For the full pricing model, see Understanding pricing layers.
How this relates to favorite lists
Favorite lists let users save collections of products and clusters for quick reordering. A favorite list can belong to a company (companyId), a contact (contactId) or a customer (customerId).
Company-level lists are shared across all contacts in that company. Contact-level and customer-level lists are personal.
For example, a company might have a shared list for commonly ordered supplies, while individual contacts maintain their own lists for specific projects.
For practical details, see Favorite lists.
How this relates to attributes
Companies, contacts and customers can all have attributes. The attribute system works the same way as for products: each attribute is defined by an attributeDescription with a name, type, group and behavior flags.
Company attributes might store business-specific data like payment possibilities or business type classifications. Contact attributes might control ordering behavior, such as whether a contact can only order via quotes or has a budget restriction.
System attributes (where isSystem is true and isHidden is true) are used internally for features like user group assignments and are not meant to be displayed to end users.