> ## Documentation Index
> Fetch the complete documentation index at: https://docs.houdini.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payout Wallet Rotation

> Improve swap privacy by rotating provider routing paths across consecutive orders

# Payout Wallet Rotation

Rotate swap routing paths across consecutive orders so that repeated swaps from the same user don't always flow through the same provider wallet.

## Overview

When a user makes multiple swaps, Houdini normally selects the best-priced route each time. In practice, this often means the same provider handles consecutive swaps — creating a pattern that reduces privacy.

Payout wallet rotation solves this by deprioritizing recently used provider paths and selecting the next-best route instead, while keeping the price within an acceptable range.

> [!NOTE]
>
> Rotation applies to **CEX swaps only** (standard and private). DEX swaps execute on-chain through smart contracts and are not affected by provider path selection.

## How It Works

**1. Quote request with rotation enabled**

You request quotes with `rotatePayoutWallets=true`. Houdini fetches quotes from all available providers as usual.

**2. Recent path lookup**

The system checks your recent orders (last N orders within 24 hours) to find which provider paths were already used.

**3. Path deprioritization**

Quotes matching recently used paths are moved down in the ranking. Quotes using fresh (not recently used) paths are promoted to the top.

**4. Price protection**

If the best non-recently-used quote deviates more than the allowed threshold from the original best quote, rotation is skipped and the best-priced route is used instead. You never pay significantly more for rotation.

## Parameters

**rotatePayoutWallets** `boolean` (default: false)

Enable payout wallet rotation. When `true`, the system deprioritizes recently used provider paths in the quote ranking.

**deviationThreshold** `number` (default: 5)

Maximum allowed price deviation percentage. If the best rotated quote is more than this percentage worse than the original best quote, rotation is skipped. Range: 0–100.

**rotationLookback** `number` (default: 10)

Number of recent orders to check for previously used paths. Valid range: 2–99.

## Lookup Priority

The system determines "recently used paths" based on the following priority:

| Priority | Identifier | When used |
| - | - | - |
| 1 | `multiId` | Split orders — checks all orders in the same Split |
| 2 | Partner ID | Partner API calls — checks recent orders from your partner account |
| 3 | `receiverAddress` + IP | Anonymous/private orders — checks by destination address and IP |

For partner integrations, your partner ID is automatically used (priority 2). You don't need to pass any additional identifiers.

## Price Protection

Rotation never forces a significantly worse price. The `deviationThreshold` parameter controls the maximum acceptable price difference:

* **Deviation ≤ threshold**: Rotated quote is used (different provider path)
* **Deviation > threshold**: Rotation is skipped, best-priced quote is returned
* **All quotes recently used**: Original ranking is preserved (no rotation possible)

**Example**: With `deviationThreshold=5`, if the best quote returns 10 ETH and the best *non-recently-used* quote returns 9.6 ETH (4% worse), the rotated quote is used. If it returns 9.4 ETH (6% worse), rotation is skipped.

## API v2 Usage

In v2, rotation is configured at **quote time**. The rotation parameters are query params on `GET /quotes`, and the selected quote carries the rotation context through to the exchange.

### Step 1: Get Quotes with Rotation

```javascript Node.js theme={null}
const params = new URLSearchParams({
  amount: '1',
  from: '6689b73ec90e45f3b3e51566',  // ETH token id
  to:   '6689b73ec90e45f3b3e51577',  // SOL token id
  types: 'private',
  rotatePayoutWallets: 'true',
  deviationThreshold: '5',
  rotationLookback: '10',
  receiverAddress: '1nc1nerator11111111111111111111111111111111'
});

const response = await fetch(
  `https://api-partner.houdiniswap.com/v2/quotes?${params}`,
  {
    headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
  }
);

const { quotes } = await response.json();
// Quotes are already re-ranked with rotation applied
const bestQuote = quotes[0];
```

```bash cURL theme={null}
curl -G "https://api-partner.houdiniswap.com/v2/quotes" \
  -H "Authorization: YOUR_PARTNER_ID:YOUR_SECRET" \
  -d "amount=1" \
  -d "from=6689b73ec90e45f3b3e51566" \
  -d "to=6689b73ec90e45f3b3e51577" \
  -d "types=private" \
  -d "rotatePayoutWallets=true" \
  -d "deviationThreshold=5" \
  -d "rotationLookback=10" \
  -d "receiverAddress=1nc1nerator11111111111111111111111111111111"
