curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"fromChain": "<string>",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"refundAddress": "<string>"
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route"
payload = {
"fromChain": "<string>",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"refundAddress": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fromChain: '<string>',
fromToken: '<string>',
fromAmount: '<string>',
fromAddress: '<string>',
refundAddress: '<string>'
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route",
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([
'fromChain' => '<string>',
'fromToken' => '<string>',
'fromAmount' => '<string>',
'fromAddress' => '<string>',
'refundAddress' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route"
payload := strings.NewReader("{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"state": "ready",
"accountId": "<string>",
"routeId": "<string>",
"quoteId": "<string>",
"expiresAtEpochMs": 123,
"fromChainId": "<string>",
"toChainId": "1",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"transactionRequest": {
"target": "<string>",
"data": "<string>",
"value": "<string>",
"gasLimit": "<string>"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}Prepare an account-owned Squid route
Checks the source wallet’s Ethereum USDC allowance to the verified Squid Router before preparing an unsigned route to the account’s xReserve recipient. Insufficient allowance returns approval_required with exact-amount manual approval metadata; an unknown allowance returns unavailable. Unsupported source verification returns unavailable. The source wallet receives any source-chain refund. The route expires after 120 seconds. No approval or funds are signed, sent or credited. A source token other than Ethereum USDC, an unlimited amount or a Squid route this server does not accept answers 409 command_rejected with its squidRouteRefusal; do not retry the same request. Each account holds one Squid request at a time and at most 6 per minute, and all accounts share Squid’s request quota; past either bound the route answers 429 rate_limited with squidRouteRefusal account_request_bound or global_request_bound and a Retry-After header, in seconds, before Squid is called. A Squid outage answers 503 dependency_unavailable with dependency squid; retry later.
Method and path: POST /v1/accounts//squid-route
Authentication: DFNS trader bearer required.
Request schema: SquidHandoffRequest.
Response schema: SquidHandoffResponse.
Error envelope: ExternalRestError (external-rest-error/v1).
curl --request POST \
--url https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"fromChain": "<string>",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"refundAddress": "<string>"
}
'import requests
url = "https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route"
payload = {
"fromChain": "<string>",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"refundAddress": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fromChain: '<string>',
fromToken: '<string>',
fromAmount: '<string>',
fromAddress: '<string>',
refundAddress: '<string>'
})
};
fetch('https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route', 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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route",
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([
'fromChain' => '<string>',
'fromToken' => '<string>',
'fromAmount' => '<string>',
'fromAddress' => '<string>',
'refundAddress' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route"
payload := strings.NewReader("{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://testnet.edel-api.xyz/v1/accounts/{accountId}/squid-route")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromChain\": \"<string>\",\n \"fromToken\": \"<string>\",\n \"fromAmount\": \"<string>\",\n \"fromAddress\": \"<string>\",\n \"refundAddress\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"state": "ready",
"accountId": "<string>",
"routeId": "<string>",
"quoteId": "<string>",
"expiresAtEpochMs": 123,
"fromChainId": "<string>",
"toChainId": "1",
"fromToken": "<string>",
"fromAmount": "<string>",
"fromAddress": "<string>",
"transactionRequest": {
"target": "<string>",
"data": "<string>",
"value": "<string>",
"gasLimit": "<string>"
}
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}{
"version": "external-rest-error/v1",
"requestId": "<string>",
"code": "promo_code_unknown",
"safeMessage": "<string>",
"retryable": true,
"recoveryActions": [
"none"
],
"occurredAtEpochMs": 1,
"orderOutcome": "not_submitted",
"clientOrderIds": [
"<string>"
],
"reconciliation": "<string>",
"realtimeTicketFailure": "invalid",
"apiKeyRejection": "malformed",
"agentRefusal": "agents_not_admitted_in_environment",
"rejectionGuard": "custodial_signer_environment_not_service_held",
"withdrawalFailure": "requested",
"feeShareAcceptRefusal": "challenge_missing",
"dependency": "dfns",
"squidRouteRefusal": "route_not_found"
}Authorizations
The authorization field takes the session bearer returned by sign-in, or an API key where the route allows keys. Paste the token itself into the authorization field. When invitation-only access is enabled, private operations require the account's sign-in email to be invited. Sign-in can complete without an invitation, but private HTTP, MCP and FIX operations refuse with access_not_allowlisted (HTTP 403): "Private access is limited to invited accounts. Contact support to request access." Public market data remains available. Invitation changes apply to the next private operation, including existing FIX sessions. Do not retry until support confirms access.
Path Parameters
1Body
Source EVM chain ID. A source without configured transaction verification is unavailable.
^[1-9]\d{0,15}$Source token contract address, validated against the provider route.
^0x[0-9a-fA-F]{40}$Positive uint256 amount in source-token base units.
^[1-9]\d{0,77}$The source wallet that signs the transaction and receives source-chain refunds.
^0x[0-9a-fA-F]{40}$Must match fromAddress, ignoring case; a separate refund recipient is unsupported.
^0x[0-9a-fA-F]{40}$Response
Success
- Option 1
- Option 2
- Option 3
"ready"1^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$1 - 256^[1-9]\d{0,15}$"1"^0x[0-9a-fA-F]{40}$^[1-9]\d{0,77}$^0x[0-9a-fA-F]{40}$Show child attributes
Show child attributes