Before creating a transaction fee model, ensure the following:
- To create fee models, you must have active Upvest API client credentials with the required
transaction_fees:adminscopes enabled. - You have determined the exact structure of the fees, your desired tier thresholds and whether the fees will be absolute (fixed cash amounts) or relative (basis points of order value).
Use POST /transaction_fees/models to define your fee model. Fee models are immutable once created. You can create multiple fee models.
Applies a simple flat fee per transaction regardless of the order value.
Example: 1 EUR fee per order
POST /transaction_fees/models
{
"label": "absolute fee amount - 1 EUR per any order",
"currency": "EUR",
"charge_method": "COLLECTED_BY_UPVEST",
"value_type": "ABSOLUTE",
"application_type": "VOLUME",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0.00",
"fee_amount": "1.00"
}
]
}
The example below uses a tiered absolute fee to reward high-volume users with lower effective rates.
Example tier structure for absolute fees:
| Tier | Thresholds (e.g., the order’s cash amount) | Transaction fee |
|---|---|---|
| 0 | Up to €499.99 | €1.00 |
| 1 | €500.00 – €1,999.99 | €2.00 |
| 2 | €2,000.00 – €9,999.99 | €5.00 |
| 3 | €10,000 and above | €10.00 |
POST /transaction_fees/models
{
"label": "absolute fee amount - tiered fee model",
"currency": "EUR",
"charge_method": "COLLECTED_BY_UPVEST",
"value_type": "ABSOLUTE",
"application_type": "VOLUME",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0",
"fee_amount": "1.00"
},
{
"tier_id": "1",
"base_amount_from": "500.00",
"fee_amount": "2.00"
},
{
"tier_id": "2",
"base_amount_from": "2000.00",
"fee_amount": "5.00"
},
{
"tier_id": "3",
"base_amount_from": "10000.00",
"fee_amount": "10.00"
}
]
}Applies a simple flat fee percentage regardless of the order value.
Example: 1 % fee per order
POST /transaction_fees/models
{
"label": "1% transaction fee",
"currency": "EUR",
"charge_method": "COLLECTED_BY_UPVEST",
"value_type": "RELATIVE",
"application_type": "VOLUME",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0.00",
"fee_bps": "100"
}
]
}Applies a flat fee percentage with minimum and maximum fee amount.
Example: 1 % fee per order, not less than 1 EUR, not more than 100 EUR.
POST /transaction_fees/models
{
"label": "1% transaction fee, min 1 EUR, max 100 EUR",
"currency": "EUR",
"charge_method": "COLLECTED_BY_UPVEST",
"value_type": "RELATIVE",
"application_type": "VOLUME",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0.00",
"fee_bps": "100",
"min_fee_amount":"1.00",
"max_fee_amount":"100.00"
}
]
}
Depending on the order volume, each next EUR is charged less fee than the previous.
Example:
| Tier | Thresholds (e.g., the order’s cash amount) | Fee basis point (bps) |
|---|---|---|
| 0 | First €5000.00 of the order volume | 300 |
| 1 | Amount exceeding €5000.00, but less than €10000.00 | 250 |
| 2 | Amount exceeding € 10.000.00 | 200 |
POST /transaction_fees/models
{
"label": "Marginal relative tiered fee model",
"currency": "EUR",
"charge_method": "CHARGED_BY_CLIENT",
"value_type": "RELATIVE",
"application_type": "MARGINAL",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0.00",
"fee_bps": "300"
},
{
"tier_id": "1",
"base_amount_from": "5000.00",
"fee_bps": "250"
},
{
"tier_id": "2",
"base_amount_from": "10000.00",
"fee_bps": "200"
}
]
}
Example:
| Tier | Thresholds (e.g., the total order’s cash amount) | Fee basis point (bps) | Fee limits |
|---|---|---|---|
| 0 | Up to €4999.99 | 300 | Min: 1 |
| 1 | €5000.00 – €9.999,99 | 250- | Min: 150 |
| 2 | 10.000.00 and above | 200 | Min: 250 Max: 300 |
POST /transaction_fees/models
{
"label": "Tiered relative fee model with lower/upper bounds",
"currency": "EUR",
"charge_method": "CHARGED_BY_CLIENT",
"value_type": "RELATIVE",
"application_type": "VOLUME",
"base_amount_scope": "ORDER",
"tiers": [
{
"tier_id": "0",
"base_amount_from": "0.00",
"fee_bps": "300",
"min_fee_amount":"1.00"
},
{
"tier_id": "1",
"base_amount_from": "5000.00",
"fee_bps": "250",
"min_fee_amount": "150.00"
},
{
"tier_id": "2",
"base_amount_from": "10000.00",
"fee_bps": "200",
"min_fee_amount": "250.00",
"max_fee_amount": "300.00"
}
]
}
| Field | Required | Description |
|---|---|---|
label | Required | A human-readable name for the fee model. The label should be unique, descriptive, and clear to aid in referencing the transaction fee model. |
currency | Required | The currency of the fee. Alphabetic three-letter ISO 4217 currency code. This field accepts either EUR or GBP. |
charge_method | Required | This field determines which party collects the fee. The value of this field depends on the funding arrangement you have with Upvest. For pre-funding clients, always set charge_method equal to CHARGED_BY_UPVEST. For post-trade settlement clients, always set charge_method equal to CHARGED_BY_CLIENT. |
value_type | Required | The value_type field determines the type of fee to be collected. Set this equal to either: - ABSOLUTE for fixed, flat cash fees. - RELATIVE for basis-point-based fees. |
application_type | Required | Determines how the fee will be applied to the transaction. - VOLUME: the full order value is assessed against the tier thresholds. The fee in the tiers is applied to the total volume of the order. - MARGINAL: each portion of the order value is charged at the rate of the tier it falls within. Use this to set up a marginal/progressive fee structure. Only applicable to tiered fee models. |
base_amount_scope | Required | Set this field equal to ORDER. Specifies that fee tiers are evaluated against the total order value. |
tiers | Required | Array of tier objects. At least one tier must be specified. A single-tier model functions as a simple flat fee. |
tiers[].tier_id | Required | A string identifier for the tier (e.g. "0", "1", "2"). |
tiers[].base_amount_from | Required | The lower boundary (inclusive) of the tier. The first tier must always start at "0". |
tiers[].fee_amount | Conditional | Required for ABSOLUTE models. The fixed, flat fee amount charged when the order falls within this tier. |
tiers[].fee_bps | Conditional | Required for RELATIVE models. The fee rate in basis points applied to the order value for this tier. |
tiers[].min_fee_amount | Optional | Minimum fee amount for a RELATIVE tier. The calculated fee will not fall below this value. |
tiers[].max_fee_amount | Optional | Maximum fee amount for a RELATIVE tier. The calculated fee will not exceed this value. |
Once you have created a fee model, the response returns an id. This is the transaction_fee_model_id for use in order requests and ex-ante cost reports.
For ex-ante reporting, you can use the POST /reports endpoint to include your transaction fee model in the reporting.
POST /reports
{
"type": "ORDER_EX_ANTE_COST",
"order": {
"user_id": "d1a4be99-8bb6-4e78-b897-8168f6823ab5",
"account_id": "c5034305-c441-4711-adbf-93cfbc13a695",
"order_type": "MARKET",
"side": "BUY",
"instrument_id": "LU0274208692",
"instrument_id_type": "ISIN",
"currency": "EUR",
"quantity": "15"
},
"fees": [
{
"type": "TRANSACTION_FEE_BUY",
"transaction_fee_model_id": "eb5ba93f-5dfe-4bf1-84da-0caacc80c000"
},
{
"type": "TRANSACTION_FEE_SELL",
"value_type": "ABSOLUTE",
"cash_amount": "0.95",
"currency": "EUR"
},
{
"type": "ANNUAL_AUM_BASED_FEE",
"value_type": "RELATIVE",
"bps": "37"
}
],
"inducements": [
{
"value_type": "ABSOLUTE",
"cash_amount": "0.10",
"currency": "EUR"
}
]
}When placing an order, reference your transaction_fee_model_id in the fee_configuration array. Upvest will calculate and apply the appropriate fee based on the order value and the configured tiers.
If no fee model is assigned and an explicit fee is instead provided via fee_configuration, the explicit fee takes precedence.
POST /orders
{
"user_id": "2dedfeb0-58cd-44f2-ae08-0e41fe0413d9",
"account_id": "debf2026-f2da-4ff0-bb84-92e45babb1e3",
"cash_amount": "1000",
"currency": "EUR",
"side": "BUY",
"instrument_id": "US0378331005",
"instrument_id_type": "ISIN",
"order_type": "MARKET",
"user_instrument_fit_acknowledgement": true,
"limit_price": "",
"stop_price": "",
"fee_configuration": [
{
"type": "TRANSACTION_FEE_BUY",
"transaction_fee_model_id": "eb5ba93f-5dfe-4bf1-84da-0caacc80c000"
}
]
}The fee_configuration.type must match the type of order:
- Set
TRANSACTION_FEE_BUYfee type for BUY orders - Set
TRANSACTION_FEE_SELLfee type for SELL orders.
If there is a mismatch, the order will be rejected.
After an order with a transaction fee is executed, fees are reflected in the CASH_TRANSACTION.EXECUTED webhook events. The fees array is populated with the fee details.
The value reflected in the delta field is dependent on your funding setup with Upvest.
- Pre-funding clients: The
deltareflects the net cash movement inclusive of both taxes and fees. - Post-trade settlement clients: The
deltareflects the net cash movement for the order inclusive of taxes but does not include the impact of the fee.
For more information, refer to the Webhooks and transaction fee details section.
The order event webhook includes the transaction_fee_model_id but not a detailed breakdown of the transaction fee. Also, order execution events do not include details on transaction fees.