Skip to main content

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.
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:
PriorityIdentifierWhen used
1multiIdMultiSwap orders — checks all orders in the same multi-swap group
2Partner IDPartner API calls — checks recent orders from your partner account
3receiverAddress + IPAnonymous/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

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];

Step 2: Create Exchange

No additional parameters needed — the quote already has rotation applied.
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:
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}` }
  }
);

Option B: Rotation at Exchange Time

Pass a filters object in the POST /exchange request body:
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
    }
  })
});
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

Aspectv1v2
Where rotation is configuredQuote endpoint, exchange endpoint, or bothQuote endpoint only
How rotation reaches the exchangefilters object passed directly in exchange bodyInherited from the selected quote via quoteId
Quote IDs with rotationDiscarded when rotation is enabled on exchangePreserved — rotation is already applied to the quote
Latency impactAdds ~3-5s when used on exchange (re-quotes)No additional latency on exchange
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

Enable rotation for private/anonymous swaps where users make repeated swaps. For one-off standard swaps, rotation adds little value.
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.
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.
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

Private Swap Integration

Full guide for integrating private multi-hop swaps

Routing Types

Understand the three routing strategies