***
title: Swap and Send
description: Send swapped tokens directly to any address using the recipient parameter.
---------------------------------------------------------------------------------------
By default, swapped tokens are returned to the address that initiates the trade (the `taker`). With the `recipient` parameter, you can send the output tokens directly to any wallet address — in a single transaction.
This unlocks use cases like:
* Swapping and gifting tokens to another wallet
* Purchasing tokens on behalf of a user
* Automating treasury distributions in a different token
* Powering "pay with any token" checkout flows
The `recipient` parameter is supported on both the **Swap API** and **Gasless
API**.
***
## How it works
When you include `recipient` in your request, the `buyToken` is delivered to that address at settlement. The taker (the address signing and submitting the transaction) still pays and authorizes the swap — they just don't receive the output.
```
Taker ──pays sellToken──► 0x Settler / AllowanceHolder ──sends buyToken──► Recipient
```
If `recipient` is omitted, it defaults to the taker's address, so existing integrations are unaffected.
***
## API Reference
### `recipient`
| Property | Value |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type | `string` |
| Required | No |
| Format | `^0x[a-fA-F0-9]{40}$` |
| Default | Taker address |
| Supported | Swap API ([price](https://docs.0x.org/api-reference/openapi-json/swap/allowanceholder-getprice), [quote](https://docs.0x.org/api-reference/openapi-json/swap/allowanceholder-getquote)), Gasless API ([price](https://docs.0x.org/api-reference/openapi-json/gasless/getprice#request.query), [quote](https://docs.0x.org/api-reference/openapi-json/gasless/getquote#request.query)) |
`recipient` is **not supported** for wrap and unwrap operations (e.g. ETH ↔
WETH). Passing it for those trade types will result in an error. Check for
native/wrapped token pairs and omit `recipient` before calling the API.
***
## Swap API Example
Include `recipient` as a query parameter when fetching a quote and submitting the swap.
```typescript
const params = new URLSearchParams({
sellToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", // ETH
buyToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
sellAmount: "1000000000000000000", // 1 ETH in wei
taker: "0xYourTakerAddress",
recipient: "0xRecipientAddress", // buyToken sent here
});
const response = await fetch(
`https://api.0x.org/swap/permit2/quote?${params}`,
{
headers: {
"0x-api-key": process.env.ZEROX_API_KEY!,
"0x-version": "v2",
},
},
);
const quote = await response.json();
```
```python
import requests
import os
params = {
"sellToken": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", # ETH
"buyToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", # USDC
"sellAmount": "1000000000000000000", # 1 ETH in wei
"taker": "0xYourTakerAddress",
"recipient": "0xRecipientAddress", # buyToken sent here
}
response = requests.get(
"https://api.0x.org/swap/permit2/quote",
headers={
"0x-api-key": os.environ["ZEROX_API_KEY"],
"0x-version": "v2",
},
params=params,
)
quote = response.json()
```
```bash
curl "https://api.0x.org/swap/permit2/quote?\
sellToken=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&\
buyToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
sellAmount=1000000000000000000&\
taker=0xYourTakerAddress&\
recipient=0xRecipientAddress" \
-H "0x-api-key: $ZEROX_API_KEY" \
-H "0x-version: v2"
```
***
## Gasless API Example
The `recipient` parameter works the same way with the Gasless API. Include it in the quote request body — the relayer will deliver `buyToken` to the recipient address on settlement.
```typescript
const params = new URLSearchParams({
sellToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
buyToken: "0x6B175474E89094C44Da98b954EedeAC495271d0F", // DAI
sellAmount: "1000000000", // 1000 USDC (6 decimals)
taker: "0xYourTakerAddress",
recipient: "0xRecipientAddress", // buyToken sent here
});
const response = await fetch(`https://api.0x.org/gasless/quote?${params}`, {
headers: {
"0x-api-key": process.env.ZEROX_API_KEY!,
"0x-version": "v2",
},
});
const quote = await response.json();
```
```python
import requests
import os
params = {
"sellToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", # USDC
"buyToken": "0x6B175474E89094C44Da98b954EedeAC495271d0F", # DAI
"sellAmount": "1000000000", # 1000 USDC (6 decimals)
"taker": "0xYourTakerAddress",
"recipient": "0xRecipientAddress", # buyToken sent here
}
response = requests.get(
"https://api.0x.org/gasless/quote",
headers={
"0x-api-key": os.environ["ZEROX_API_KEY"],
"0x-version": "v2",
},
params=params,
)
quote = response.json()
```
```bash
curl "https://api.0x.org/gasless/quote?\
sellToken=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48&\
buyToken=0x6B175474E89094C44Da98b954EedeAC495271d0F&\
sellAmount=1000000000&\
taker=0xYourTakerAddress&\
recipient=0xRecipientAddress" \
-H "0x-api-key: $ZEROX_API_KEY" \
-H "0x-version: v2"
```
***
## Errors
The API validates recipient at the price and quote stage — before any transaction is submitted — so no gas is wasted. There are two common error cases: an [invalid recipient address](/docs/0x-swap-api/additional-topics/swap-and-send#invalid-recipient-address) and passing recipient on a [wrap/unwrap operation](/docs/0x-swap-api/additional-topics/swap-and-send#wrapunwrap-operations).
### Invalid recipient address
The `recipient` value must be a valid Ethereum address — a 42-character hex string starting with `0x`. This error is triggered by things like a truncated address, a non-hex character, or passing a raw ENS name instead of a resolved address.
Always resolve ENS names to addresses client-side before passing them to the API. The `recipient` field does not support ENS.
```json
{
"name": "INPUT_INVALID",
"message": "The input is invalid",
"data": {
"zid": "0x8843f11733fbf965f90ef10a",
"details": [
{
"field": "recipient",
"reason": "Invalid ethereum address"
}
]
}
}
```
To catch this before hitting the API, validate the address client-side:
```typescript
import { isAddress, getAddress } from "viem";
const raw = userInputAddress;
if (!isAddress(raw)) {
throw new Error("Invalid recipient address");
}
const recipient = getAddress(raw); // normalizes to EIP-55 checksum
```
### Wrap/unwrap operations
`recipient` is not supported when `sellToken` and `buyToken` are a native/wrapped pair (e.g. ETH ↔ WETH, MATIC ↔ WMATIC). These operations don't route through the swap protocol, so the `recipient` field has no effect and is rejected.
```json
{
"name": "RECIPIENT_NOT_SUPPORTED",
"message": "The recipient parameter is not supported for wrap/unwrap operations",
"data": {
"zid": "0x05e4e8147d97597183b471ca"
}
}
```
Guard against this by detecting wrap/unwrap pairs before building your request and omitting `recipient` in those cases:
```typescript
const WRAP_UNWRAP_PAIRS: [string, string][] = [
["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"], // ETH ↔ WETH
// add other pairs as needed
];
const isWrapUnwrap = (sellToken: string, buyToken: string) =>
WRAP_UNWRAP_PAIRS.some(
([a, b]) =>
(sellToken.toLowerCase() === a.toLowerCase() && buyToken.toLowerCase() === b.toLowerCase()) ||
(sellToken.toLowerCase() === b.toLowerCase() && buyToken.toLowerCase() === a.toLowerCase())
);
const params = {
sellToken,
buyToken,
sellAmount,
taker,
...(!isWrapUnwrap(sellToken, buyToken) && { recipient }),
};
```
The `zid` in the error response is a trace ID — include it when contacting support to help diagnose the issue.
***
## Key considerations
* **Taker still pays.** The `taker` signs and funds the transaction. Only the output destination changes.
* **Omitting `recipient` is safe**, it falls back to the taker address, so no changes are needed for existing flows.
* **Validate before sending.** Always validate `recipient` client-side to avoid wasted gas on failed transactions.
* **Wrap/unwrap is not supported.** Check for native/wrapped token pairs and strip `recipient` before calling the API.
```
```