```

### Step 2: Create Exchange

No additional parameters needed — the quote already has rotation applied.

```javascript theme={null}
const response = await fetch('https://api-partner.houdiniswap.com/v2/exchanges', {
  method: 'POST',
  headers: {
    'Authorization': `${API_KEY}:${API_SECRET}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    quoteId: bestQuote.quoteId,
    addressTo: '1nc1nerator11111111111111111111111111111111'
  })
});
```

## API v1 Usage

In v1, rotation can be configured on both the quote and exchange endpoints.

### Option A: Rotation at Quote Time

Pass rotation parameters as query params on `GET /quote`:

```javascript Node.js theme={null}
const params = new URLSearchParams({
  amount: '1',
  from: 'ETH',
  to: 'BNB',
  anonymous: 'true',
  useXmr: 'false',
  rotatePayoutWallets: 'true',
  deviationThreshold: '5',
  rotationLookback: '10'
});

const response = await fetch(
  `https://api-partner.houdiniswap.com/quote?${params}`,
  {
    headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
  }
);
```

```bash cURL theme={null}
curl -G "https://api-partner.houdiniswap.com/quote" \
  -H "Authorization: YOUR_PARTNER_ID:YOUR_SECRET" \
  -d "amount=1" \
  -d "from=ETH" \
  -d "to=BNB" \
  -d "anonymous=true" \
  -d "useXmr=false" \
  -d "rotatePayoutWallets=true" \
  -d "deviationThreshold=5" \
  -d "rotationLookback=10"
```

### Option B: Rotation at Exchange Time

Pass a `filters` object in the `POST /exchange` request body:

```javascript Node.js theme={null}
const response = await fetch('https://api-partner.houdiniswap.com/exchange', {
  method: 'POST',
  headers: {
    'Authorization': `${API_KEY}:${API_SECRET}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 1,
    from: 'ETH',
    to: 'BNB',
    addressTo: '0x000000000000000000000000000000000000dead',
    anonymous: true,
    useXmr: false,
    ip: '203.0.113.1',
    userAgent: 'Mozilla/5.0',
    timezone: 'UTC',
    filters: {
      rotatePayoutWallets: true,
      deviationThreshold: 5,
      rotationLookback: 10
    }
  })
});
```

```bash cURL theme={null}
curl -X POST "https://api-partner.houdiniswap.com/exchange" \
  -H "Authorization: YOUR_PARTNER_ID:YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1,
    "from": "ETH",
    "to": "BNB",
    "addressTo": "0x000000000000000000000000000000000000dead",
    "anonymous": true,
    "useXmr": false,
    "ip": "203.0.113.1",
    "userAgent": "Mozilla/5.0",
    "timezone": "UTC",
    "filters": {
      "rotatePayoutWallets": true,
      "deviationThreshold": 5,
      "rotationLookback": 10
    }
  }'
```

> [!WARNING]
>
> When `rotatePayoutWallets` is enabled on `POST /exchange` in v1, any `inQuoteId` and `outQuoteId` values are discarded. The system fetches fresh quotes with rotation applied at exchange time. This adds a few seconds to the exchange request.

## v1 vs v2 Behavior

| Aspect | v1 | v2 |
| - | - | - |
| **Where rotation is configured** | Quote endpoint, exchange endpoint, or both | Quote endpoint only |
| **How rotation reaches the exchange** | `filters` object passed directly in exchange body | Inherited from the selected quote via `quoteId` |
| **Quote IDs with rotation** | Discarded when rotation is enabled on exchange | Preserved — rotation is already applied to the quote |
| **Latency impact** | Adds \~3-5s when used on exchange (re-quotes) | No additional latency on exchange |

> [!TIP]
>
> For v1 integrations, we recommend using rotation at **quote time** (Option A) rather than exchange time. This avoids the re-quoting overhead and gives you visibility into the rotated quotes before committing to an exchange.

## Best Practices

> [accordion] Use rotation for privacy-sensitive flows
>
> Enable rotation for private/anonymous swaps where users make repeated swaps. For one-off standard swaps, rotation adds little value.

> [accordion] Keep the default deviation threshold
>
> The default 5% threshold balances privacy with price quality. Setting it too high (e.g., 20%) may route through significantly worse-priced providers. Setting it too low (e.g., 1%) may prevent rotation entirely when quotes are tightly clustered.

> [accordion] Adjust lookback based on volume
>
> If your integration processes many swaps per hour, increase `rotationLookback` to 20–30 to ensure broader path diversity. For low-volume integrations, the default of 10 is sufficient.

> [accordion] Combine with the swaps filter
>
> Use the `swaps` parameter (v2) or `onlySwaps` filter (v1) alongside rotation to restrict which providers are considered. Rotation will only rotate within the allowed provider set.

## Next Steps

> [card] [Private Swap](https://docs.houdini.com/developer-hub/swap-flows/private-swap.md)
>
> Full guide for integrating private multi-hop swaps

> [card] [Routing Types](https://docs.houdini.com/developer-hub/core-concepts/routing-types.md)
>
> Understand the three routing strategies


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.