> For the complete documentation index, see [llms.txt](https://docs-swap.crypto-chief.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-swap.crypto-chief.com/getting-started/partner-fees.md).

# Partner Fees

## Partner Fees

`fee_bps` and `fee_recipient` on [`POST /v1/quote`](/api-reference/quote.md) and [`POST /v1/build`](/api-reference/build.md) withhold a share of the swap's output to a partner — you. The fee is taken **on chain, inside the swap transaction**: the output token arrives split between the recipient and the fee receiver.

`fee_bps` is the share in basis points (1 bps = 0.01 %). `fee_recipient` is where it goes. `fee_bps` without `fee_recipient` is `400 INVALID_REQUEST` (`fee_recipient is required with fee_bps`). On Solana, TON and XRP Ledger, `fee_recipient` without `fee_bps` is also `400 INVALID_REQUEST` (`fee_bps is required with fee_recipient`). `fee_bps: 0` means no fee.

The fee shows in `fees.service` as `{bps, amount, token}`, with `amount` in the output token's base units:

```json
{
  "service": {"bps": 25, "amount": "441481", "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"}
}
```

{% hint style="warning" %}
**`amount_out`, `amount_out_min` and `net_amount_out` are after the fee** — they are what the recipient actually gets. The amounts in `route` and `fees.pools` are **before** it. The sum of the `route` outputs minus `amount_out` is the fee.
{% endhint %}

### Where fees are available

| Family     | Mechanism                                                   | Limit     | Available |
| ---------- | ----------------------------------------------------------- | --------- | --------- |
| Solana     | Jupiter platform fee, paid to the recipient's token account | ≤ 300 bps | Yes       |
| TON        | STON.fi v2 referral fee into the recipient's referral vault | ≤ 100 bps | Yes       |
| XRP Ledger | A second `Payment` inside a `Batch` transaction (XLS-56)    | ≤ 300 bps | Yes       |
| EVM        | —                                                           | —         | **No**    |
| TRON       | —                                                           | —         | **No**    |

{% hint style="warning" %}
**On EVM networks and TRON, partner fees are not available.** A quote or build with `fee_bps` there is refused:

```json
{
  "error": "INVALID_REQUEST",
  "message": "fee is not supported on ETH_MAINNET by oneinch_v6, sushi_rp5, dex_router: partner fees need the Crypto Chief router (cc_router), which is not deployed on this network"
}
```

{% endhint %}

Above the family limit the request is a `400 INVALID_REQUEST`.

### Solana

The fee is Jupiter's platform fee, paid by the Jupiter program into the **fee account**: the associated token account of `fee_recipient` for the output token — for SOL output, its wSOL account.

The fee account must exist, be initialized and not be frozen; otherwise the request is `400 INVALID_REQUEST` naming the account. `fee_recipient` equal to `from_address` is rejected. And if the simulation shows the fee account received more than `fee_bps` of the output, the build is `422 SIMULATION_FAILED`.

### TON

`fee_recipient` is a basechain address, raw (`0:…`) or user-friendly (`EQ…` / `UQ…`), and not the zero address (`fee_recipient is not a TON address`, `fee_recipient must not be the zero address`).

The fee is STON.fi v2's referral fee on the last hop. It **accrues in the referral vault** owned by `fee_recipient` — one vault per token — and is withdrawn from there with `withdraw_fee`. It does not arrive with the swap's output messages.

Two consequences:

* With a fee, routes run through STON.fi only — DeDust has no on-chain partner fee. If no source can pay, the request is `400 INVALID_REQUEST`: `fee is not supported on TON_MAINNET by stonfi_v2 (referral fee is at most 100 bps), dedust (no on-chain partner fee)`.
* `fees.network.details.dex_gas` includes 0.015 TON for the vault deposit.

### XRP Ledger

The swap becomes a `Batch` transaction (XLS-56) of two inner payments: the swap (a `Payment` to yourself) and the fee payment to `fee_recipient`. A `Batch` applies **both** inner payments or none, and its own result does not show them — check both inner transactions in the validated ledger. The wallet must support XLS-56.

The recipient is checked against the ledger. The request is `400 INVALID_REQUEST` when:

* the account does not exist (a fee in XRP below the account reserve does not create it);
* it has DepositAuth or RequireDest set;
* its trust line for the output currency is missing, deep-frozen, not authorized by the issuer, or full;
* it is an X-address, or equals `from_address`;
* the output issuer holds NoRipple on its side of the trust lines of both the recipient and `from_address` — including the line a `trust_set` step would create when the issuer has no DefaultRipple. Without `from_address`, the quote warns instead of refusing.

The executor `xrpl_batch` exists only for fees: `executors: ["xrpl_batch"]` without `fee_bps` is `503 EXECUTOR_UNAVAILABLE`. Excluding it, or the BatchV1\_1 amendment being off, makes fee requests `400 INVALID_REQUEST`: `fee is not supported on XRP_MAINNET by xrpl_payment (a Payment has a single destination), xrpl_batch (<reason>)`.

A `Batch` cannot be simulated: the build simulates the solo swap `Payment` and checks the fee payment against the recipient's account. The issuer's transfer fee on the fee payment shows in `fees.other` as `issuer_transfer_fee_partner`; the network fee of the `Batch` in `fees.network.details.batch_fee_drops`.

### Checking the fee arrived

* Solana, TON: the fee account's or vault's balance.
* XRP Ledger: the second inner `Payment` of the validated `Batch`.
* Everywhere: `fees.service.amount` of the build is what the fee comes to in the output token's base units.
