Skip to main content

Overview

Standard swaps route through a single centralized exchange (CEX) for fast execution. In API v2, all swap types — standard, private, and DEX — share the same /quotes and /exchanges endpoints. Pass types=standard to get only standard quotes, or filter the response by type: "standard". Tokens are identified by their ID (not symbol), and orders are created by passing a quoteId.
Best For: Users who prioritize speed and want the fastest completion times (typically 3-30 minutes) with straightforward single-hop routing.
Looking for the v1 standard swap guide? See API v1 — Standard Swap.

How It Works

1

Get Tokens

Bulk fetch CEX-supported tokens and cache to your DB, or search by name/symbol. Note each token’s id.
2

Get Quotes

Call GET /quotes with token IDs. The response returns quotes from all available providers — select the one with type: "standard".
3

Create Order

Call POST /exchanges with the selected quoteId and the user’s destination address.
4

Send Deposit

Send exactly inAmount of the input token to the depositAddress returned in the order.
5

Monitor Status

Poll GET /orders/{houdiniId} until statusLabel is FINISHED.

Integration Guide

Step 1: Get Tokens

There are two approaches for getting tokens. Choose the one that fits your integration:
Fetch all CEX-supported tokens once and store them in your backend database. This is the best approach for production integrations — it keeps your UI fast and avoids hammering the API.
Cache the token list in your backend database. Load on server startup or via a scheduled job, and refresh periodically (e.g., every 24 hours). Never call /tokens on every user request.
// Paginate through all CEX tokens and store in your DB
async function fetchAllCexTokens() {
  let page = 1;
  let allTokens = [];

  while (true) {
    const response = await fetch(
      `https://api-partner.houdiniswap.com/v2/tokens?hasCex=true&pageSize=20&page=${page}`,
      {
        headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
      }
    );

    const { tokens, totalPages } = await response.json();
    allTokens = allTokens.concat(tokens);

    if (page >= totalPages) break;
    page++;
  }

  return allTokens; // save to your DB
}

Step 2: Get Quotes

Call GET /quotes using token IDs (not symbols). The response includes quotes from all available providers across all swap types.
const params = new URLSearchParams({
  amount: '1',
  from: '6689b73ec90e45f3b3e51566',  // ETH token id from /tokens
  to:   '6689b73ec90e45f3b3e51558',  // USDC token id from /tokens
  types: 'standard',                 // only return standard quotes
});

const response = await fetch(
  `https://api-partner.houdiniswap.com/v2/quotes?${params}`,
  {
    headers: {
      'Authorization': `${API_KEY}:${API_SECRET}`,
      'x-user-ip': userIp,
      'x-user-agent': userAgent,
      'x-user-timezone': userTimezone
    }
  }
);

const { quotes } = await response.json();

// Pick a standard (single-hop CEX) quote
const standardQuote = quotes.find(q => q.type === 'standard');
console.log('Provider:', standardQuote.swapName);
console.log('Amount out:', standardQuote.amountOut);
console.log('ETA:', standardQuote.duration, 'minutes');
console.log('Quote ID:', standardQuote.quoteId); // needed for next step

Quotes Response

{
  "quotes": [
    {
      "quoteId": "69af9e02f9c5affabcaccc14",
      "type": "standard",
      "swap": "cc",
      "swapName": "Coincraddle",
      "logoUrl": "https://api.houdiniswap.com/assets/logos/coincraddle.jpg",
      "amountIn": 1,
      "amountOut": 23.56,
      "amountOutUsd": 2019.09,
      "min": 0.098169,
      "max": 4688.581529,
      "duration": 30,
      "rewardsAvailable": true
    }
  ],
  "total": 5
}
Key Fields:
  • quoteId: Pass this to /exchanges to create the order
  • type: "standard" for single-hop CEX routing
  • swap / swapName: CEX provider code and human-readable name
  • amountOut: Output amount
  • duration: Estimated completion time in minutes
  • min / max: Valid input amount range

Step 3: Create Order

Pass the quoteId and destination address to POST /exchanges:
const response = await fetch('https://api-partner.houdiniswap.com/v2/exchanges', {
  method: 'POST',
  headers: {
    'Authorization': `${API_KEY}:${API_SECRET}`,
    'Content-Type': 'application/json',
    'x-user-ip': userIp,
    'x-user-agent': userAgent,
    'x-user-timezone': userTimezone
  },
  body: JSON.stringify({
    quoteId: '694cd4ef6ca7023b5e00a288',  // from /quotes
    addressTo: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'
  })
});

