Request a MultiversX swap quote and, when sender is present, receive transaction data for signing.
Endpoint
| Field | Value |
|---|
| Method | GET |
| Path | /api/v1/quote |
| Base URL | https://swap.xoxno.com |
| Auth | None |
| Availability | Public |
| Rate limit | 100 requests per second per IP |
Required Params
| Param | Type | Description |
|---|
from | string | Input token identifier, for example WEGLD-bd4d79. |
to | string | Output token identifier, for example USDC-c76f1f. |
amountIn or amountOut | string | Exactly one amount, encoded as an integer string in the token’s smallest unit. |
Optional Params
| Param | Type | Default | Description |
|---|
slippage | number | 0.01 | Decimal slippage tolerance. 0.01 means 1%. |
sender | string | none | Bech32 sender. When set, the response can include a full transaction object. |
includePaths | boolean | false | Include paths[] route breakdown. |
maxSplits | number | 6 | Maximum route splits. |
maxHops | number | 6 | Maximum swaps per path. |
algorithm | string | hybrid | greedy, lagrangian, or hybrid. |
referralId | number | 0 | Referral identifier for fee attribution. |
maxBuiltinCalls | number | none | Cap smart contract calls in the generated transaction. |
includeLpRoutes | boolean | false | Allow LP tokens as intermediate hops. Enabled automatically when from or to is an LP token. |
Convert human-readable amounts to smallest unit strings before quoting. Use /api/v1/pair-config to read decimals and minAmountIn.
Request
cURL
TypeScript
Python
Rust
curl "https://swap.xoxno.com/api/v1/quote?\
from=WEGLD-bd4d79&\
to=USDC-c76f1f&\
amountIn=1000000000000000000&\
slippage=0.005&\
includePaths=true"
const params = new URLSearchParams({
from: "WEGLD-bd4d79",
to: "USDC-c76f1f",
amountIn: "1000000000000000000",
slippage: "0.005",
includePaths: "true",
});
const res = await fetch(`https://swap.xoxno.com/api/v1/quote?${params}`);
if (!res.ok) throw new Error(`quote failed: ${res.status}`);
const quote = await res.json();
console.log(quote.amountOut, quote.amountOutMin);
import httpx
res = httpx.get(
"https://swap.xoxno.com/api/v1/quote",
params={
"from": "WEGLD-bd4d79",
"to": "USDC-c76f1f",
"amountIn": "1000000000000000000",
"slippage": "0.005",
"includePaths": "true",
},
timeout=10,
)
res.raise_for_status()
quote = res.json()
print(quote["amountOut"], quote["amountOutMin"])
use reqwest::Client;
use serde_json::Value;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let quote: Value = Client::new()
.get("https://swap.xoxno.com/api/v1/quote")
.query(&[
("from", "WEGLD-bd4d79"),
("to", "USDC-c76f1f"),
("amountIn", "1000000000000000000"),
("slippage", "0.005"),
("includePaths", "true"),
])
.send()
.await?
.error_for_status()?
.json()
.await?;
println!("{} {}", quote["amountOut"], quote["amountOutMin"]);
Ok(())
}
Success Response
{
"amountIn": "1000000000000000000",
"amountOut": "42500000",
"amountOutMin": "42287500",
"amountInShort": 1,
"amountOutShort": 42.5,
"amountOutMinShort": 42.2875,
"priceImpact": 0.0021,
"rate": 42.5,
"rateInverse": 0.023529,
"paths": [
{
"amountIn": "1000000000000000000",
"amountOut": "42500000",
"splitPpm": 1000000,
"swaps": [
{
"dex": "xExchange",
"pool": "erd1...",
"tokenIn": "WEGLD-bd4d79",
"tokenOut": "USDC-c76f1f"
}
]
}
]
}
Response Fields
| Field | Type | Description |
|---|
amountIn | string | Input amount in smallest units. |
amountOut | string | Expected output amount in smallest units. |
amountOutMin | string | Minimum output after slippage, in smallest units. |
amountInShort | number | Human-readable input amount. |
amountOutShort | number | Human-readable output amount. |
priceImpact | number | Estimated price impact as a decimal. |
rate | number | Output units per input unit. |
rateInverse | number | Input units per output unit. |
paths[] | array | Returned only when includePaths=true. |
txData | string | Encoded contract call data when a full transaction object is not returned. |
transaction | object | Full transaction object when sender is set and transaction building succeeds. |
Transaction Data
Pass sender when the user is ready to sign. The service fetches nonce, simulates gas, and returns a transaction object when those steps complete within the service timeout.
curl "https://swap.xoxno.com/api/v1/quote?\
from=WEGLD-bd4d79&\
to=USDC-c76f1f&\
amountIn=1000000000000000000&\
sender=erd1..."
If nonce fetch or simulation exceeds 8 seconds, the response falls back to txData without transaction.
Do not reuse txData across quote requests. It encodes route and slippage state from that request.
Errors
| Status | Cause | Fix |
|---|
400 | Missing from, to, or amount; both amount fields set; invalid token format. | Fix query params and retry. |
404 | No route for the pair. | Call /api/v1/pair-config and show the unsupported pair state. |
422 | Route exists, but transaction construction or simulation failed. | Retry with lower maxSplits, lower maxHops, or without sender for pricing only. |
429 | Per-IP rate limit exceeded. | Back off and queue requests client-side. |
503 | Service is warming up or pool snapshot is unavailable. | Retry with backoff. |
Edge Cases
| Case | Behavior | Client handling |
|---|
from equals to | The endpoint searches for same-token arbitrage cycles. | Treat the result as an arbitrage route, not a swap quote. |
ESDT input with only txData | txData is not the full transaction data field. | Wrap it with the correct ESDT transfer prefix. |
| Large route | More splits and hops can increase response time and gas. | Cap maxSplits and maxHops for wallet flows. |
| High-frequency polling | Path details increase response size. | Keep includePaths=false. |
Verify
Before signing:
amountOutMin matches the slippage shown to the user.
transaction.sender equals the current wallet when transaction is present.
- Token amounts are smallest unit strings.
- The quote was generated after the latest user change to token, amount, slippage, or sender.