Skip to content

Commit 5e69347

Browse files
authored
Merge pull request #181 from 0xProject/jlin/add-multi-fee-guide
add multi-fee support guide
2 parents 44391e8 + 9f3661e commit 5e69347

2 files changed

Lines changed: 186 additions & 2 deletions

File tree

fern/docs.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ navigation:
138138
- section: Additional Topics
139139
slug: additional-topics
140140
contents:
141-
- page: How to Set Token Allowances
141+
- page: Set Token Allowances
142142
slug: how-to-set-your-token-allowances
143143
path: docs/pages/0x-swap-api/additional-topics/how-to-set-your-token-allowances.mdx
144-
- page: Handling Native Tokens
144+
- page: Handle Native Tokens
145145
slug: handling-native-tokens
146146
path: docs/pages/0x-swap-api/additional-topics/handling-native-tokens.mdx
147147
- page: 0x Parser
@@ -153,6 +153,9 @@ navigation:
153153
- page: Buy/Sell Tax Support
154154
slug: buy-sell-tax-support
155155
path: docs/pages/0x-swap-api/additional-topics/buy-sell-tax-support.mdx
156+
- page: Multi-Fee Support
157+
slug: multi-fee-support
158+
path: docs/pages/0x-swap-api/additional-topics/multi-fee-support.mdx
156159
- page: Swap and Send
157160
slug: swap-and-send
158161
path: docs/pages/0x-swap-api/additional-topics/swap-and-send.mdx
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
title: Multi-Fee Support
3+
description: Collect fees for multiple recipients in a single swap using the Swap and Gasless APIs.
4+
---
5+
6+
The Swap and Gasless APIs support collecting fees for **multiple recipients in a single transaction**. This is useful for use cases like revenue sharing between a protocol and a frontend, splitting fees between partners, or distributing fees across multiple treasury addresses — all without requiring multiple transactions or custom contracts.
7+
8+
## Overview
9+
10+
Both `swapFeeRecipient` and `swapFeeBps` accept **comma-separated lists**, allowing you to define multiple fee recipients, each with their own fee rate.
11+
12+
Each fee is:
13+
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`
17+
18+
## Parameters
19+
20+
<ParamField query="swapFeeRecipient" type="string" optional>
21+
The wallet address(es) to receive trading fees. Accepts a single address or multiple comma-separated addresses.
22+
23+
**Example:** `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045,0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359`
24+
25+
When providing multiple values, the list must be the same length as `swapFeeBps`. You must also specify `swapFeeBps` to use this parameter.
26+
27+
</ParamField>
28+
29+
<ParamField query="swapFeeBps" type="string" optional>
30+
The fee amount(s) in basis points (Bps) to charge per recipient. Accepts a single value or multiple comma-separated values.
31+
32+
**Example:** `5,10`
33+
34+
When providing multiple values, the list must be the same length as `swapFeeRecipient`. The default maximum is **1000 Bps** per recipient. [Contact us](mailto:support@0x.org) if your integration requires a higher limit.
35+
36+
</ParamField>
37+
38+
<Note>
39+
`swapFeeRecipient` and `swapFeeBps` are co-dependent — you must specify both
40+
together. When using multiple fees, both lists must be the same length and
41+
positionally matched (index 0 of `swapFeeBps` applies to index 0 of
42+
`swapFeeRecipient`, and so on).
43+
</Note>
44+
45+
## Example Request
46+
47+
The following examples split fees between two recipient addresses — 5 Bps to `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045` and 10 Bps to `0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359`.
48+
49+
<CodeGroup>
50+
51+
```bash cURL
52+
curl "https://api.0x.org/swap/allowance-holder/price\
53+
?chainId=1\
54+
&buyToken=0xdac17f958d2ee523a2206206994597c13d831ec7\
55+
&sellToken=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\
56+
&sellAmount=100000000\
57+
&taker=0x70a9f34f9b34c64957b9c401a97bfed35b95049e\
58+
&swapFeeRecipient=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045,0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359\
59+
&swapFeeBps=5,10" \
60+
-H "0x-api-key: <YOUR_API_KEY>"
61+
```
62+
63+
```typescript TypeScript
64+
const feeRecipients = [
65+
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
66+
"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359",
67+
];
68+
const feeBps = [5, 10];
69+
70+
const params = new URLSearchParams({
71+
chainId: "1",
72+
buyToken: "0xdac17f958d2ee523a2206206994597c13d831ec7",
73+
sellToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
74+
sellAmount: "100000000",
75+
taker: "0x70a9f34f9b34c64957b9c401a97bfed35b95049e",
76+
swapFeeRecipient: feeRecipients.join(","),
77+
swapFeeBps: feeBps.join(","),
78+
});
79+
80+
const response = await fetch(
81+
`https://api.0x.org/swap/allowance-holder/price?${params}`,
82+
{
83+
headers: {
84+
"0x-api-key": process.env.ZEROX_API_KEY!,
85+
"0x-version": "v2",
86+
},
87+
},
88+
);
89+
90+
const data = await response.json();
91+
92+
// 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+
);
98+
});
99+
```
100+
101+
```python Python
102+
import os
103+
import requests
104+
105+
fee_recipients = [
106+
"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
107+
"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359",
108+
]
109+
fee_bps = [5, 10]
110+
111+
params = {
112+
"chainId": "1",
113+
"buyToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
114+
"sellToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
115+
"sellAmount": "100000000",
116+
"taker": "0x70a9f34f9b34c64957b9c401a97bfed35b95049e",
117+
"swapFeeRecipient": ",".join(fee_recipients),
118+
"swapFeeBps": ",".join(str(b) for b in fee_bps),
119+
}
120+
121+
response = requests.get(
122+
"https://api.0x.org/swap/allowance-holder/price",
123+
params=params,
124+
headers={"0x-api-key": os.environ["ZEROX_API_KEY"]},
125+
)
126+
127+
data = response.json()
128+
129+
# Access full fee breakdown
130+
for i, fee in enumerate(data["fees"]["integratorFees"]):
131+
print(f"Recipient {fee_recipients[i]} receives {fee['amount']} of {fee['token']}")
132+
```
133+
134+
</CodeGroup>
135+
136+
## Example Response
137+
138+
When multiple fees are configured, the response includes both the legacy `integratorFee` field (containing the first fee, for backwards compatibility) and the new `integratorFees` array (containing all fees):
139+
140+
```json
141+
{
142+
"fees": {
143+
"integratorFee": {
144+
"amount": "49989",
145+
"token": "0xdac17f958d2ee523a2206206994597c13d831ec7",
146+
"type": "volume"
147+
},
148+
"integratorFees": [
149+
{
150+
"amount": "49989",
151+
"token": "0xdac17f958d2ee523a2206206994597c13d831ec7",
152+
"type": "volume"
153+
},
154+
{
155+
"amount": "99978",
156+
"token": "0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359",
157+
"type": "volume"
158+
}
159+
],
160+
"zeroExFee": {
161+
"amount": "149968",
162+
"token": "0xdac17f958d2ee523a2206206994597c13d831ec7",
163+
"type": "volume"
164+
},
165+
"gasFee": null
166+
}
167+
}
168+
```
169+
170+
<Note>
171+
`fees.integratorFee` is retained for backwards compatibility and always
172+
reflects the **first** fee in the list. Use `fees.integratorFees` to access
173+
the full breakdown of all fees.
174+
</Note>
175+
176+
Each entry in `integratorFees` corresponds positionally to the `swapFeeRecipient` and `swapFeeBps` values in your request:
177+
178+
| Index | Recipient | Fee (Bps) | Amount (in buy token) |
179+
| ----- | -------------------------------------------- | --------- | --------------------- |
180+
| 0 | `0xdac17f958d2ee523a2206206994597c13d831ec7` | 5 | 49,989 |
181+
| 1 | `0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359` | 10 | 99,978 |

0 commit comments

Comments
 (0)