- Tokens: Use token
id values to request quotes via /quotes for all swap types (standard, private, DEX).
- Networks: Use network data for UI display (logos, names, explorer links) and address validation.
Tokens
Token Identifiers
In API v2, both CEX and DEX tokens are fetched from the same /tokens endpoint. Every token has a single id field (MongoDB ObjectId format) used in all quote requests.
- CEX Tokens — filter with
hasCex=true (used for standard and private swaps)
- DEX Tokens — filter with
hasDex=true (used for on-chain DEX swaps)
Token Fields
| Field | Type | Description | Example |
|---|
id | string | Required for /quotes — Unique token identifier | "6689b73ec90e45f3b3e51566" |
symbol | string | Token ticker symbol | "ETH" |
name | string | Full token name | "Ethereum" |
address | string | Token contract address | "0x0000...0000" |
chain | string | Blockchain network shortName | "ethereum" |
decimals | number | Token decimals | 18 |
icon | string | Token logo URL | "https://api.houdiniswap.com/assets/..." |
hasDex | boolean | Available for DEX swaps | true |
hasCex | boolean | Available for CEX swaps | true |
enabled | boolean | Whether token is available for swaps | true |
price | number | Current USD price | 2937 |
Trading Limits
"minMax": {
"cex": { "min": 0.0253712625, "max": 16.914175 },
"dex": { "min": 0.005, "max": 50 },
"private": { "min": 0.0845708751, "max": 16.914175 }
}
cex: min/max for standard CEX swaps
dex: min/max for DEX swaps
private: min/max for private/anonymous swaps
Always use the id field (ObjectId format) when passing tokens to /quotes. Passing symbols will not work.
Fetching Tokens
There are two approaches — choose the one that fits your integration:
Bulk Fetch + Cache (Recommended for Production)
Paginate through all tokens and store in your database. Refresh every 24 hours.
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
}
async function fetchAllDexTokens() {
let page = 1;
let allTokens = [];
while (true) {
const response = await fetch(
`https://api-partner.houdiniswap.com/v2/tokens?hasDex=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
}
Token Search (On-Demand)
Search by name or symbol using the term parameter.
async function searchTokens(query, type = 'hasCex') {
const params = new URLSearchParams({
term: query, // e.g. "ethereum" or "ETH"
[type]: '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
}
Query Parameters:
| Parameter | Description |
|---|
hasCex | Filter to CEX-supported tokens |
hasDex | Filter to DEX-supported tokens |
term | Search by name, symbol, or address |
chain | Filter by chain shortName (e.g. "ethereum") |
page | Page number (default: 1) |
pageSize | Results per page (max: 100, default: 20) |
Example Response:
{
"tokens": [
{
"id": "6689b73ec90e45f3b3e51566",
"symbol": "ETH",
"name": "Ethereum",
"address": "0x0000000000000000000000000000000000000000",
"chain": "ethereum",
"decimals": 18,
"icon": "https://api.houdiniswap.com/assets/tokens/ETH.png",
"hasCex": true,
"hasDex": true,
"enabled": true,
"price": 2937,
"minMax": {
"cex": { "min": 0.0253712625, "max": 16.914175 },
"dex": { "min": 0.005, "max": 50 },
"private": { "min": 0.0845708751, "max": 16.914175 }
}
}
],
"total": 1,
"totalPages": 1
}
Using Token IDs in Quotes
Pass the id from the token response as from and to parameters in /quotes:
// ETH token id from /tokens response
const ethId = '6689b73ec90e45f3b3e51566';
// SOL token id from /tokens response
const solId = '6689b73ec90e45f3b3e51577';
const params = new URLSearchParams({
amount: '1',
from: ethId,
to: solId,
types: 'standard' // or 'private', 'dex'
});
const response = await fetch(
`https://api-partner.houdiniswap.com/v2/quotes?${params}`,
{
headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
}
);
const { quotes } = await response.json();
Networks (Chains)
Chain Identifiers
Houdini exposes supported blockchain networks via the /chains endpoint. Use shortName to filter tokens by chain and for address validation.
| Field | Type | Description | Example |
|---|
id | string | Unique chain identifier | "507f1f77bcf86cd799439011" |
name | string | Full network name | "Ethereum Mainnet" |
shortName | string | Short name — use for chain filtering | "ethereum" |
chainId | number | EVM chain ID (EVM chains only) | 1 |
kind | string | Network type | "evm" |
memoNeeded | boolean | Whether a memo/tag is required | false |
explorerUrl | string | Transaction explorer URL template | "https://etherscan.io/tx/{txHash}" |
addressUrl | string | Address explorer URL template | "https://etherscan.io/address/{address}" |
addressValidation | string | Regex for validating wallet addresses | "^(0x)[0-9A-Za-z]{40}$" |
Fetching Chains
const response = await fetch(
'https://api-partner.houdiniswap.com/v2/chains',
{
headers: { 'Authorization': `${API_KEY}:${API_SECRET}` }
}
);
const { chains } = await response.json();
const enabledChains = chains.filter(c => c.enabled ?? true);
Query Parameters:
| Parameter | Description |
|---|
hasCex | Filter to chains supporting CEX swaps |
hasDex | Filter to chains supporting DEX swaps |
kind | Filter by type: "evm", "solana", "bitcoin", etc. |
name | Search by name or shortName |
page / pageSize | Pagination |
Example Response:
{
"chains": [
{
"id": "507f1f77bcf86cd799439011",
"name": "Ethereum Mainnet",
"shortName": "ethereum",
"chainId": 1,
"kind": "evm",
"memoNeeded": false,
"explorerUrl": "https://etherscan.io/tx/{txHash}",
"addressUrl": "https://etherscan.io/address/{address}",
"addressValidation": "^(0x)[0-9A-Za-z]{40}$",
"tokenAddressValidation": "^(0x)[0-9A-Za-z]{40}$"
}
],
"total": 1,
"totalPages": 1
}
Using Networks
Validate Addresses
Use the addressValidation regex to validate user input before submitting:
function validateAddress(chain, address) {
const regex = new RegExp(chain.addressValidation);
if (!regex.test(address)) {
throw new Error(`Invalid address for ${chain.name}`);
}
return true;
}
Generate Explorer Links
function getTransactionUrl(chain, txHash) {
return chain.explorerUrl.replace('{txHash}', txHash);
}
function getAddressUrl(chain, address) {
return chain.addressUrl.replace('{address}', address);
}
Check Memo Requirements
function checkMemoRequirement(chain) {
if (chain.memoNeeded) {
return { required: true, message: `${chain.name} requires a memo/tag` };
}
return { required: false };
}
Next Steps