Distribution Network
The distribution network is the partner layer on top of Licensing. A distributor is a workspace that sells Altovar products to its own customers and issues the license keys for them, inside the limits you set.
Access it from the sidebar: Licensing → Distributors.
There is no separate licensing engine behind this. A key issued by a partner is an ordinary tenant license key — the same one you would issue from Licensing → Keys — only attributed to the partner’s channel and capped by what you granted. Everything you already know about policies, expiry and revocation still applies.
The order that works
Each step depends on the one before it. Skipping one does not fail loudly — it fails later, on the partner’s side, when they try to sell something.
Create the distributor
Either you link the partner’s existing workspace, or Auris creates it and invites the contact. Nothing is sellable yet.
Grant the product lines
One grant per product line. Without a grant the line does not exist for the partner, and there is no quota for its customers to consume.
Attribute its customers
You attribute customers, not the partner. Until a customer is attributed, the partner cannot issue a single key for it.
Issue a key — optionally
The partner normally does this from its own portal. You can do it in its place from the distributor page, for a first order or a migration.
Step 1 — Create the distributor
New Distributor opens on two modes, because a partner reaches you in two different states. Pick the wrong one and nothing breaks — you just get an error that names the other one.
Link an existing workspace
The partner is already on Auris and becomes a distributor as well.
- Go to Licensing → Distributors and click New Distributor, then Link an existing workspace
- Tenant Realm — the realm of the workspace that becomes a distributor (for example
acme-partner). It must already exist, otherwise you get No tenant with that realm - Name — leave empty to reuse the workspace name
- Tier — free text for your own commercial segmentation (
gold,reseller, …). It enforces nothing - Notes — internal. The partner never sees them
- Click Create
This mode sends no invite, and it configures no way in. It attaches a row to a workspace that
already has its own users and its own sign-in. If nobody in that workspace can reach
partners.altovar.net yet, that is a workspace problem, not a distributor one — and
⋮ → Resend invite will not fix it, because there is no partner-portal magic link set up on
that realm to re-send. Use the other mode for a partner that does not exist yet.
Create a new workspace
The partner is new. Auris creates the whole space — Keycloak realm, workspace, owner user — registers it as a distributor and emails the first-access link to the contact.
- New Distributor → Create a new workspace
- Name — the partner’s company name
- Realm slug — becomes the name of the workspace and cannot be changed later. Lowercase letters, numbers and hyphens; it must start with a letter
- Contact email — the contact person. Unless you fill in the next field, this is also the owner user of the new workspace and the recipient of the invite
- Sign-in address (if different) — optional. When you fill it in, this one becomes the identity: the Keycloak user, the workspace owner and the recipient of the invite. The contact address above then stays a contact only, stored on the distributor
- Contact first name / last name, Tier, Notes — optional
- Click Create workspace and distributor
Copy the first-access link before you close the panel. The result panel tells you whether the email actually went out, and always shows a First-access link — that link is how you deliver access by hand when the mail does not arrive. It expires 24 hours after it is minted. If you close the panel without copying it, use ⋮ → Resend invite to mint a new one; do not delete and recreate the partner, because the slug is burnt as soon as the workspace exists.
One workspace can be a distributor only once: a second attempt answers That tenant is already a distributor. A slug already used by another workspace answers A tenant with this slug already exists, and a Keycloak realm left behind without its workspace answers A Keycloak realm with this name already exists without a matching tenant.
Contact vs. sign-in address
Two addresses, one identity. This is the distinction that decides where the invite goes.
| Field | What it is | Where it lives |
|---|---|---|
| Sign-in | The identity: the Keycloak user, the workspace owner, the address the invite is sent to and the one the portal authenticates | The workspace, not the distributor |
| Contact | A commercial reference and nothing else. It authenticates nothing and no user exists behind it | The distributor row |
An empty Contact means same as the sign-in address — not unknown. Changing the address a contact signs in with is an operation on the workspace user in Keycloak; it does not happen from the distributor page.
Resend invite
⋮ → Resend invite mints a new first-access link for the partner’s owner and tries to email it. Use it when the first invite did not arrive, or when you closed the panel without copying the link.
- It redoes nothing: realm, workspace, user and configuration already exist. It only mints a link
- The recipient is the active owner of that workspace, not something you choose. There is no field to type an address into, on purpose
- The link comes back whether or not the email went out, because delivering it by hand is exactly why this exists
- This workspace has no active owner (
MEMBERSHIP_NOT_FOUND) or The contact does not exist as a user in the partner workspace (KEYCLOAK_USER_NOT_FOUND) mean the accounts have to be fixed first — the invite is not the problem
Contract reference
From the distributor page, ⋮ → Edit carries Contract reference and Signature date. They are a pointer to the signed contract in the ERP (CON-2026-0001), for people reading the page — no automation reads them.
Edit also carries three fields that are anything but decorative: Contact, Parent in the network and May create sub-distributors. See Sub-distribution below.
Step 2 — Grant the product lines
A grant answers one question: what may this partner sell, and within which ceiling? It is created per line, from the distributor page → Grants → Add Grant.
| Line | What it is | Produces keys |
|---|---|---|
| ERP | Altovar ERP, module by module | Yes |
| TALON | TALON | Yes |
| Cloud | Cloud | Yes |
| Drive | Drive | Yes |
| Menu | Menu | Yes |
| Restaurant | Restaurant | Yes |
| Siti | Client websites | No |
Siti is a service line. Websites are delivered as a project against a contract, so no license key exists for them. Grant the line to record that the partner sells it and to hold its customer quota; the partner will never find it in the issuing form.
Modules — the trap
On the ERP line the grant carries the list of modules the partner may resell.
No module selected means NO restriction. An empty module list on a grant lets the partner sell every ERP module. On a key the same empty list means the opposite — a key with no modules unlocks nothing at all. Same control, two screens, inverted meaning. The grant dialog warns you when you leave everything unchecked; read that warning, it is not decoration.
In practice:
- You want to restrict — tick exactly the modules the partner may sell. Anything they ask for outside that list is refused (
MODULES_NOT_GRANTED), and if they ask for nothing, they get precisely your list, never a full key - You want no restriction — leave every module unchecked
On a sub-distributor, “no restriction” is not available under a restricted parent. An empty
list is the perfect superset, so it is refused with MODULES_NOT_IN_PARENT_GRANT: a child under a
restricted parent must tick a subset, not nothing. The rule above holds only for a direct Altovar
partner. See Sub-distribution.
The other fields
- Max Customers — the customer ceiling for this line. Leave empty for no limit. See below for when it actually bites
- Discount % — the number the partner’s price list is computed from. In its portal, under Price list and margins, the partner sees the list price of every plan on this line, the same price with this discount applied (Your price) and the difference (Your margin). It does not produce an invoice and it does not change a key — but it is not a memo either, so do not park a negotiation figure here
- Active — deactivating a grant stops issuing on that line without deleting it. The partner stops seeing the line entirely: its portal only ever receives the active grants, so an unexplained deactivation reads as a line that vanished
Discount is also a ceiling. A sub-distributor may not be granted more than its parent
(DISCOUNT_EXCEEDS_PARENT), and a parent may not be lowered below a child that already holds that
line (CHILD_GRANT_EXCEEDS). The same goes for Max Customers. For the same reason,
deactivating or deleting a grant is refused while a sub-distributor still holds that line: the
refusal names the children to narrow first.
Each line can hold only one grant, so lines that already have one are not offered again — edit the existing one instead.
Step 3 — Attribute the customers
Customers are attributed by Altovar, never by the partner. A partner does not acquire a
customer by issuing a key for it. Until you attribute a workspace to a channel, every issuing
attempt on that workspace is refused with CUSTOMER_NOT_ATTRIBUTED, and the partner is simply
stuck until you act.
This is deliberate. A key of type tenant with status active is exactly the shape the ERP gate accepts: without this rule, knowing the name of a workspace would be enough to license an Altovar direct customer and walk away with the row claiming it as your own.
From the distributor page → Customers → Add Customer:
- Tenant Realm — the realm of the customer workspace. It must already exist
- Product Line — only lines the partner holds a grant for are listed. If the partner has none, the dialog tells you to add a grant first
- Notes — internal
- Click Add
Attribution is per line
The same customer is attributed once per line. A customer that buys ERP and Cloud from the same partner is two attributions, one for each — and the distributor list still counts it as one customer.
The line decides one thing only: which quota that attribution consumes. It never decides access, so a wrong line costs a slot on the wrong grant and nothing else. Fix it by removing the row and adding it back on the right line.
The quota bites here
Max Customers is enforced when you attribute, not when the partner issues. Attributing one customer over the ceiling of that line is refused; the partner never sees the wall you just hit.
Re-attributing a customer that is already on the same line is idempotent — it does not eat a second slot.
There is one case where the partner meets the ceiling directly: extending an existing customer to a new line. A customer attributed on Cloud, licensed on ERP, becomes a new customer on the ERP quota, and the issuing call books it.
One customer, one channel
A workspace belongs to a single channel. Attributing a customer that already belongs to another distributor is refused with CUSTOMER_ATTRIBUTED_ELSEWHERE — the second channel does not silently win, and the customer does not end up shared.
Handing a customer over to another channel
⋮ → Transfer to another channel, on the customer row. The customer changes partner in one go: no key is revoked or reissued, active keys stay active and only change channel, and the end customer sees no interruption.
The customer moves as a whole, with every line it holds in that channel: the row you clicked is only the handle, there is no per-line transfer.
The destination has to pass the same questions as a fresh attribution — active, holding the line, upstream chain active, and with its customer quota counted as if the customer were joining now. On top of that, the modules of the keys it inherits must fit inside its own grant: they are not silently narrowed, the transfer is refused (MODULES_NOT_GRANTED).
The handover is an act of the registry, and the registry is Altovar’s: it does not exist in the partner portal. A partner neither takes customers away nor gives them away on its own. The audit event is written on both partner tenants — the one losing the customer keeps a trace too.
Removing a customer
⋮ → Remove customer detaches the link. The workspace itself is untouched — it keeps its users, its data and, if you leave them, its keys.
The removal is refused while that customer still holds active or suspended keys in that channel, on any line (CUSTOMER_HAS_KEYS, with the count in the message). Revoke or let those keys expire first, otherwise the channel would keep licensing a customer that, on paper, is not its own.
Step 4 — Issue a key for the partner
You can issue in the partner’s place from the distributor page → Issue Key. The distributor field is pre-filled and locked: the key lands in that channel.
The rest of the form is the ordinary issuing form — policy, licensee, ERP tier, expiry, ERP modules.
The plan is not optional on a channel key
On the ERP line, a key attributed to a distributor has to state the plan being sold. It is not an informative field: that slug is where the two things the product actually reads come from.
| What the plan writes on the key | What happens when it is missing |
|---|---|
| The quotas (users, e-invoices per month) | The customer’s ERP reads no cap: Free and Business become the same thing |
| The modules that plan contains | The ERP turns everything on, paid verticals included — an absent list is fail-open, not “no restriction” |
The plan’s numbers are not to be retouched. The API compares the key’s limits with the
catalogue ones by value: a Starter whose users were pushed from 3 to 5 is no plan at all and is
refused with ERP_CHANNEL_PLAN_REQUIRED — the same code as a missing plan, on an issue where you
did pick one. The dialog tells you before it lets you submit. In direct sales those fields stay editable as
ever: the constraint only concerns keys that carry a distributor.
On a key, no module selected means the key unlocks nothing. This is the inverse of the grant
screen. On a channel key the plan is also the ceiling for modules: at least one has to be
ticked (ERP_CHANNEL_MODULES_REQUIRED) and none may sit outside the chosen plan
(ERP_CHANNEL_MODULES_ABOVE_PLAN). The verticals — hotel, restaurant, POS, e-commerce, field
service, fleet, rental — belong to no plan: they are not sold through the channel.
Nine modules are tickable and sit in no plan, and two of them are not even add-ons. On top of
the seven verticals above there are Archive (dms) and Human Resources (hr): the issuing
dialog offers them — they are sellable ERP modules — but no catalogue tier grants them and, unlike
the verticals, no add-on sells them either. On a channel key they are therefore unobtainable by
any route: a higher plan does not help, and ticking one disables the button. They can only be
issued on a direct sale, where modules have no ceiling. The dialog now says so, naming the
modules you ticked. If they are to become sellable through the channel, that is a catalogue
decision and it is not taken from this screen: raise it with whoever owns the ERP price list.
What is checked and what is not. Attributing a key to a channel from Licensing → Keys
requires the same platform-level permission as the distributor pages, and the same checks on the
customer run from here: it cannot already belong to another channel
(CUSTOMER_ATTRIBUTED_ELSEWHERE), and if it was not attributed yet the row is created here and
spends a slot of the Max Customers ceiling (MAX_CUSTOMERS_REACHED). The ERP plan is mandatory
as above. The grant’s module list is
not: that one lives in the partner issuing path, so from here you can tick a module inside the plan
but outside what that partner is entitled to resell. It is your call, not an oversight; make it
deliberately.
Changing a channel customer’s plan
A customer moving from Starter to Business no longer needs a new key. The plan of a channel ERP key is rewritten in place: same key, same JWT, unchanged status, no interruption for the end customer. Until now the only road was revoke and reissue — an outage on the single most frequent event there is.
The button belongs to the partner, not to you. The operation is a partner API route —
POST /api/partner/distribution/keys/{id}/plan, permission manage:distribution on the partner’s
own space — and it is the partner who performs it on its own customer. In their portal it is
Licenses → ⋮ → Change plan. It does not exist in the Console: there is no equivalent route
here, and the admin issuing route does not measure the grant’s module list (see the box above). If
a partner asks you for an upgrade, send them to their portal.
Everything that holds at issuing time holds here, measured now and not when the key was minted: partner active, upstream chain alive, line erp granted and active, modules inside the intersection of plan and grant. The customer attribution is untouched and no Max Customers slot is consumed: the customer was already there.
| Code | What happened | What to do |
|---|---|---|
KEY_NOT_ERP | A plan change on a key that is not ERP | The plan is a notion of the ERP line only: on the others there is nothing to change |
KEY_NOT_LIVE | The key is revoked or expired | On a dead key there is no service to keep uninterrupted: a new key is needed |
PLAN_MODULES_NOT_GRANTED | The plan and the grant share no module | Widen the grant, or sell a plan the grant covers. A key with no modules would unlock nothing |
MODULES_EMPTY | An empty module list was sent | Omit the field to get the ceiling (plan ∩ grant): an empty list blocks everything |
Sub-distribution
A partner can resell through another partner. The network is a tree: level 1 is a direct Altovar partner, level 2 its sub-distributor, level 3 the last one allowed.
The whole thing follows from one sentence: what a child may do is a subset of what its parent may do. Everything below is that sentence applied.
Who can create a sub-distributor
Nobody by default. The right is a switch on the partner — ⋮ → Edit → May create sub-distributors — and only you can raise it. Turn it on and the partner opens sub-distributors from its own portal, without asking you: it fills in name, identifier and the contact’s email, and Auris creates the child’s workspace and mints its first-access link, which the parent delivers.
You still decide the terms. The child is born with no grant at all and with its own sub-distribution right off, so until you grant it a line it can sell nothing. A parent that could write its own child’s grants would be deciding the discount Altovar earns.
Why three levels
The margin of a parent is the gap between its own discount and its child’s. Every level cuts a slice out of the same discount, on the same list price — and the ERP list starts at 9 EUR per month. A fourth level would have to sit under the third, that is, work at roughly zero margin. The chain stops at three (MAX_DEPTH_EXCEEDED), and the check runs both when a child is created and when you re-parent an existing partner — re-parenting a partner that already has children sinks them too, and that is counted.
What a child grant must respect
When you write a grant on a partner that has a parent, it is checked against the parent’s grant on that same line:
| Rule | Refusal |
|---|---|
| The parent must hold that line, active | LINE_NOT_IN_PARENT_GRANT |
| Modules must be a subset. Under a restricted parent, an empty list is refused: it means no restriction, which is a superset | MODULES_NOT_IN_PARENT_GRANT |
| Discount must be less than or equal to the parent’s | DISCOUNT_EXCEEDS_PARENT |
| The customer cap must not exceed the parent’s. Under a capped parent, no limit is refused for the same reason as the empty module list | MAX_CUSTOMERS_EXCEEDS_PARENT |
The same pact seen from the other side: you cannot narrow, deactivate or delete a parent grant while a child still sits outside the new shape (CHILD_GRANT_EXCEEDS). Nothing is silently pushed down onto the child — a third party signed those terms — so the refusal lists the children to fix first.
Suspension travels down the chain
Suspending or terminating a partner stops every partner below it. The descendants keep their
own ACTIVE status, and yet they can no longer issue, nor suspend or reactivate their customers’
keys, nor grow their own network: they get CHAIN_NOT_ACTIVE. The same happens when you take a
line away from a parent — the child gets LINE_NOT_GRANTED_UPSTREAM on that line.
They will not know which partner it is. The API response identifies the upstream partner, but the partner portal deliberately shows only a distributor above you is suspended or terminated and points them at their account manager. So the call lands on you, from a partner whose own page says active — and this is the one case where their status is not the answer.
No customer key is touched by any of this. The chain gates the commercial act, not the licence already delivered: the end customer bought a product, not a channel, and switching it off over a contract two levels above would punish it for something it knows nothing about.
At issuing time, the modules actually grantable are the intersection along the whole chain. When two restricted lists have nothing in common the line is refused with MODULES_NOT_GRANTED, rather than read as no restriction.
Removing a partner from a chain
Delete is refused while a partner has children (DISTRIBUTOR_HAS_CHILDREN): deleting the parent would promote every child to a direct Altovar partner, because the discount ceiling, the customer cap and the module subset all live on the parent’s row. The way out is Terminate.
Detaching a single partner is deliberate and explicit: ⋮ → Edit → Parent in the network → None. It promotes that partner to direct Altovar — no ceiling above it any more — and leaves an audit trail. Do it knowing that.
Operating licence
Two different rights, and the grants only express the first one:
- A grant says what the partner may sell to its customers. It unlocks nothing on the partner’s own screen
- The operating licence says what the partner may use to work. It is an ordinary ERP licence on the partner’s own workspace
From the distributor page, the Operating licence card grants it and revokes it. The module profile is fixed by the platform and is not chosen here: crm, documents, finance, projects, calendar, subscriptions, products, inventory, billing. Expiry is optional.
It is not a channel sale, and that is deliberate. The key is not attributed to the partner’s channel, so it does not show up among the keys the partner sold, it does not appear in its portal counters, and it does not make a partner that never sold anything undeletable. A partner that also bought ERP as a customer keeps that licence untouched: revoking the operating licence only touches the one granted from here.
Terminate does not switch it off. A terminated partner keeps a working ERP: nothing about a status change touches this key. The partnership ends on paper and the ex-partner keeps using the product. If that is not what you agreed, revoke the operating licence yourself — the status change will not do it for you.
Delete is refused while the licence is live (DISTRIBUTOR_HAS_OPERATING_LICENSE). It is
refused rather than revoked for you, because deleting a registry row must not silently cut off
somebody’s access: revoking is its own act, with its own audit trail. So the order is revoke,
then terminate, then delete.
To change the profile there is no edit: revoke, then grant again. A second grant on top of a live one is refused (OPERATING_LICENSE_EXISTS) so that “the” operating licence stays identifiable.
Suspending, terminating, deleting
From the distributor page, the ⋮ menu:
| Action | Effect |
|---|---|
| Suspend | The partner is blocked until you reactivate it — and so is every partner below it |
| Terminate | The partnership is marked as ended. Same effect downstream. Does not touch the operating licence |
| Delete | Removes the distributor, its grants and its customer links. Refused if the channel holds keys, the partner has children, or it still holds an operating licence |
A distributor that is suspended or terminated cannot issue keys, and cannot suspend or
reactivate the ones it already issued (DISTRIBUTOR_NOT_ACTIVE). Flipping a key is a
commercial act on a live customer, so it needs the same standing as issuing: an ex-partner must
not be able to cut off a customer that is no longer its own.
Keys already issued are not touched by suspending or terminating: existing customers keep working. To cut a specific customer off, act on the key itself.
Delete is refused as soon as the channel holds any key (DISTRIBUTOR_HAS_KEYS), the partner has sub-distributors (DISTRIBUTOR_HAS_CHILDREN), or it still holds an operating licence (DISTRIBUTOR_HAS_OPERATING_LICENSE). The way out of a partnership is Terminate, not delete.
The operating licence is checked separately, and Terminate does not check it at all. That key
is deliberately not attributed to the channel, so it is not part of DISTRIBUTOR_HAS_KEYS — Delete
looks for it on its own. Terminate does not: a terminated partner keeps a live ERP licence
until you revoke it by hand. That is the case nothing will stop for you.
What the partner does alone
At partners.altovar.net the partner sees its agreement and its channel, and — on its own — adds customers (existing workspace or a new one), issues keys for them on granted lines, within the allowed modules, then suspends and reactivates them — and changes the plan of an ERP key it already issued, in place, without cutting the customer off. From a customer row it can generate a site in its own ERP (the operating licence is claimed automatically if it was still missing) or ask Altovar to produce it.
It also reads its price list — but only whoever holds manage:distribution in its space, not every member — and, only if you turned the right on, it creates its own sub-distributors from the My network page.
It cannot move a customer to another channel, change its own grants, raise its ceiling, revoke a key, grant itself the right to sub-distribute, write its children’s grants, re-mint an invite, or see the notes you take about it. Everything on that list comes back to you.
Send partners to the Partner Portal guide.
Permissions
| Permission | Who | What it allows |
|---|---|---|
manage:distributors | Altovar platform administrators | The whole Distributors section: distributors, grants, customers, channel attribution when issuing, the operating licence, Resend invite — and linking an existing workspace |
provision:distributor-tenants | Altovar platform administrators | The Create a new workspace mode only: minting a Keycloak realm, a workspace and an owner invite |
read:distribution | The partner’s own members | Read their own distribution space: agreement, customers, keys and sub-distributors. Not the price list |
manage:distribution | The partner’s own administrators | Issue, suspend, reactivate and change plan inside their own channel, add customers, claim the operating licence, open a site request, read the price list — and, only where canSubdistribute is on, create sub-distributors |
The price list is not a read like the others. read:distribution sits among the permissions
every MEMBER membership holds by construction, and rightly so for the agreement, the customers, the
keys and the network — operational data. The Pricing and margins page is not: it puts the list
price next to the discounted price, which is the margin line by line, which is the commercial
position of the relationship with Altovar. It therefore sits behind manage:distribution, which a
MEMBER does not have and which an administrator of the partner tenant cannot re-grant itself by
composing a custom role either. A member opening that page reads you do not have permission, and
the Pricing entry does not even appear in their sidebar. Granting read:distribution to a
sales contact does not open the price list to them.
Why provision:distributor-tenants is separate. Linking an existing tenant writes a row in a
registry; creating a workspace mints an authentication namespace Auris will serve forever. An
administrator holding only manage:distributors sees the Create a new workspace mode and is
refused when submitting it: You do not have permission to create distributor workspaces. That is
the permission to ask for.
manage:distribution is wider than “issue and suspend”. On a partner whose
canSubdistribute is on, that same permission creates sub-distributors — which means creating
Keycloak realms. Weigh it before granting it to an M2M integration of the partner: the M2M scope
carries exactly the same reach as a portal session.
manage:distributors and provision:distributor-tenants are only ever evaluated against the
Altovar platform workspace. Owning a workspace and being its administrator does not let anyone
manage distributors from inside their own workspace, whatever workspace they ask for.
Messages you may run into
This table is exhaustive by construction, and from now on verifiably so: a check
(apps/docs/scripts/check-distribution-codes.mjs, wired into the docs lint) compares the codes
cited here with the THREE maps that translate them into HTTP responses in the API — the two status
tables plus the one the partner-registration route answers with — in both directions and in both
languages. A new code nobody documents makes the check fail. The third map was added on
2026-09-06, after two of its codes had appeared with no guide naming them and the check had stayed
green: it had the wrong shape to be seen.
| Code | What happened | What to do |
|---|---|---|
TENANT_NOT_FOUND | No workspace with that realm | Create the workspace first, or check the spelling |
DISTRIBUTOR_EXISTS | That workspace is already a distributor | Open the existing one |
TENANT_IS_CHANNEL_CUSTOMER | That workspace is already an attributed customer of a channel, and a channel customer cannot also be a partner | The message names the channel and the line: detach the attribution first (or transfer the customer), then register it as a partner |
SLUG_TAKEN | The slug picked for the new workspace already belongs to another one | Pick another one |
SLUG_INVALID | The slug breaks the rules, or is one of the reserved ones | The message says which rule: length, format, or reserved slug |
REALM_EXISTS | A Keycloak realm with that name already exists without a matching tenant | Pick another slug, or have the orphan realm cleaned up: creation cannot get out of that state on its own |
DISTRIBUTOR_NOT_FOUND | The distributor named does not exist (any more) | Reload the page: someone may have deleted it while you held it open |
CUSTOMER_ATTRIBUTED_ELSEWHERE | The customer belongs to another channel | Detach it from the other channel first, or transfer it |
MAX_CUSTOMERS_REACHED | The ceiling of that line is full | Raise Max Customers on the grant, or free a slot |
MAX_CUSTOMERS_BELOW_CURRENT | You wrote a ceiling below the customers already attributed on that line | The message carries the real count: remove some customers first, or raise the ceiling |
CUSTOMER_HAS_KEYS | The customer still holds live keys in the channel | Revoke or expire them, then remove the attribution |
CUSTOMER_NOT_ATTRIBUTED | The partner tried to issue for a workspace you never attributed | Attribute the customer on that line |
CUSTOMER_NOT_ALLOWED | The target cannot be a channel customer: it is the Altovar platform workspace, or the distributor itself | A partner licenses customers, never itself. For the ERP it uses, see Operating licence |
CUSTOMER_IS_DISTRIBUTOR | The target is another distributor’s workspace | A partner is not a channel customer, not even a sub-distributor: that relationship is expressed with grants |
CUSTOMER_NOT_ACTIVE | The customer workspace is deactivated | Reactivate it if the customer really is still live: attributing or issuing would burn a slot for a tenant Altovar considers closed |
CHANNEL_LICENSEE_MUST_BE_TENANT | You issued with a distributor but a licensee that is not a workspace (user, e-mail, device, organization) | A channel key is always licensed to a workspace: the customer row, the ceiling and “one customer, one channel” are all defined there |
TRANSFER_SAME_DISTRIBUTOR | You transferred a customer to the channel that already holds it | Pick another destination: there is nothing to move |
LINE_NOT_GRANTED | The line has no grant, the grant is inactive, or it is siti. In a transfer it is the destination that lacks it | Add or reactivate the grant — on the receiving side, if you are transferring |
MODULES_NOT_GRANTED | Modules outside the grant were asked for. In a transfer these are the modules of the keys the destination inherits | Widen the receiving grant. Keys are not silently narrowed |
DISTRIBUTOR_NOT_ACTIVE | A suspended or terminated partner tried to issue, to flip a key or to change its plan — or is the destination of a transfer | Reactivate the distributor if the partnership is alive |
DISTRIBUTOR_HAS_KEYS | Delete attempted on a channel that holds keys | Use Terminate |
POLICY_NOT_FOUND | The line is granted and issuable, but its license policy is missing or disabled | A configuration problem on your side, not a partner limit — check the policy for that line |
MODULES_UNKNOWN | A module id the ERP catalogue does not know | Fix the module list; an unknown id would unlock nothing |
EXPIRES_AT_IN_PAST | An expiry already gone by | The customer would receive a dead key. Pick a future date, or none |
The ERP plan of a channel key
| Code | What happened | What to do |
|---|---|---|
ERP_CHANNEL_PLAN_REQUIRED | An ERP key with a distributor and no plan, or with limits that no longer match any catalogue plan | Pick the ERP tier, and leave its numbers as they are |
ERP_CHANNEL_PLAN_MISMATCH | The key states one plan and carries another’s quotas | A key that says Business and is worth Free is worse than one with no plan: make the two agree |
ERP_CHANNEL_MODULES_REQUIRED | No module ticked on a channel key | An absent list turns everything on, an empty one turns nothing on: tick at least one |
ERP_CHANNEL_MODULES_ABOVE_PLAN | Modules outside the chosen plan | The plan is the ceiling. Verticals, dms and hr belong to no plan: they are not sold through the channel, and no higher plan contains them |
Sub-distribution and operating licence
| Code | What happened | What to do |
|---|---|---|
SUBDISTRIBUTION_NOT_ALLOWED | A partner tried to create a sub-distributor without the right | Turn on May create sub-distributors on that partner, if that is the deal |
CHAIN_NOT_ACTIVE | A partner above this one is suspended or terminated | Look upstream: the partner’s own status is fine, its chain is not |
CHAIN_CYCLE | The upstream chain loops back on itself | Nobody’s limit: it is the registry in a state that needs looking at. Report it |
CHAIN_TOO_DEEP | The upstream chain is deeper than the three levels allowed | As above: nobody fixes it by retrying |
SUBDISTRIBUTION_DEPTH_EXCEEDED | You turned on May create sub-distributors for a partner already at the last level | Leave it off: you would be handing over a button that always refuses |
MAX_SUBDISTRIBUTORS_REACHED | A partner already holds the maximum number of children | The message carries the count and the cap: its network does not widen further |
LINE_NOT_GRANTED_UPSTREAM | A partner above this one has no active grant on that line | Restore the line upstream, or drop it downstream |
LINE_NOT_IN_PARENT_GRANT | The child grant names a line the parent does not hold | Grant the parent first |
MODULES_NOT_IN_PARENT_GRANT | The child modules are not a subset — or the list is empty under a restricted parent | Tick a subset. Under a restricted parent, “no restriction” is not available |
DISCOUNT_EXCEEDS_PARENT | The child discount is higher than the parent’s | Lower the child, or raise the parent first |
MAX_CUSTOMERS_EXCEEDS_PARENT | The child cap is above the parent’s, or is no limit under a capped parent | Set a cap at or below the parent’s |
CHILD_GRANT_EXCEEDS | You narrowed, deactivated or deleted a parent grant while children still sit outside it | The message lists the children: narrow them first |
DISTRIBUTOR_HAS_CHILDREN | Delete attempted on a partner that has sub-distributors | Use Terminate, or re-parent the children first |
MAX_DEPTH_EXCEEDED | The chain would go past three levels | Nothing to fix: the network stops at three |
PARENT_SELF | A distributor was set as its own parent | Pick another parent |
PARENT_CYCLE | The chosen parent already sits below this partner | Pick a parent outside this partner’s subtree |
PARENT_NOT_FOUND | The parent no longer exists | Reload the page |
OPERATING_LICENSE_EXISTS | The partner already holds a live operating licence | To change the profile: revoke, then grant again |
OPERATING_LICENSE_NOT_FOUND | Revoke attempted with no operating licence granted | Nothing to revoke |
DISTRIBUTOR_HAS_OPERATING_LICENSE | Delete attempted on a partner whose operating licence is still live | Revoke it from the Operating licence card, then delete |
TRANSACTION_FAILED | The database transaction did not complete while registering a partner, attributing a customer or issuing a key | Nothing was written. Retry — this is not a broken state |
MEMBERSHIP_NOT_FOUND | Resend invite on a workspace with no active owner | Fix the workspace accounts first |
KEYCLOAK_USER_NOT_FOUND | The owner address has no Keycloak user in that realm | Fix the accounts first: sending the link would land it in the wrong realm |
Related
- Licensing Console — policies, keys, seats, devices
- Partner Portal — the guide to hand to your partners
- Software Licensing — validating keys inside a product