const order = await response.json();
console.log('Order ID:', order.houdiniId);
console.log('Deposit to:', order.depositAddress);
console.log('Send amount:', order.inAmount, order.inSymbol);
console.log('Expires:', order.expires);

Order Response

{
  "houdiniId": "iBQMRX3xvXrFMGQi71ogo9",
  "created": "2025-12-25T06:13:46.673Z",
  "expires": "2025-12-25T06:43:46.673Z",
  "depositAddress": "0x7364a0b6c55004427a4a7c26355ce9c75ef56194",
  "receiverAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
  "anonymous": false,
  "status": -1,
  "statusLabel": "NEW",
  "inAmount": 1,
  "inSymbol": "ETH",
  "inStatus": 0,
  "inStatusLabel": "NEW",
  "outAmount": 2456.78,
  "outSymbol": "USDC",
  "outStatus": 0,
  "outStatusLabel": "NEW",
  "eta": 3,
  "inAmountUsd": 2937,
  "swapName": "Changelly",
  "inToken": {
    "id": "6689b73ec90e45f3b3e51566",
    "symbol": "ETH",
    "name": "Ethereum",
    "decimals": 18,
    "chain": "ethereum"
  },
  "outToken": {
    "id": "6689b73ec90e45f3b3e51558",
    "symbol": "USDC",
    "name": "USD Coin",
    "decimals": 6,
    "chain": "ethereum"
  }
}
Key Response Fields:
  • houdiniId: Unique order identifier — use for status polling
  • depositAddress: Send input funds here
  • inAmount / inSymbol: Exact amount and token to send
  • expires: Deposit deadline (typically 30 minutes)
  • statusLabel: Human-readable order status
  • eta: Estimated completion time in minutes
Send exactly inAmount of inSymbol to depositAddress before expires.

Step 4: Send Deposit

After creating the order, send the input tokens to depositAddress. The status will advance automatically once the deposit is detected on-chain.

Step 5: Monitor Order Status

Poll GET /orders/{houdiniId} to track progress, or subscribe via the WebSocket API for real-time updates:
const response = await fetch(
  `https://api-partner.houdiniswap.com/v2/orders/${order.houdiniId}`,
  {
    headers: {
      'Authorization': `${API_KEY}:${API_SECRET}`,
      'x-user-ip': userIp,
      'x-user-agent': userAgent,
      'x-user-timezone': userTimezone
    }
  }
);

const status = await response.json();
console.log('Status:', status.statusLabel);
// WAITING     — awaiting deposit
// CONFIRMING  — deposit detected, awaiting confirmations
// EXCHANGING  — CEX is processing the swap
// FINISHED    — swap complete, funds sent
// FAILED      — swap failed
// EXPIRED     — deposit not received in time
// REFUNDED    — funds returned to sender

Status Progression

NEW / WAITING
  ↓ Deposit sent and detected
CONFIRMING
  ↓ Blockchain confirmations received
EXCHANGING
  ↓ CEX processes the swap
FINISHED
Poll every 30 seconds. Standard swaps typically complete in 3–30 minutes. For real-time updates without polling, use the WebSocket API.

Best Practices

  • Bulk fetch + cache: Paginate through /v2/tokens?hasCex=true on server startup and store in your DB. Refresh every 24 hours.
  • Search: Use ?term=<query> for on-demand token lookup — good for lightweight integrations.
  • Never call /tokens on every user request in production.
  • Poll /orders/{houdiniId} every 30 seconds
  • Store houdiniId for future reference and support lookups
  • Handle all statusLabel values: FINISHED, FAILED, EXPIRED, REFUNDED
  • Re-fetch quotes if quote is expired before calling /exchanges
  • Validate addressTo format before submitting
  • Implement retry logic with backoff for API calls
  • Never expose API keys in frontend code
  • Use backend-only API integration
  • Validate all addresses before submitting
  • Store order records for audit trail

Common Issues

Causes: Network congestion, CEX processing delays, slow block confirmations.Solution: Continue monitoring. Most swaps complete within 2× the estimated time.
Issue: User sent an incorrect amount to the deposit address.Solution: A partial refund may be processed. Contact support with the houdiniId.
Cause: Deposit was not received before the expires timestamp.Solution: Fetch a new quote and create a new order.
Solution: Wait for blockchain confirmations. Check the deposit transaction on a block explorer and verify the correct amount was sent.

Example Repositories

See full working integrations on GitHub:

Next Steps