Quotes & Estimates
Two routes with the same body:
| Route | Purpose |
|---|---|
POST /crypto/quotes | Generates a quote with quoteId and guaranteed price for quoteTtlSeconds (30 s), to use in purchase. Requesting without executing is free. |
POST /crypto/quotes/estimate | Simple estimate: does not generate quoteId and nothing is reserved. Used to show the approximate amount ("≈") before buying. |
Endpoint
- Method: POST
Quote
https://api.xgateglobal.com/crypto/quotes
Estimate
https://api.xgateglobal.com/crypto/quotes/estimate
Request
Required Headers
| Header | Value | Description |
|---|---|---|
Authorization | Bearer <your_token> | The JWT token obtained at login. |
Body (Request Body)
| Field | Type | Required | Description |
|---|---|---|---|
asset | string | Yes | USDT or USDC. |
network | string | Yes | POLYGON, ETHEREUM, TRON, or SOLANA (according to asset). |
amount | string | Yes | Total in BRL to be debited from balance, string with 2 decimal places (e.g. "1500.00"). |
{
"asset": "USDT",
"network": "TRON",
"amount": "1500.00"
}
Price with built-in spread
The amount is the total in BRL debited from your balance. The unit rate (rate) already includes the commercial spread. There are no additional fees charged — only the network gas fee (networkFee) is deducted from the crypto delivered.
Responses
Success
POST /crypto/quotes responds with 201 Created:
{
"quoteId": "l3m8Qm1n0pV2cXk5dY9sTg4hWz7aB6eR1uJ0oK2qF3i",
"expiresAt": "2026-10-13T14:03:52.114Z",
"asset": "USDT",
"network": "TRON",
"amount": "1500.00",
"rate": "5.45400000",
"cryptoAmount": "275.027502",
"networkFee": "0.012000",
"deliveredAmount": "275.015502"
}
POST /crypto/quotes/estimate responds with 200 OK with the same fields, without quoteId and expiresAt, and containing estimatedAt (timestamp of the estimate).
Field Description
| Field | Type | Description |
|---|---|---|
quoteId | string | (Quote only) Identifier to use in POST /crypto/purchases. |
expiresAt | string | (Quote only) Expiration timestamp of the guaranteed price. |
estimatedAt | string | (Estimate only) Timestamp of the estimate. |
asset, network | string | Quoted asset and network. |
amount | string | Total in BRL to be debited. |
rate | string | Price of 1 unit of asset in BRL (8 decimal places), with spread already included. |
cryptoAmount | string | Gross quantity purchased (6 decimal places): amount ÷ rate. |
networkFee | string | Network gas fee, deducted from delivery. |
deliveredAmount | string | Final quantity that reaches the wallet: cryptoAmount − networkFee. |
How the amount is calculated
cryptoAmount = amount ÷ rate (rounded down, 6 decimals)
deliveredAmount = cryptoAmount − networkFee
Common Errors
| Status | Reason |
|---|---|
| 400 | VALIDATION_FAILED, AMOUNT_MUST_BE_STRING |
| 401 | UNAUTHORIZED |
| 403 | PERMISSION_DENIED, COMPANY_MISMATCH, COMPANY_BLOCKED, ALLOWED_IPS_REQUIRED, CLIENT_IP_NOT_ALLOWED, CRYPTO_DISABLED, CRYPTO_API_DISABLED, BUY_DISABLED |
| 422 | ASSET_NOT_SUPPORTED, NETWORK_NOT_SUPPORTED, AMOUNT_BELOW_MIN, AMOUNT_ABOVE_MAX, AMOUNT_TOO_LOW_FOR_NETWORK_FEE, PRICE_UNSTABLE |
| 429 | RATE_LIMITED |
| 503 | PRICE_STALE, NETWORK_FEE_UNAVAILABLE, CONFIGURATION_UNAVAILABLE, SERVICE_OVERLOADED |
See the meaning of each code in Error Codes.
Integration
- Node.js
const axios = require("axios");
(async () => {
const email = "your_email@domain.com";
const password = "**********";
try {
const url_api = "https://api.xgateglobal.com";
const login = await axios.post(`${url_api}/auth/token`, { email, password });
const headers = { "Authorization": `Bearer ${login.data.token}` };
const body = { asset: "USDT", network: "TRON", amount: "1500.00" };
// Estimate (nothing is reserved)
const estimate = await axios.post(`${url_api}/crypto/quotes/estimate`, body, { headers });
console.log("≈", estimate.data.deliveredAmount, estimate.data.asset);
// Quote with guaranteed price for 30 seconds
const quote = await axios.post(`${url_api}/crypto/quotes`, body, { headers });
console.log(quote.data.quoteId, quote.data.expiresAt);
} catch (error) {
console.log(error.response.data.reason, error.response.data.message); // Error
}
})()