> ## 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.

# Standard Swap

> Integrate standard CEX swaps using the unified v2 quotes and exchanges API

## 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`.

> [!NOTE]
>
> **Best For**: Users who prioritize speed and want the fastest completion times (typically 3-30 minutes) with straightforward single-hop routing.

> [!NOTE]
>
> Looking for the v1 standard swap guide? See [API v1 — Standard Swap](https://docs.houdini.com/api-v1/swap-flows/standard-swap.md).

> [!NOTE]
>
> Standard swaps support **fixed rate** and **reverse quotes**. Add `fixed=true` to lock the rate and guarantee the output amount, and `amountType=receive` to specify what the recipient receives instead of what the user sends. See [Fixed Rate & Reverse Quote](https://docs.houdini.com/developer-hub/swap-flows/fixed-rate-swap.md).

## 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:

> [tab] Bulk Fetch + Cache
>
> 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.
>
> > [!WARNING]
> >
> > 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.
>
> ```javascript JavaScript theme={null}
> // 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
> }
> ```
>
> ```bash cURL theme={null}
> curl -X GET "https://api-partner.houdiniswap.com/v2/tokens?hasCex=true&pageSize=20&page=1" \
>   -H "Authorization: your_api_key:your_api_secret"
> ```

> [tab] Token Search
>
> Search for specific tokens by name or symbol on demand. Useful for lightweight integrations or when you want to let users search without prefetching everything.
>
> ```javascript JavaScript theme={null}
> // Search tokens as user types
> async function searchTokens(query) {
>   const params = new URLSearchParams({
>     term: query,        // e.g. "bitcoin" or "ETH"
>     hasCex: 'true',
>     pageSize: '20',
>     page: '1'
>   });
>
>   const response = await fetch(
>     `https://api-partner.houdiniswap.com/v2/tokens?${params}`,
>     {
>       headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
>     }
>   );
>
>   const { tokens } = await response.json();
>   return tokens; // use token `id` in /quotes requests
> }
> ```
>
> ```bash cURL theme={null}
> curl -X GET "https://api-partner.houdiniswap.com/v2/tokens?term=bitcoin&hasCex=true&pageSize=20&page=1" \
>   -H "Authorization: your_api_key:your_api_secret"
> ```

### Step 2: Get Quotes

Call `GET /quotes` using token IDs (not symbols). The response includes quotes from all available providers across all swap types.

```javascript JavaScript theme={null}
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
```

```bash cURL theme={null}
curl -X GET "https://api-partner.houdiniswap.com/v2/quotes?amount=1&from=6689b73ec90e45f3b3e51566&to=6689b73ec90e45f3b3e51558&types=standard" \
  -H "Authorization: your_api_key:your_api_secret" \
  -H "x-user-ip: 192.168.1.1" \
  -H "x-user-agent: Mozilla/5.0..." \
  -H "x-user-timezone: America/New_York"
