Skip to content

Commit 178cdf6

Browse files
committed
update multi-fee support guide
1 parent 32e53eb commit 178cdf6

1 file changed

Lines changed: 40 additions & 34 deletions

File tree

fern/docs/pages/0x-swap-api/additional-topics/multi-fee-support.mdx

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ The Swap and Gasless APIs support collecting fees for **multiple recipients in a
77

88
## Overview
99

10-
Both `swapFeeRecipient` and `swapFeeBps` accept **comma-separated lists**, allowing you to define multiple fee recipients, each with their own fee rate.
10+
Fee splitting is controlled by three query parameters that work together:
1111

12-
Each fee is:
12+
- `swapFeeRecipient` — one or more wallet addresses (comma-separated) that receive fees at settlement
13+
- `swapFeeBps` — one or more fee amounts in basis points (comma-separated), defining how much each recipient earns
14+
- `swapFeeToken` _(optional)_ — the token fees are collected in; if omitted, typically defaults to the buy token, unless the sell token has higher priority (e.g., stablecoins or more liquid assets) or the buy token is ineligible.
1315

14-
- Collected in the `swapFeeToken` (the buy token by default)
15-
- Delivered directly to the specified recipient address
16-
- Reported individually in the response under `fees.integratorFees`
16+
`swapFeeRecipient` and `swapFeeBps` are positionally matched and co-dependent. The first value in `swapFeeBps` applies to the first address in `swapFeeRecipient`, the second to the second, and so on. Both must be present and the same length.
17+
18+
By default, each fee is collected in the buy token and delivered directly to the specified address at settlement. You can optionally collect fees in a different token by specifying `swapFeeToken`, as long as each value is set to either the address of the `buyToken` or `sellToken`.
1719

1820
## Parameters
1921

@@ -35,16 +37,30 @@ When providing multiple values, the list must be the same length as `swapFeeReci
3537

3638
</ParamField>
3739

40+
<ParamField query="swapFeeToken" type="string" optional>
41+
The contract address of the token to collect trading fees in. Accepts a single address or multiple comma-separated addresses.
42+
43+
**Format:** `^\s*0x(?!0{40})[a-fA-F0-9]{40}(\s*,\s*0x(?!0{40})[a-fA-F0-9]{40})*\s*$`
44+
45+
Each value must be set to either the address of the `buyToken` or the `sellToken`. When multiple values are provided, the list must be the same length as `swapFeeBps`.
46+
47+
If omitted, 0x selects the fee token from the trade. The buy token is used by default unless the sell token has higher priority (e.g., stablecoins or more liquid assets) or the buy token is ineligible.
48+
49+
You must also specify `swapFeeRecipient` and `swapFeeBps` to use this parameter.
50+
51+
</ParamField>
52+
3853
<Note>
3954
`swapFeeRecipient` and `swapFeeBps` are co-dependent — you must specify both
4055
together. When using multiple fees, both lists must be the same length and
4156
positionally matched (index 0 of `swapFeeBps` applies to index 0 of
42-
`swapFeeRecipient`, and so on).
57+
`swapFeeRecipient`, and so on). `swapFeeToken` must also match this length
58+
when multiple values are provided.
4359
</Note>
4460

4561
## Example Request
4662

47-
The following examples split fees between two recipient addresses — 5 Bps to `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045` and 10 Bps to `0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359`.
63+
The following example splits fees between two recipients on a USDC → USDT swap — 5 Bps to the platform and 10 Bps to a distribution partner. `swapFeeToken` is omitted, so fees default to the buy token (USDT).
4864

4965
<CodeGroup>
5066

@@ -55,26 +71,24 @@ curl "https://api.0x.org/swap/allowance-holder/price\
5571
&sellToken=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\
5672
&sellAmount=100000000\
5773
&taker=0x70a9f34f9b34c64957b9c401a97bfed35b95049e\
58-
&swapFeeRecipient=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045,0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359\
74+
&swapFeeRecipient=0xPLATFORM_ADDRESS,0xPARTNER_ADDRESS\
5975
&swapFeeBps=5,10" \
6076
-H "0x-api-key: <YOUR_API_KEY>"
6177
```
6278

