A practical guide to simulating a TON swap, reading the returned price data, and carrying the quote safely into transaction construction.
If your application needs to ey sign a swap, STON.fi exposes a direct way to request that information: POST https://api.ston.fi/v1/swap/simulate. STON.fi calls the operation a swap simulation, but in a wallet, trading interface, bot, or backend it serves the role of a swap quote. You provide the asset being sold, the asset being bought, the amount in blockchain units, and a slippage tolerance. The API returns the expected output together with minimum output, fees, price impact, gas information, pool data, and the Router that should be used if you continue to execution.
The critical detail is that the quote is not just a price. It is routing and execution context for a specific swap at a specific moment.
What a STON.fi swap quote actually gives you
A DEX quote answers a more useful question than "What is token A worth in token B?" It asks, "If I sell this exact amount through the liquidity available now, what should the swap produce?"
STON.fi's DEX API exposes this through /v1/swap/simulate. The official API reference describes the endpoint as a pre-execution simulation that calculates expected output, fees, and gas costs. The current response schema also includes price_impact, min_ask_units, recommended_min_ask_units, recommended_slippage_tolerance, pool information, and a complete router object. ion matters because an AMM quote depends on the input size and pool state. Two requests for the same pair can return different results if the amount changes or if liquidity changes between requests.
For a typical interface, the quote should give you enough data to display:
- expected amount received
- minimum acceptable amount received
- swap rate
- price impact
- protocol or swap fee information
- estimated gas parameters
- selected pool and Router
A simulation does not execute anything on-chain. No wallet signature is required merely to ask the API for the quote.
The four inputs you need
For a direct swap simulation, four values are essential: the asset you are selling, the asset you want to receive, the amount being sold, and the slippage tolerance. The raw REST endpoint uses snake_case query parameters, while the official TypeScript client exposes camelCase properties. The client then maps them to the REST request.
| Purpose | Raw REST parameter |
@ston-fi/api property |
|---|---|---|
| Asset to sell | offer_address |
offerAddress |
| Asset to receive | ask_address |
askAddress |
| Amount to sell | units |
offerUnits |
| Slippage tolerance | slippage_tolerance |
slippageTolerance |
The REST endpoint also supports optional parameters such as pool_address, referral settings, and DEX version restrictions. For a basic quote request, start with the four required values and add optional routing constraints only when your application has a reason to control them.
One implementation detail is easy to miss: this is a POST endpoint, but the documented swap inputs are query parameters. The official @ston-fi/api client does the same internally when it calls /v1/swap/simulate. The amount to blockchain units first
units does not mean a human-readable amount such as "1.5" unless the token happens to use zero decimals. It means the smallest indivisible units of the offered asset.
TON jettons can use different decimal precision. TON documentation explicitly warns developers not to assume that every jetton has the same decimals value. For example, many assets use 9 decimals, while USDT on TON uses 6. An incorrect decimal conversion can change the intended amount by orders of magnitude. And is conceptually:
blockchain units = display amount * 10^decimals
For production code, avoid ordinary JavaScript floating-point arithmetic for token amounts. A simple string-based conversion can keep the calculation exact:
function toUnits(amount, decimals) {
const [whole, fraction = ""] = amount.split(".");
const padded = (fraction + "0".repeat(decimals)).slice(0, decimals);
return (
BigInt(whole) * 10n ** BigInt(decimals) +
BigInt(padded || "0")
).toString();
}
const offerUnits = toUnits("1.5", 9);
// "1500000000"
Fetch the asset's real decimal precision from trusted metadata rather than hardcoding 9. If your project already uses STON.fi tooling, use the metadata returned for the selected asset and keep amounts as strings or integers until you format them for display.
Request the quote with the raw REST API
At the HTTP level, the request is small. You can call the production API directly with fetch, curl, or any HTTP client.
A generic curl request looks like this:
curl -X POST \
"https://api.ston.fi/v1/swap/simulate?offer_address=<OFFER_ASSET>&ask_address=<ASK_ASSET>&units=<OFFER_UNITS>&slippage_tolerance=0.01" \
-H "accept: application/json"
In JavaScript, building the query parameters explicitly makes the request easier to inspect:
const offerAddress = "<OFFER_ASSET>";
const askAddress = "<ASK_ASSET>";
const offerUnits = "<AMOUNT_IN_SMALLEST_UNITS>";
const params = new URLSearchParams({
offer_address: offerAddress,
ask_address: askAddress,
units: offerUnits,
slippage_tolerance: "0.01",
});
const response = await fetch(
`https://api.ston.fi/v1/swap/simulate?${params.toString()}`,
{ method: "POST" }
);
if (!response.ok) {
throw new Error(`STON.fi quote failed: ${response.status}`);
}
const quote = await response.json();
console.log(quote);
The 0.01 value represents 1 percent slippage tolerance. STON.fi's official TypeScript client currently documents 0.01 as a recommended value, while the simulation response can also return a recommended_slippage_tolerance. Treat slippage as a transaction protection setting, not as another name for price impact. plication, wrap the call in normal network error handling, validate the response shape, and reject zero or malformed amounts before sending the request.
Use the official TypeScript client when possible
If you are already working in TypeScript or JavaScript, @ston-fi/api removes most of the raw HTTP plumbing. The package is the official TypeScript client for the STON.fi HTTP API and exposes simulateSwap() directly.
npm install @ston-fi/api
`
Then request a quote:
`ts
import { StonApiClient } from "@ston-fi/api";
const client = new StonApiClient();
const quote = await client.simulateSwap({
offerAddress: "",
askAddress: "",
offerUnits: "",
slippageTolerance: "0.01",
});
console.log({
expectedOutput: quote.askUnits,
minimumOutput: quote.minAskUnits,
priceImpact: quote.priceImpact,
swapRate: quote.swapRate,
router: quote.router,
});
There is one naming difference worth remembering. The raw REST response uses fields such as ask_units and min_ask_units; the client normalizes API responses into camelCase, so your TypeScript code reads askUnits and minAskUnits. The official client source and response types make this mapping visible. applications, this client is the cleaner option because it gives you a stable application-facing interface while still using the same STON.fi REST API underneath.
Read the response as execution data, not just a number
Suppose your UI only prints ask_units. You have technically displayed an expected output, but you have thrown away much of the information that makes the quote useful.
The most important raw REST fields to inspect are:
-
ask_units: the simulated output amount. -
min_ask_units: the minimum output associated with the supplied slippage tolerance. -
recommended_min_ask_units: the API's recommended minimum output. -
price_impact: the effect of this swap size on the execution price. -
swap_rate: the simulated exchange rate. -
fee_unitsandfee_percent: fee information returned for the route. -
gas_params: estimated gas-related values. -
pool_address: the pool selected for the simulation. -
router: the Router metadata returned with the route.
The response type in the official client includes all of these fields. use expected output with guaranteed output.** A quote reflects a simulation against current state. If pool reserves change before the transaction executes, the final conditions can differ. That is why the minimum output and slippage protection exist.
A useful quote review in your interface can therefore be compact:
- "You receive" from expected output
- "Minimum received" from the minimum output
- "Price impact" as a separate risk signal
- fee estimate
- a warning when the quote is old or conditions have materially changed
If a quote is going to sit on screen for a while, request it again before constructing or submitting the transaction.
Carry the returned Router into the swap
The most important production pattern appears after the quote is returned.
STON.fi's current v2 SDK documentation explicitly recommends an API-driven workflow: simulate first, take the router object from the simulation result, pass it into dexFactory(), and then build the transaction against the returned Router rather than hardcoding a Router contract address. The documentation says this approach keeps integrations compatible with Router upgrades. It also states that api.ston.fi serves mainnet data. off looks like this:
`
`
ts
import { dexFactory, Client } from "@ston-fi/sdk";
import { StonApiClient } from "@ston-fi/api";
const apiClient = new StonApiClient();
const simulationResult = await apiClient.simulateSwap({
offerAddress: "",
askAddress: "",
offerUnits: "",
slippageTolerance: "0.01",
});
const { router: routerInfo } = simulationResult;
const dexContracts = dexFactory(routerInfo);
const tonClient = new Client({
endpoint: "",
});
const router = tonClient.open(
dexContracts.Router.create(routerInfo.address)
);
`
`
At that point, you have moved from "What would this swap look like?" to "Which contract configuration should build this swap?" The quote and transaction are two stages of the same workflow.
STON.fi's swap documentation also recommends reusing values from the simulation result when constructing the actual transaction. That reduces the chance that your signed payload describes a different route or minimum output from the one your interface just showed.
Common mistakes to avoid
Most integration bugs around quoting are not exotic smart contract failures. They are data-handling mistakes before a transaction is ever built.
Passing display amounts as **units***.* "1" and "1000000000" can represent the same human amount for a 9-decimal token, but they are very different API inputs.
Assuming every jetton has 9 decimals. Read the token metadata. TON's jetton documentation specifically warns that decimals vary. SON body to the raw simulation endpoint and ignoring its documented query parameters.** If you call REST directly, follow the current OpenAPI schema. If you use @ston-fi/api, let the client handle the mapping. ice impact and slippage as the same value.** Price impact describes how the trade affects the quoted rate through available liquidity. Slippage tolerance defines how much unfavorable movement you are willing to accept between quote and execution.
Hardcoding the Router. Use the Router returned by the simulation for the mainnet execution flow recommended by STON.fi. uote indefinitely.** A simulation is a snapshot, not a reservation. Refresh it when enough time has passed or when the amount, pair, or slippage setting changes.
A good practical rule is simple: treat the quote as disposable data that must stay synchronized with the transaction you are about to ask the wallet to sign.
Frequently Asked Questions
Is /v1/swap/simulate a real swap?
No. It simulates the swap and returns expected execution data without moving funds or requiring a wallet signature. Execution is a separate step in which your application builds the appropriate TON transaction and asks the wallet to sign it. The simulation is therefore ideal for price previews, validation, and transaction preparation.
What does units mean in the STON.fi quote request?
It is the amount of the offered asset in its smallest blockchain units. You must convert the human-readable amount using that asset's decimals metadata. For a token with 9 decimals, 1.5 tokens is 1,500,000,000 units. Do not assume every TON jetton has 9 decimals.
Is slippage tolerance the same as price impact?
No. Price impact reflects how the size of the requested swap affects the quoted execution price through pool liquidity. Slippage tolerance is the maximum adverse change your transaction is prepared to accept. STON.fi returns price impact separately and uses the slippage setting when calculating minimum output values.
Can I quote an exact output amount instead?
Use POST /v1/reverse_swap/simulate. The normal /v1/swap/simulate endpoint starts with a known amount to sell and estimates what you receive. The reverse endpoint starts with the amount you want to receive and calculates the required input. STON.fi exposes both flows in the REST API and in @ston-fi/api.
Should I hardcode a STON.fi Router address after getting a quote?
No for the normal mainnet integration pattern. STON.fi's current v2 documentation recommends taking the Router metadata from the simulation response and constructing the SDK contracts dynamically with dexFactory(). That keeps the transaction builder aligned with the route selected by the API and avoids depending on a manually fixed Router address.
Can I use api.ston.fi to request testnet swap quotes?
The current STON.fi v2 swap documentation states that the REST API at api.ston.fi serves mainnet data. Its testnet instructions use a manual contract setup instead of the mainnet API-driven routing workflow. If you are building a production mainnet integration, use the API-driven pattern; treat testnet as a separate setup.
What should my app check immediately before using a STON.fi quote?
Confirm that the pair, input amount, token decimals, slippage setting, expected output, minimum output, and returned Router still match what the user sees. If the quote is stale, request a fresh simulation. Then build the transaction from that simulation data instead of reconstructing the route from hardcoded values. That keeps the visible quote and the transaction as closely aligned as possible.
Further Reading
- STON.fi DEX API Reference - endpoint overview for swaps, reverse swaps, liquidity, and DEX data
- STON.fi Swagger UI - interactive interface for exploring and testing the REST API
- STON.fi OpenAPI Schema - current machine-readable definition of
/v1/swap/simulate, parameters, and responses - STON.fi API - official overview of the HTTP API and API viewers
- STON.fi v2 SDK Guide - API-driven mainnet simulation, Router discovery, and transaction construction
- STON.fi Swap Guide for React - end-to-end example using
@ston-fi/api,@ston-fi/sdk, and TonConnect -
@ston-fi/api- official TypeScript client package and usage examples - STON.fi API client source - implementation of
simulateSwap()and REST parameter mapping - STON.fi response types - current fields returned by swap simulation in the official client
- TON Jetton Metadata - authoritative explanation of jetton decimals and smallest-unit conversion







Top comments (1)
Hi! Thanks for watching and supporting me! If you spot a mistake in the text above, please let me know in the comments below so we can help others! Thanks again!