```

### Quotes Response

```json theme={null}
{
  "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

#### Rate options

The quote above is a **floating** rate — `amountOut` is an estimate that can move before settlement. Two options change that:

| Option | Parameter | Effect |
| - | - | - |
| Fixed rate | `fixed=true` | `amountOut` is guaranteed, locked until `validUntil` |
| Reverse quote | `fixed=true&amountType=receive` | `amount` becomes what the recipient receives; the API computes the deposit |

Both require a `refundAddress` on the source chain when you create the order, and both return fewer routes than a floating quote since not every provider supports them. See [Fixed Rate & Reverse Quote](https://docs.houdini.com/developer-hub/swap-flows/fixed-rate-swap.md) for the full flow, response differences, and error codes.

### Step 3: Create Order

Pass the `quoteId` and destination address to `POST /exchanges`:

```javascript 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',
    '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);
```

```bash cURL theme={null}
curl -X POST "https://api-partner.houdiniswap.com/v2/exchanges" \
  -H "Authorization: your_api_key:your_api_secret" \
  -H "Content-Type: application/json" \
  -H "x-user-ip: 192.168.1.1" \
  -H "x-user-agent: Mozilla/5.0..." \
  -H "x-user-timezone: America/New_York" \
  -d '{
    "quoteId": "694cd4ef6ca7023b5e00a288",
    "addressTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
  }'
```

### Order Response

```json theme={null}
{
  "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

> [!WARNING]
>
> 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](https://docs.houdini.com/developer-hub/core-concepts/websocket-order-updates.md) for real-time updates:

```javascript JavaScript theme={null}
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
```

```bash cURL theme={null}
curl -X GET "https://api-partner.houdiniswap.com/v2/orders/iBQMRX3xvXrFMGQi71ogo9" \
  -H "Authorization: your_api_key:your_api_secret" \
  -H "x-user-ip: 192.168.1.1" \
  -H "x-user-agent: Mozilla/5.0..." \
  -H "x-user-timezone: America/New_York"
```

### Status Progression

```
NEW / WAITING
  ↓ Deposit sent and detected
CONFIRMING
  ↓ Blockchain confirmations received
EXCHANGING
  ↓ CEX processes the swap
FINISHED
```

> [!TIP]
>
> Poll every 30 seconds. Standard swaps typically complete in 3–30 minutes. For real-time updates without polling, use the [WebSocket API](https://docs.houdini.com/developer-hub/core-concepts/websocket-order-updates.md).

## Best Practices

> [accordion] Token Fetching
>
> * **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.

> [accordion] Transaction Monitoring
>
> * Poll `/orders/{houdiniId}` every 30 seconds
> * Store `houdiniId` for future reference and support lookups
> * Handle all `statusLabel` values: FINISHED, FAILED, EXPIRED, REFUNDED

> [accordion] Error Handling
>
> * Re-fetch quotes if quote is expired before calling `/exchanges`
> * Validate `addressTo` format before submitting
> * Implement retry logic with backoff for API calls

> [accordion] Security
>
> * 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

> [accordion] Swap Taking Longer Than Expected
>
> **Causes**: Network congestion, CEX processing delays, slow block confirmations.
>
> **Solution**: Continue monitoring. Most swaps complete within 2× the estimated time.

> [accordion] Wrong Amount Deposited
>
> **Issue**: User sent an incorrect amount to the deposit address.
>
> **Solution**: A partial refund may be processed. Contact support with the `houdiniId`.

> [accordion] Order Expired
>
> **Cause**: Deposit was not received before the `expires` timestamp.
>
> **Solution**: Fetch a new quote and create a new order.

> [accordion] Status Stuck at CONFIRMING
>
> **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:

> [card] [Next.js Example](https://github.com/HoudiniSwap/houdini-api-examples/tree/main/nextjs-example)
>
> Full Next.js integration showing standard, private, and DEX swap flows

> [card] [Node.js Example](https://github.com/HoudiniSwap/houdini-api-examples/tree/main/node-examples)
>
> Backend Node.js integration with token fetching, quoting, and order tracking

## Next Steps

> [card] [Private Swap](https://docs.houdini.com/developer-hub/swap-flows/private-swap.md)
>
> Multi-hop privacy swaps

> [card] [DEX Swap](https://docs.houdini.com/developer-hub/swap-flows/dex-swap.md)
>
> On-chain decentralized swaps

> [card] [Fixed Rate & Reverse Quote](https://docs.houdini.com/developer-hub/swap-flows/fixed-rate-swap.md)
>
> Guarantee the output amount, or specify what the recipient receives

> [card] [Order Lifecycle](https://docs.houdini.com/developer-hub/core-concepts/order-lifecycle.md)
>
> Understand all order statuses

> [card] [Error Handling](https://docs.houdini.com/developer-hub/troubleshooting/errors.md)
>
> Handle errors and edge cases


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