6379
```typescript TypeScript
64-
const feeRecipients = [
65-
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
66-
"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359",
67-
];
68-
const feeBps = [5, 10];
69-
7080
const params = new URLSearchParams({
7181
chainId: "1",
7282
buyToken: "0xdac17f958d2ee523a2206206994597c13d831ec7",
7383
sellToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
7484
sellAmount: "100000000",
7585
taker: "0x70a9f34f9b34c64957b9c401a97bfed35b95049e",
76-
swapFeeRecipient: feeRecipients.join(","),
77-
swapFeeBps: feeBps.join(","),
86+
swapFeeRecipient: [
87+
"0xPLATFORM_ADDRESS", // index 0 — earns 5 Bps
88+
"0xPARTNER_ADDRESS", // index 1 — earns 10 Bps
89+
].join(","),
90+
swapFeeBps: "5,10",
91+
// swapFeeToken (optional)
7892
});
7993

8094
const response = await fetch(
@@ -90,32 +104,24 @@ const response = await fetch(
90104
const data = await response.json();
91105

92106
// Access full fee breakdown
93-
const fees = data.fees.integratorFees;
94-
fees.forEach((fee, i) => {
95-
console.log(
96-
`Recipient ${feeRecipients[i]} receives ${fee.amount} of ${fee.token}`,
97-
);
107+
data.fees.integratorFees.forEach((fee, i) => {
108+
console.log(`Recipient ${i}: ${fee.amount} of ${fee.token}`);
98109
});
99110
```
100111

101112
```python Python
102113
import os
103114
import requests
104115

105-
fee_recipients = [
106-
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
107-
"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359",
108-
]
109-
fee_bps = [5, 10]
110-
111116
params = {
112117
"chainId": "1",
113118
"buyToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
114119
"sellToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
115120
"sellAmount": "100000000",
116121
"taker": "0x70a9f34f9b34c64957b9c401a97bfed35b95049e",
117-
"swapFeeRecipient": ",".join(fee_recipients),
118-
"swapFeeBps": ",".join(str(b) for b in fee_bps),
122+
"swapFeeRecipient": ",".join(["0xPLATFORM_ADDRESS", "0xPARTNER_ADDRESS"]),
123+
"swapFeeBps": "5,10",
124+
# swapFeeToken (optional)
119125
}
120126

121127
response = requests.get(
@@ -128,7 +134,7 @@ data = response.json()
128134

129135
# Access full fee breakdown
130136
for i, fee in enumerate(data["fees"]["integratorFees"]):
131-
print(f"Recipient {fee_recipients[i]} receives {fee['amount']} of {fee['token']}")
137+
print(f"Recipient {i}: {fee['amount']} of {fee['token']}")
132138
```
133139

134140
</CodeGroup>
@@ -175,7 +181,7 @@ When multiple fees are configured, the response includes both the legacy `integr
175181

176182
Each entry in `integratorFees` corresponds positionally to the `swapFeeRecipient` and `swapFeeBps` values in your request:
177183

178-
| Index | Recipient | Fee (Bps) | Amount (in buy token) |
179-
| ----- | -------------------------------------------- | --------- | --------------------- |
180-
| 0 | `0xdac17f958d2ee523a2206206994597c13d831ec7` | 5 | 49,989 |
181-
| 1 | `0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359` | 10 | 99,978 |
184+
| Index | Recipient | Fee (Bps) | Amount (in buy token) |
185+
| ----- | -------------------- | --------- | --------------------- |
186+
| 0 | `0xPLATFORM_ADDRESS` | 5 | 49,989 |
187+
| 1 | `0xPARTNER_ADDRESS` | 10 | 99,978 |

0 commit comments

Comments
 (0)