Fees
Understand Due transaction fees, application-fee markups and subsidies, validation rules, and monthly invoicing.
Understand how transaction fees are built up, add your own markup or subsidise Due fees, and determine when collected fees appear on your invoice.
The key idea is that fees are additive layers, not competing rules. Every transaction can include up to four components: two channel fees, an FX markup, and an optional application fee that you set. Two validation rules apply only to the application-fee component.
On-chain payouts
All on-chain payouts are free, including cross-chain payouts (bridging assets across networks). Due charges no separate network or withdrawal fee for sending crypto on-chain: an on-chain rail's channel fee is 0 bps and 0 fixed.
For a fiat-to-crypto conversion, the quote can still show a fee on the destination crypto leg. In most cases, this is the source fee restated in the destination currency, not an additional charge. See example 3.
The FX markup is included in fxRate and disclosed separately as fxMarkup. It is not a line-item amount, and the on-chain send itself is free.
Fiat transfers and conversions
Fiat payout, pay-in, and conversion fees vary by payment method, currency, and corridor.
For tailored pricing, book a demo or contact [email protected].
How fees fit together
Every transaction's total cost is the sum of these components:
| Component | What it is | Where it comes from |
|---|---|---|
| Source-channel fee | The inbound (deposit) rail's variable fee, feeBps, plus its fixed fee, feeFixed. | GET /v1/channels, on the source rail |
| Destination-channel fee | The outbound rail's variable fee, feeBps, plus any fixed fee. On-chain rails are free: 0 bps and 0 fixed. | GET /v1/channels, on the destination rail |
| FX markup | The conversion spread in basis points, included in the quoted fxRate. | The quote (fxMarkup) |
| Application fee | An optional fee you set: your markup on top of Due fees, or a subsidy of them. | Your quote, estimate, or virtual-account request (applicationFeeBps, applicationFeeAmount) |
The first three components are Due fees: fixed inputs for a given rail and quote. The application fee is the component you control. The components add together; none overrides another.
Total variable fee (bps) = fxMarkup + source rail feeBps + destination rail feeBps + applicationFeeBps
Total fixed fee = source rail feeFixed + any fixed destination fee + applicationFeeAmountBps means basis points: 100 bps equals 1%, so 10 bps equals 0.1%. Fixed fees (feeFixed and applicationFeeAmount) are never part of the basis-point calculation.
Count each fee once. A fiat-to-crypto quote can restate the source fixed fee in the destination currency on the destination leg. It is the same fee shown in two currencies, not two separate charges. On-chain destination rails add no fixed fee of their own.
Where to set an application fee
Set an application fee on the quote, on a transfer estimate, or on a virtual account.
On a quote or an estimate, add the fields inside the source or destination object, not at the top level of the request body. A fee placed at the top level is ignored silently.
{
"source": {
"rail": "sepa",
"currency": "EUR",
"amount": "200",
"applicationFeeAmount": 1
},
"destination": {
"rail": "base-sepolia",
"currency": "USDC"
}
}Three constraints apply:
- One side only: Set the fee on either
sourceordestination, never both. Setting both returnserr_quote_application_fee_one_side_only. - Platforms only: Application fees are available to platform accounts. Other accounts receive
err_quote_application_fee_outside_platform. - Subsidies cannot exceed Due's fee: A negative application fee may offset Due's fee in full but not beyond it. An excess subsidy returns
err_quote_application_fee_exceeds_internal_fee.
You do not need to pass the fee again when creating the transfer. The quote response includes a signed token that carries the application fee, and the transfer created from that token applies it.
Reading a fee response
Each side of a quote or estimate returns three fee fields.
| Field | Meaning |
|---|---|
fee | The Due channel fee for that rail, in that side's currency. |
applicationFee | Your application fee, in that side's currency. Returned only on the side where you set it. |
totalFee | The sum of fee and applicationFee for that side, in that side's currency. |
Handle these response behaviours:
- Missing application fee:
applicationFeeis omitted when there is none; it is not returned as"0". Treat a missing field as zero. - Restated opposite leg: On a conversion, the destination
feeandtotalFeerestate the source figures in the destination currency. They do not add new fees, so never add the two legs together. Count each fee once.
The FX markup is not a fee field. It is contained in fxRate and disclosed separately as fxMarkup in basis points.
Application fees: markup and subsidy
Use applicationFeeBps and applicationFeeAmount to add your own markup to Due’s fees, or to subsidise them in full or in part, including the FX markup.
- Add a markup: Use positive values. They stack on top of Due’s fees.
- Subsidise: Use negative values. They reduce or fully cover Due’s fees.
A subsidy can cover Due’s fee in full but never exceed it. How this is validated depends on where you set the application fee.
Virtual accounts
The variable and fixed parts are validated separately.
Variable fee. The combined variable fee can’t be negative:
fxMarkup + source rail feeBps + destination rail feeBps + applicationFeeBps >= 0A negative applicationFeeBps can offset Due’s variable fees in full, as long as the combined variable fee is at least 0.
Fixed fee. A negative applicationFeeAmount can offset the source rail’s feeFixed in full but not exceed it. Against a feeFixed of 1.50, applicationFeeAmount: -1.50 is valid and -1.51 is rejected.
Transfer quotes
The total subsidy, combining applicationFeeAmount and the amount implied by applicationFeeBps, can’t be greater than Due’s fee on that transfer. If Due’s fee is $5, a total subsidy of $3 or $5 is valid. A total subsidy of $6 is rejected with err_quote_application_fee_exceeds_internal_fee.
Which side to set the fee on
Set the application fee on the side whose fee you want to offset:
- Pay-in fees are charged on
source, in the source currency. - Payout fees are charged on
destination, in the payout currency. For example, an ACH payout’s fixed fee is in USD on the destination leg.
A subsidy on the same side as the fee offsets it exactly. A subsidy on the other side is converted at the quote’s rate and may not match the fee.
Subsidising fees in full
To cover fees in full without hardcoding values:
- Read
feeBpsandfeeFixedfor each rail fromGET /v1/channels. It returns your platform’s own rates. - Set
applicationFeeBpsandapplicationFeeAmountto the negatives of those values. - To also cover the FX markup, add the quote’s
fxMarkupto the negativeapplicationFeeBps.
Your application fees then follow your rates automatically if they change.
Example: an ACH rail at 20 bps + USD 1.50, with no FX markup
| Flow | Where to set it | Values |
|---|---|---|
| Pay-in to a virtual account | The virtual account | applicationFeeBps: -20, applicationFeeAmount: -1.50 |
| Payout (USDC → USD ACH) | destination on the quote | applicationFeeBps: -20, applicationFeeAmount: -1.50 |
The end user receives the full amount, and the subsidised fees are billed to you (see Fee invoicing).
Worked examples
1. Find the source-channel fee from the rail
This ACH rail accepts USD deposits with feeBps of 20. Its feeFixed of 1.5 is a separate fixed fee and is not part of the basis-point calculation.
{
"rail": "ach",
"currencyCode": "USD",
"feeBps": 20,
"feeFixed": "1.5",
"type": "static_deposit",
"accountType": "business",
"railSettings": {
"rail": "ach",
"speed": "1-2 days",
"schemas": ["bank_us"]
}
}Therefore, the source rail's feeBps is 20 and its fixed fee is $1.50.
2. Calculate the combined variable fee for a virtual account
With fxMarkup = 10, source rail feeBps = 20, destination rail feeBps = 5, and applicationFeeBps = -10:
fxMarkup: 10 bps
Source rail feeBps: 20 bps
Destination rail feeBps: 5 bps
applicationFeeBps: -10 bps
---------------------------------
Combined variable fee: 25 bps (0.25%)10 + 20 + 5 - 10 = 25. The negative applicationFeeBps offsets 10 bps of the other components. This is valid because the combined variable fee is at least 0.
3. Read a quote against the model (SEPA to Base)
{
"source": {
"rail": "sepa",
"currency": "EUR",
"amount": "200",
"fee": "0.9"
},
"destination": {
"rail": "base",
"currency": "USDC",
"amount": "229.410275",
"fee": "1.037013"
},
"fxRate": 0.86787743028,
"fxMarkup": 20
}Map this quote to the fee components:
- The source rail's
feeBpsis0; itsfeeFixedis€0.90, shown assource.fee. fxMarkupis20bps. It is included infxRateand disclosed separately, not as a line-item amount.- The destination rail's
feeBpsis0with no fixed Base fee. Base is a free on-chain rail. Thedestination.feeof1.037013USDC is the€0.90source fee restated in USDC, not an extra charge. - No application fee was set, so
applicationFeeis omitted.
0.90 ÷ 0.86787743028 = 1.037013 (the €0.90 source fee, in USDC)
200 ÷ 0.86787743028 = 230.447288 (gross conversion of the full deposit)
230.447288 − 1.037013 = 229.410275 (= destination.amount, the net USDC delivered)The combined variable fee is 0 + 20 + 0 + 0 = 20 bps, which is valid. The only cash fee on the transaction is the single €0.90 SEPA fee, shown as €0.90 on the source leg and 1.037013 USDC on the destination leg. Count it once.
4. Quote with an application fee
Send a quote request with applicationFeeAmount inside one side of the request. This example adds a €1.00 application fee to the source side.
POST /v1/transfers/quote
{
"source": {
"rail": "sepa",
"currency": "EUR",
"amount": "200",
"applicationFeeAmount": 1
},
"destination": {
"rail": "base",
"currency": "USDC"
}
}The response returns the channel fee, application fee, and total fee on the source. The destination restates the channel and total fees in USDC.
{
"source": {
"rail": "sepa",
"currency": "EUR",
"amount": "200",
"fee": "0.9",
"applicationFee": "1",
"totalFee": "1.9"
},
"destination": {
"rail": "base",
"currency": "USDC",
"amount": "226.82637",
"fee": "1.030509",
"totalFee": "2.175518"
},
"fxRate": 0.8733552440400001,
"fxMarkup": 20,
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
}Reconcile the response line by line:
Source channel fee (SEPA feeFixed) 0.90 EUR
Application fee (yours) 1.00 EUR
--------
source.totalFee 1.90 EUR
200.00 - 1.90 = 198.10 EUR net amount converted
198.10 / 0.8733552440400001 = 226.82637 = destination.amount
0.90 / 0.8733552440400001 = 1.030509 = destination.fee (restated)
1.90 / 0.8733552440400001 = 2.175518 = destination.totalFee (restated)Both fees are deducted from the source before conversion. The destination figures are the same two fees expressed in USDC, not additional charges. Base is a free on-chain rail, so it adds no fee of its own. The 20 bps FX markup is already inside fxRate.
5. Combine a BPS and fixed application fee
applicationFeeBps and applicationFeeAmount are independent components and combine. Neither overrides the other, and both are optional.
POST /v1/transfers/quote
{
"source": {
"rail": "tron",
"currency": "USDT",
"amount": "100",
"channelType": "static_deposit",
"applicationFeeBps": 7,
"applicationFeeAmount": 1
},
"destination": {
"rail": "mena_local",
"currency": "AED"
}
}{
"source": {
"rail": "tron",
"currency": "USDT",
"amount": "100",
"fee": "0",
"applicationFee": "1.07",
"totalFee": "1.07"
},
"destination": {
"rail": "mena_local",
"currency": "AED",
"amount": "361.87",
"fee": "0",
"totalFee": "3.92"
},
"fxRate": 0.2733832539142274,
"fxMarkup": 40
}7 bps of 100 USDT = 0.07
applicationFeeAmount = 1.00
------
applicationFee = 1.07 USDT6. Subsidise Due fees
Use negative values to offset Due's markup.
- Virtual account: If
fxMarkup + source rail feeBps + destination rail feeBps = 20, thenapplicationFeeBps: -10produces a combined fee of10bps and is accepted.applicationFeeBps: -30produces-10bps and is rejected because a virtual account's combined variable fee cannot be negative. - Transfer quote: If Due's fee is
$5,applicationFeeAmount: -2plus a$1subsidy fromapplicationFeeBpsproduces a$3total subsidy. This is valid because it does not exceed Due's$5fee. A$6total subsidy is not valid.
Fee invoicing
Application fees are settled at the end of each month on your invoice:
- Markups you add are credited to you.
- Subsidies are billed to you as a separate line.
For questions about your invoice or the commercial terms of your agreement, contact your account manager.
Updated 4 days ago