The examples use
$BASE for the base URL and a stock token with 9 decimals. Your Securitize contact gives you each stock’s contract addresses, tokenId and decimals (Amounts and assets).
1. Get a real-time price
- Show it on the order ticket and the confirmation screen, with its venues (Prices and market data).
- Fetch it on a fixed cadence while the ticket is open, not on every keystroke: each investor can make one call a second and sixty an hour, and the same again to prepare and to submit.
- Two expiries, two jobs.
validUntilis how long the quote itself is current, about 2 seconds: refresh what you show by then.signedPriceis what the order is checked against: it expires about 20 seconds after it is issued, and the order is priced at the quote it signed. Prepare the order within those 20 seconds. marketStatusUNAVAILABLEmeans no trading now.CLOSEDis pre-market or post-market and can be traded. See Market status.
2. Prepare the order
A buy: spend 1,000 USDC at a best offer of 231.25, accepting 0.5% slippage, so at least 4.3027 tokens (how to work that out).assetAmount instead of liquidityAmount, to the stock’s sell contract address.
EXPIRED_PRICE: the signed price expired, or the market moved since the quote. Fetch a new price, show it, and prepare again.minOutputAmountis the investor’s protection, and the bound enforced on chain: below it, the trade reverts and nothing moves. See below.INVALID_AMOUNT: an amount is not positive, has more decimals than the token allows, or the order’s value is outside the per-order limits.MAX_POSITION: a buy would take the investor’s position in the stock over its limit.- Use the right contract address. A stock has one for buying and one for selling; the wrong one answers
SYMBOL_NOT_FOUND.
Working out minOutputAmount
Work it out in whole units from the quote the investor accepted and their slippage, then convert to base units, rounding down. USDC has 6 decimals; the stock token’s come from your Securitize contact.
Skipping the conversion leaves a buy’s floor 10^(tokenDecimals − 6) times too low (a thousand times for a 9-decimal token), and the slippage protection goes with it. Use decimal arithmetic, never floating point.
slippageBps itself is recorded with the order.
3. The investor signs
RelayunsignedTransaction to your frontend and have the investor’s wallet sign it, unchanged. With a Solana wallet, for example:
- Never modify it. It carries a signed price and a validated swap instruction; any change invalidates it on chain and the trade reverts.
- Sign, do not send. Securitize broadcasts the transaction: that is what makes it an order executed by Securitize Markets. Use the wallet’s sign-only call, never sign-and-send.
- This signature is the order. It is the investor’s acceptance at the price and terms on your confirmation screen, which is why that screen carries the price, the amounts and the best execution acknowledgement.
4. Submit it
Within 120 seconds of the prepare:- Submit each prepared transaction once. A second submission of the same one answers
409 TRADE_IN_PROGRESS, or400 UNAVAILABLE_MARKETonce the first has been taken. Never resubmit to find out what happened: read the chain. - After 120 seconds, the transaction can no longer be submitted (
UNAVAILABLE_MARKET). Prepare it again, with a new price. tokenIdmust be the stock the order was prepared for.
What happens on chain
The Securitize router program checks Securitize’s signature and the investor’s, that the price has not expired and is still acceptable, and that the fill meetsminOutputAmount. It then fills the order against the market maker and moves both assets, in the same transaction. There is no separate clearing or settlement cycle: delivery versus payment, atomically, the same day. If any check fails, the transaction reverts and nothing moves.
Three moments, each with its own record: