Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ navigation:
- page: Get Started
slug: get-started-with-solana-swap-api
path: docs/pages/solana-swap-api/guides/get-started.mdx
- page: Monetize Your App
slug: monetize-your-app
path: docs/pages/solana-swap-api/guides/monetize-your-app.mdx
- page: Important Integration Notes
slug: important-integration-notes
path: docs/pages/solana-swap-api/guides/important-integration-notes.mdx
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Monetize Your App
title: Monetize Your App on EVM
description: This guide covers how you can monetize your app by using the 0x Swap API.
---

Expand Down
2 changes: 1 addition & 1 deletion fern/docs/pages/introduction/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ https://api.0x.org/gasless/quote # Request a firm quote

**For an integrator fee address:** No. You should assume the fee recipient ATA must already exist. If it may not exist, add a `createAssociatedTokenAccountIdempotent` instruction for the fee recipient + fee token mint yourself, **before** the swap/fee transfer path. See the [Integrator Byte Costs](/svm/solana-swap-api/guides/integrator-byte-costs) guide for how to account for the extra bytes this adds.

The relevant field is [`swap_fee_recipient`](/api-reference/solana-swap-ap-is/swap/instructions#swap_fee_recipient) — it accepts either a wallet address (for native SOL output) or a valid token account address (for token outputs).
The relevant field is [`swap_fee_recipient`](/api-reference/solana-swap-ap-is/swap/instructions#request.body.swap_fee_recipient) — it accepts either a wallet address (for native SOL output) or a valid token account address (for token outputs).

</Accordion>
</AccordionGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ We currently return **a single flat array of instructions.** Here's what’s cur
- **Setup Instructions (N):**
- These create associated token accounts (ATAs) for the user (`taker`) as needed. This uses `createIdempotent`, so instructions won’t fail if an ATA already exists.
- The number of instructions (`N`) depends on how many tokens the route involves, sometimes there may be 1 extra instruction for native SOL support (for certain DEXs).
- **Integrator fee recipient ATAs are not created automatically.** The [`swap_fee_recipient`](/api-reference/solana-swap-ap-is/swap/instructions#swap_fee_recipient) field accepts either a wallet address (for native SOL output) or a valid token account address (for token outputs). If you're collecting fees on a token output, the token account you pass must already exist — 0x will not create it. If it may not exist, add a `createAssociatedTokenAccountIdempotent` instruction for the fee recipient + fee token mint **before** the swap/fee transfer path. See the [Integrator Byte Costs](/svm/solana-swap-api/guides/integrator-byte-costs) guide for how to account for those extra bytes.
- **Integrator fee recipient ATAs are not created automatically.** The [`swap_fee_recipient`](/api-reference/solana-swap-ap-is/swap/instructions#request.body.swap_fee_recipient) field accepts either a wallet address (for native SOL output) or a valid token account address (for token outputs). If you're collecting fees on a token output, the token account you pass must already exist — 0x will not create it. If it may not exist, add a `createAssociatedTokenAccountIdempotent` instruction for the fee recipient + fee token mint **before** the swap/fee transfer path. See the [Integrator Byte Costs](/svm/solana-swap-api/guides/integrator-byte-costs) guide for how to account for those extra bytes.
- **Swap Instruction (1):**
- A single instruction on our [**Settler**](https://github.com/0xProject/0x-settler) program to perform the actual swap.
- **Cleanup Instructions (as required):**
Expand Down
106 changes: 106 additions & 0 deletions fern/docs/pages/solana-swap-api/guides/monetize-your-app.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Monetize Your App on Solana
description: This guide covers how you can monetize your app by using the 0x Solana Swap API.
---

## Introduction

Integrate in-app swaps to let users trade seamlessly and at the best prices across Solana's top DEXs. As your app grows, you can monetize those trades with low-friction strategies to generate revenue and build a sustainable business.

See our [Monetization Report](https://0x.org/reports/monetization-across-defi-report) to learn how top DeFi apps are turning trading activity into millions.

See below for pricing guidance and code examples.

## Monetization

Out-of-the-box, the 0x Solana Swap API lets you collect one or more volume-based fees (aka affiliate fees, trading fees, or commission) directly within a swap request, available on all pricing plans.

<Tip>
⚡️ [Example code](https://github.com/0xProject/0x-examples/tree/main/solana-example) for integrating the Solana Swap API.

⚡️ See the [Solana Swap API reference](/api-reference/solana-swap-ap-is/swap/instructions) for the full request and response schema.
</Tip>

## Collect volume-based fees

The 0x Solana Swap API supports one or more volume-based fees within a single swap request. This lets you route fees to multiple recipients with independently specified amounts and sides — perfect for multi-product apps, partner revenue-share setups, or flexible monetization strategies.

To apply volume-based fees, include the following fields in the body of your [`/solana/swap-instructions` request](/api-reference/solana-swap-ap-is/swap/instructions):

- [`swap_fee_ppm`](/api-reference/solana-swap-ap-is/swap/instructions#request.body.swap_fee_ppm) — the fee amount(s) in **parts per million (ppm)**. Each entry must be between `0` and your per-app maximum (`100_000` ppm / 10% by default — see [Pricing considerations](#pricing-considerations)), and a value of `0` disables that entry. Supports single or multiple comma-separated values.
- [`swap_fee_recipient`](/api-reference/solana-swap-ap-is/swap/instructions#request.body.swap_fee_recipient) — the account(s) to receive the fees. Supports single or multiple comma-separated values, and must contain the same number of entries as `swap_fee_ppm`.
- [`swap_fee_side`](/api-reference/solana-swap-ap-is/swap/instructions#request.body.swap_fee_side) — *(optional)* the side each fee is charged on: `buy` (the output token) or `sell` (the input token). Supports single or multiple comma-separated values. May be omitted only when every fee uses the default `buy` side; otherwise it must contain the same number of entries as `swap_fee_ppm`.

<Note>
Fees on Solana are expressed in **parts per million (ppm)**, not basis points. `1_000_000` ppm = 100%, so a 1% fee is `10000` ppm and a 5% fee is `50000` ppm.
</Note>

### Example API call

The following request takes a single 1% fee on the buy (output) token and sends it to your fee account:

```js
const response = await fetch("https://api.0x.org/solana/swap-instructions", {
method: "POST",
headers: {
"0x-api-key": process.env.ZEROEX_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
token_out: "So11111111111111111111111111111111111111112", // Buy SOL
token_in: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // Sell USDC
amount_in: 100000000, // 100 USDC (6 decimals)
taker: takerKeypair.publicKey.toBase58(),
swap_fee_ppm: "10000", // 1% fee (10,000 ppm)
swap_fee_recipient: "3emsAVdmGKERbHjmGfQ6oZ1e35dkf5iYcS6U4CPKFVaa", // Your fee account
swap_fee_side: "buy", // Collect the fee on the output token
}),
});
```

### Multiple fees and recipients

Each comma-separated position defines one fee entry, so a single request can charge several fees to several recipients across both sides:

```json
{
"swap_fee_ppm": "50000,25000,10000",
"swap_fee_recipient": "recipient1,recipient2,recipient3",
"swap_fee_side": "buy,buy,sell"
}
```

In this example, a 5% and a 2.5% fee are collected on the buy token for two different recipients, and a 1% fee is collected on the sell token for a third.

<Note>
Fees on the **same side** are applied **sequentially**: each entry is charged on the amount remaining after the previous entries on that side have been deducted, not on the original amount. For example, two buy-side fees of `50000` and `25000` ppm produce an effective fee of ~7.38%, not 7.5%. Each fee amount is rounded up to the next base unit when needed.
</Note>

### Buy-side vs sell-side fees

- **`buy`** — the fee is taken from the output token. This reduces the `amount_out` and `min_amount_out` returned in the quote.
- **`sell`** — the fee is taken from the input token before the swap is routed. This reduces the amount routed into the swap.

### Fee recipient accounts

<Warning>
0x does **not** create fee recipient token accounts for you. For token outputs, the `swap_fee_recipient` you pass must be a **token account that already exists**. For native SOL output, a wallet address is accepted.

If the fee recipient's token account may not exist, add a `createAssociatedTokenAccountIdempotent` instruction for the recipient and fee token mint **before** the swap. Account for the extra transaction bytes using the [Integrator Byte Costs](/svm/solana-swap-api/guides/integrator-byte-costs) guide.
</Warning>

If a fee recipient is the taker's own token account for that side, the fee is treated as absent (not a self-transfer) and is omitted from the quote and the returned instructions. See [Important Integration Notes](/svm/solana-swap-api/guides/important-integration-notes) for details on fee recipient token accounts, including why 0x does not create them for you.

### Displaying fees

The fee you charge is fully determined by the values you send in the request, so you can display it in your UI directly from those: each `swap_fee_ppm` rate, the token it is charged in (the output token for a `buy` fee, the input token for a `sell` fee), and its `swap_fee_recipient`.

The quote already reflects any buy-side fees: the returned `amount_out` and `min_amount_out` are net of them, so the value you show the user as the amount received is correct as-is. Sell-side fees reduce the amount routed into the swap before the quote is produced.

For the complete request and response schema, see the [API Reference](/api-reference/solana-swap-ap-is/swap/instructions).

### Pricing considerations

When deciding how much to charge, set your pricing in a way that strengthens your bottom line while aligning with the value you provide to customers. The volume-based fee impacts the price for the end user, so find the sweet spot where your solution remains competitive.

Be aware that `swap_fee_ppm` has a default per-app limit of `100_000` ppm (10%) for security. The cap is enforced **per fee entry, not on the combined total**: each fee in the list is validated individually against the limit. For example, two sell-side fees of `60000` ppm (6%) each are both accepted under a `100_000` ppm cap, even though they sum to 12%, because neither individual entry exceeds the cap. If your application requires a higher per-entry value, [please reach out to us](https://docs.0x.org/docs/introduction/need-help#-contact-developer-support-fastest-direct-help).