curl --request POST \
--url https://api-partner.houdiniswap.com/v2/exchanges \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"addressTo": "<string>",
"quoteId": "<string>",
"addressFrom": "<string>",
"refundAddress": "<string>",
"refundExtraId": "<string>",
"signatures": [
{
"signature": "<string>",
"key": "<string>",
"swapRequiredMetadata": {}
}
],
"destinationTag": "<string>",
"walletInfo": "<string>"
}
'import requests
url = "https://api-partner.houdiniswap.com/v2/exchanges"
payload = {
"addressTo": "<string>",
"quoteId": "<string>",
"addressFrom": "<string>",
"refundAddress": "<string>",
"refundExtraId": "<string>",
"signatures": [
{
"signature": "<string>",
"key": "<string>",
"swapRequiredMetadata": {}
}
],
"destinationTag": "<string>",
"walletInfo": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
addressTo: '<string>',
quoteId: '<string>',
addressFrom: '<string>',
refundAddress: '<string>',
refundExtraId: '<string>',
signatures: [{signature: '<string>', key: '<string>', swapRequiredMetadata: {}}],
destinationTag: '<string>',
walletInfo: '<string>'
})
};
fetch('https://api-partner.houdiniswap.com/v2/exchanges', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-partner.houdiniswap.com/v2/exchanges",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'addressTo' => '<string>',
'quoteId' => '<string>',
'addressFrom' => '<string>',
'refundAddress' => '<string>',
'refundExtraId' => '<string>',
'signatures' => [
[
'signature' => '<string>',
'key' => '<string>',
'swapRequiredMetadata' => [
]
]
],
'destinationTag' => '<string>',
'walletInfo' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-partner.houdiniswap.com/v2/exchanges"
payload := strings.NewReader("{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-partner.houdiniswap.com/v2/exchanges")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-partner.houdiniswap.com/v2/exchanges")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"houdiniId": "example-houdini-id",
"created": "2026-01-01T12:00:00.000Z",
"depositAddress": "bc1qexampledepositaddress000000000000000000",
"receiverAddress": "0x9f1f9a5c0f1d9a5c0f1d9a5c0f1d9a5c0f1d9a5c",
"anonymous": false,
"expires": "2026-01-01T12:30:00.000Z",
"status": 0,
"inAmount": 0.25,
"inSymbol": "BTC",
"outAmount": 3.52,
"outSymbol": "ETH",
"displayStatus": "WAITING_FOR_DEPOSIT"
}{
"message": "<string>",
"code": "<string>",
"requestId": "<string>"
}{
"message": "<string>",
"code": "<string>",
"fields": {},
"requestId": "<string>"
}{
"message": "<string>",
"code": "<string>",
"requestId": "<string>"
}Create exchange
Create a new exchange (swap). Use type: "private" or type: "standard" for centralized exchanges or type: "dex" for decentralized exchanges.
curl --request POST \
--url https://api-partner.houdiniswap.com/v2/exchanges \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"addressTo": "<string>",
"quoteId": "<string>",
"addressFrom": "<string>",
"refundAddress": "<string>",
"refundExtraId": "<string>",
"signatures": [
{
"signature": "<string>",
"key": "<string>",
"swapRequiredMetadata": {}
}
],
"destinationTag": "<string>",
"walletInfo": "<string>"
}
'import requests
url = "https://api-partner.houdiniswap.com/v2/exchanges"
payload = {
"addressTo": "<string>",
"quoteId": "<string>",
"addressFrom": "<string>",
"refundAddress": "<string>",
"refundExtraId": "<string>",
"signatures": [
{
"signature": "<string>",
"key": "<string>",
"swapRequiredMetadata": {}
}
],
"destinationTag": "<string>",
"walletInfo": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
addressTo: '<string>',
quoteId: '<string>',
addressFrom: '<string>',
refundAddress: '<string>',
refundExtraId: '<string>',
signatures: [{signature: '<string>', key: '<string>', swapRequiredMetadata: {}}],
destinationTag: '<string>',
walletInfo: '<string>'
})
};
fetch('https://api-partner.houdiniswap.com/v2/exchanges', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-partner.houdiniswap.com/v2/exchanges",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'addressTo' => '<string>',
'quoteId' => '<string>',
'addressFrom' => '<string>',
'refundAddress' => '<string>',
'refundExtraId' => '<string>',
'signatures' => [
[
'signature' => '<string>',
'key' => '<string>',
'swapRequiredMetadata' => [
]
]
],
'destinationTag' => '<string>',
'walletInfo' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-partner.houdiniswap.com/v2/exchanges"
payload := strings.NewReader("{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-partner.houdiniswap.com/v2/exchanges")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-partner.houdiniswap.com/v2/exchanges")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"addressTo\": \"<string>\",\n \"quoteId\": \"<string>\",\n \"addressFrom\": \"<string>\",\n \"refundAddress\": \"<string>\",\n \"refundExtraId\": \"<string>\",\n \"signatures\": [\n {\n \"signature\": \"<string>\",\n \"key\": \"<string>\",\n \"swapRequiredMetadata\": {}\n }\n ],\n \"destinationTag\": \"<string>\",\n \"walletInfo\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"houdiniId": "example-houdini-id",
"created": "2026-01-01T12:00:00.000Z",
"depositAddress": "bc1qexampledepositaddress000000000000000000",
"receiverAddress": "0x9f1f9a5c0f1d9a5c0f1d9a5c0f1d9a5c0f1d9a5c",
"anonymous": false,
"expires": "2026-01-01T12:30:00.000Z",
"status": 0,
"inAmount": 0.25,
"inSymbol": "BTC",
"outAmount": 3.52,
"outSymbol": "ETH",
"displayStatus": "WAITING_FOR_DEPOSIT"
}{
"message": "<string>",
"code": "<string>",
"requestId": "<string>"
}{
"message": "<string>",
"code": "<string>",
"fields": {},
"requestId": "<string>"
}{
"message": "<string>",
"code": "<string>",
"requestId": "<string>"
}Authorizations
Body
Request body for creating a new exchange
Destination wallet address where funds will be sent
1 - 200Quote ID from a prior quote response. Amount, from token, to token, and swap provider are retrieved from the provided quote. For CEX exchanges, if the exchange fails with the chosen swap provider, it will fallback to the next best route.
Source wallet address (required for DEX, ignored for CEX)
Sender's wallet address for refunds if a fixed-rate swap fails. Required when the quote was created with fixed: true.
200Memo/tag for refundAddress on memo-bearing chains (e.g. XRP DestinationTag, Stellar memo, TON comment). Ignored when the destination chain has no memo concept.
64EIP-712 signatures for permit-based approvals (DEX only)
Show child attributes
Show child attributes
Destination tag / memo (e.g. for XRP, XLM)
64Wallet info string
256Response
Exchange created
The CEX deposit address where the user must send funds
- -2 Order is being initialized (label: INITIALIZING)
- -1 Order initialized (label: NEW)
- 0 Waiting for deposit confirmation (label: WAITING)
- 1 Deposit is being confirmed (label: CONFIRMING)
- 2 Exchange is in progress (label: EXCHANGING)
- 3 Order is going through anonymization (label: ANONYMIZING)
- 4 Order completed successfully (label: FINISHED)
- 5 Order has expired (label: EXPIRED)
- 6 Order failed (label: FAILED)
- 7 Order was refunded (label: REFUNDED)
- 8 Order was deleted (label: DELETED)
-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8 ETA time, depending on swap
USD value of the input amount at order creation time.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
- 0 New swap
- 1 Waiting for confirmation
- 2 Being confirmed
- 3 Exchange in progress
- 4 Sending to destination
- 5 Swap completed
- 6 Swap failed
- 7 Swap refunded
- 8 Verifying swap
- 9 Swap expired
- 10 Fallback mode
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 - 0 New swap
- 1 Waiting for confirmation
- 2 Being confirmed
- 3 Exchange in progress
- 4 Sending to destination
- 5 Swap completed
- 6 Swap failed
- 7 Swap refunded
- 8 Verifying swap
- 9 Swap expired
- 10 Fallback mode
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 WAITING_FOR_DEPOSIT, DEPOSIT_DETECTED, EXCHANGE_IN_PROGRESS, SENDING_TO_INTERMEDIARY, REACHED_INTERMEDIARY, INITIATING_SECOND_EXCHANGE, SECOND_EXCHANGE_IN_PROGRESS, SENDING_TO_RECEIVER, SWAP_COMPLETED, EXPIRED, FAILED, REFUNDED, DELETED Memo/tag required when depositing funds for assets that use one
True when the route that executed is not the one that was quoted,
because the quoted route failed and a fallback was used. The amounts may
differ from the quote — compare inAmount against quotedInAmount and
outAmount against quotedOutAmount.
The deposit amount originally quoted, present only when the order was
rerouted. inAmount is what the fallback route actually asks for; on an
exact-out order this is the side that moves.
The payout originally quoted, present only when the order was rerouted.
outAmount is what the fallback route will actually pay; on an exact-in
order this is the side that moves.
Memo/tag required when receiving funds for assets that use one