Custom Fields let you keep one shared dataset for all your customers, while giving each customer the extra fields that only they need.
Many software companies that embed Luzmo start with one copy of a dataset per customer. It works, until you need to rename a field, fix a formula, or change a format: the change has to be repeated on every copy, and over time the copies drift apart.
With Custom Fields, you manage a single dataset. Fields that everyone uses stay shared. Fields that only one customer (or a few customers) need are scoped to those tenants, so only they see them. Fix a shared calculation once, and every customer gets the fix.
A Custom Field can be:
A tenant represents one of your end customers. You create tenants through the API, and you link an embed token to a tenant when your customer's users open a dashboard or the embedded dashboard editor.
If you already use suborganizations in your embed tokens, the tenant defaults to the suborganization value, so every customer is mapped to a tenant in the same way.
Every field in a dataset is either shared or scoped to one or more tenants.
| Field scope | Who sees it | How it gets this scope |
|---|---|---|
| Shared | All tenants, and your organization | Default. Every field without a tenant assignment is shared. |
| Tenant field | Only the assigned tenants, and your organization | You assign the field to one or more tenants, or a tenant creates it in the embedded dashboard editor. |
A few rules to keep in mind:
Imagine an Opportunities dataset that you share with three customers.
| Field | Type | Scope |
|---|---|---|
| Opportunity ID | Source column | Shared |
| Amount | Source column | Shared |
| Status | Source column | Shared |
| Win rate | Formula | Shared |
| Sales Region | Source column | Acme |
| Contract Value | Derived column | Acme |
| Renewal Risk | Source column | Globex |
| Implementation Phase | Source column | Initech |
When an Acme user opens the dashboard editor, the field list shows the four shared fields plus Sales Region and Contract Value. A Globex user sees the shared fields plus Renewal Risk. Nobody sees the fields of another customer, and none of them can tell those fields exist.
If you improve the Win rate formula, all three customers get the new version immediately.
Custom Fields are a good fit when:
Custom Fields are less suited when:
| You want to… | Use |
|---|---|
| Add a row-level calculation for everyone | A shared derived column |
| Add a metric for everyone | A shared aggregation formula |
| Show a column, derived column or formula to specific customers only | Assign it to those tenants |
| Let a customer create private fields | Give them the embedded dashboard editor with a tenant-scoped token |
| Give a customer extra columns from their own database | A tenant data source |
Setup is done through the Luzmo API today. Your end users don't need to do anything: tenant fields simply appear in the field list of the dashboard editor and the embedded dashboard editor.
Create one tenant per end customer, with a unique identifier and a display name.
POST https://api.luzmo.com/0.1.0/tenant
{
"action": "create",
"version": "0.1.0",
"key": "<your API key>",
"token": "<your API token>",
"properties": {
"identifier": "acme",
"name": { "en": "Acme Corp" }
}
}
When you create an embed authorization for a customer's user, pass the tenant property. If you also pass suborganization, both values must be equal.
"properties": {
"type": "embed",
"username": "user-123",
"suborganization": "acme",
"tenant": "acme",
...
}
Associate a column (source or derived) or a formula with a tenant:
POST https://api.luzmo.com/0.1.0/column
{
"action": "associate",
"version": "0.1.0",
"key": "<your API key>",
"token": "<your API token>",
"id": "<column id>",
"resource": { "role": "Tenants", "id": "<tenant id>" }
}
Use /0.1.0/formula to assign a formula, and dissociate to remove an assignment.
To assign many fields in one call, use the bulk action on the tenant resource. A bulk call is all-or-nothing: if one assignment fails, none are applied.
POST https://api.luzmo.com/0.1.0/tenant
{
"action": "associate",
"version": "0.1.0",
"key": "<your API key>",
"token": "<your API token>",
"assignments": [
{ "tenant_id": "<acme id>", "resource": { "role": "Columns", "id": "<sales region id>" } },
{ "tenant_id": "<acme id>", "resource": { "role": "Formulas", "id": "<contract value id>" } }
]
}
Tenant fields are not added to dashboards automatically. Build dashboards with shared fields to serve every tenant with one dashboard. When a dashboard uses tenant fields, create it for (or let it be created by) the tenants that can see those fields.
When a customer's user creates a derived column or a formula in the embedded dashboard editor with a tenant-scoped embed token, the new field is automatically scoped to that tenant. Other customers never see it, and you don't need an extra API call.
Fields created by users of your own organization stay shared, unless you assign them.
A tenant can only build on fields it can see. If a derived column or formula references a field that is hidden for the tenant, creation fails with the same error as for a field that doesn't exist. This keeps other customers' fields private.
Some customers store their data in their own database, with a few extra columns on top of your standard model. With a tenant data source, one logical dataset reads each tenant's data from that tenant's own connection and table (or SQL query).
You create a tenant data source through the API with the tenantdatasetsource resource, which links a tenant and a dataset to a connection plus either a table or a SQL query.
identifier, ideally the same value you already use as suborganization.No. Custom Fields are available without a feature flag. Fields without a tenant assignment remain shared, so existing datasets are unaffected.
They control which fields a tenant can see and query: a hidden field is removed from the field list and can't be queried. They don't restrict rows. Use embed token filters, parameters or separate connections for row-level access.
Yes. Assign the same column or formula to each tenant that needs it.
Yes. Derived columns and formulas created in the embedded dashboard editor with a tenant-scoped token are automatically scoped to that tenant.
The fields that tenant created are cleaned up together with the tenant.
A suborganization groups the users of one customer for things like access and ownership. A tenant defines which dataset fields that customer sees. In most setups they use the same value.