Fees Overview
A fee is a set of percentage rates that one party charges on the platform's operations. This page explains who charges a fee, the scopes a fee can be written at, how the rate that applies to a setup is resolved, and when a change reaches the chain. The endpoint pages in this section link back here.
Who charges a fee: entity
Every fee row belongs to one entity. The three entities are priced independently, so every read and write names one of them.
entity | Name | Written over this API by |
|---|---|---|
1 | Owner | Nobody. Owner fees are authored on the owner side and mirrored here; they are read-only over this API (10004, domain 9). |
2 | Platform owner | The platform owner node's own API key only (10003, domain 9, for every other key). |
3 | Node | An API key whose node subtree covers the node. |
What a fee prices: the nine fee types
A fee value holds nine rates in three groups. Each rate is a leaf object whose value is a percentage.
| Group | Leaf keys |
|---|---|
tokenization | asset_tokenization, tokenized_asset_sales, management |
secondary_market | buy_order, sell_order, otc_sale |
lending | borrower, lending, liquidation |
- A rate is a decimal string from
"0"to"100"with at most one decimal:"2.5"is accepted,"2.55"and"100.5"are refused with10015. See Amounts and Percentages. - Every write must send all nine leaves in
value. A body that leaves one out is refused with10002(domain9). - A write may also send
categories: per-asset-category overrides of the same nine rates. An override given on a parent category is expanded to that category's leaf categories; a leaf category listed on its own keeps its own value.
Where a fee applies: scopes
Each fee row is written at exactly one scope. From most specific to least:
| Level | Scope | Meaning |
|---|---|---|
| 1 | setup | One deployed (or to-be-deployed) setup of a node |
| 2 | node + network | One node, on one network |
| 3 | node | One node, on every network |
| 4 | network | Every node, on one network |
| 5 | default | The entity-wide default |
The scope is fixed when the row is written and never changes afterwards: Update Fee by ID keeps the stored scope whatever the body says.
How the effective fee is resolved
To find what an entity charges on a setup, the server walks the five levels from the most specific to the least, for that entity only. Each level fills only the leaves that the more specific levels left unset, so a partial row at one level is completed by the levels below it. A level whose axis is unknown is skipped (for example, without a network the node + network and network levels are skipped). When an asset category is given, a row's override for that category is used in place of the row's value. A leaf that no level prices stays unset.
- Get Effective Fee runs this resolution live for any scope, including scopes with no deployment yet. Use it to preview a change.
- Get Setup Effective Fees returns what a deployed setup's fee contract holds: the values resolved when they were last pushed, with the level and fee row each leaf came from, and whether that push is
pending,confirmedorfailed.
When a setup's contracts are deployed, its fees are resolved for all three entities and that snapshot is recorded as the setup's effective fees.
Which endpoint writes which scope
| Endpoint | entity | Scope written | Who may call |
|---|---|---|---|
PUT /v2/admin/fees/platform-owner | 2 | default | Platform owner key |
PUT /v2/admin/fees/nodes/{node_id} | 3 | node, or node + network when the body has network_id | Key whose subtree covers the node |
PUT /v2/admin/fees/nodes/{node_id}/platform-owner | 2 | node, or node + network when the body has network_id | Platform owner key |
PUT /v2/admin/fees/nodes/{node_id}/setups/{setup_id} | 3 | setup | Key whose subtree covers the node |
PUT /v2/admin/fees/nodes/{node_id}/setups/{setup_id}/platform-owner | 2 | setup | Platform owner key |
PUT /v2/admin/fees/{fee_id} | the row's own | the row's own | Node rows: key whose subtree covers the node. Platform owner rows: platform owner key. Owner rows: nobody. |
Rows at other scopes (an owner's defaults, a network-only row) can be read here but not written.
When a change goes on-chain
Every write answers 200 with the saved fee row as soon as it is stored. Reaching the chain is a separate, asynchronous step that runs as node transactions; poll them with Get Node Transactions until they reach status 3 (Done) or 4 (Error).
Setup-scoped writes (the two PUT .../setups/{setup_id} endpoints) push straight to that one setup:
- If the setup is deployed and the rates changed (or this is the setup's first override), one node transaction is started: type
10(UpdateDefaultNodeFee) on the setup's node for a node fee, or type12(UpdateDefaultNodeFeeByPlatformOwner) on the platform owner's node for a platform-owner fee. - If the setup is not deployed yet, the row is only saved. The deploy picks it up.
- A change to
categoriesalone does not start a push.
Update Fee by ID on a setup row also pushes straight to that setup when it is deployed and the rates or categories changed, as one node transaction of type 10 on the setup's node.
Node and node + network writes (PUT /fees/nodes/{node_id}, PUT /fees/nodes/{node_id}/platform-owner, and Update Fee by ID on such a row) are inherited by every setup without an override of its own, so they are fanned out in the background:
- Every deployed setup in the row's scope is re-resolved. A setup whose resolved rates changed gets a value push and its effective fees are marked
pendinguntil the push settles. - A change to
categoriesadds a category push for each setup in scope. - Node fees run as types
10/11/20/21(UpdateDefaultNodeFee,UpdateCategoryNodeFee,UnsetDefaultNodeFee,UnsetCategoryNodeFee) on each setup's node. Platform-owner fees run as types12/13/22/23(the…ByPlatformOwnervariants) on the platform owner's node. - Call Get Affected Setups Count first to see how many deployed setups a change will reach.
The platform owner's default (PUT /v2/admin/fees/platform-owner) is saved but not pushed to setups that are already deployed: the fan-out skips platform-owner rows that carry no node. Setups deployed afterwards resolve it at deploy time.
Owner fees (entity 1) are never written or pushed through this API.