signedFrame helper from that page. Use a fresh externalRef on every run: a reference already used is refused as a duplicate.
1. Place the buy
A buy is aLIMIT order by quantity. Buy 10 shares, paying no more than 150 a share:
- Your own cash pays for it. Before the order reaches the broker,
quantity × limitPriceplus its fees is held against theavailableofget_cash_balance_v2. A buy it does not cover answersINVALID_ORDERwith your figures, and nothing reaches the broker. Read youravailablebefore a large buy. LIMITandquantity, always. AMARKETbuy, including one that leavesorderTypeout, and a buy bynotionalanswerINVALID_ORDER: neither names the price its cost is held at.externalRefis your idempotency key. Derive it from your own order id and store it before you send. At most 39 characters of letters, digits,.,_and-; no colon, because the mint memo uses colons as separators.- Name the chain when the symbol has more than one.
get_symbolslists every chain a symbol can be bought on. With one chain,chainIdcan be left out. With more than one, send thechainIdwhose CETs you want minted; without it the order answersINVALID_ORDERand nothing reaches the broker. - The broker checks the account too. A buy the broker account as a whole cannot pay for is refused with
INVALID_ORDERand the messageInsufficient buying power, even when your own cash covers it. - Only the symbols tracked for your account can be traded, the ones
get_symbolslists. A symbol your account does not trade, mistyped or not, answersINVALID_ORDER; check it againstget_symbols. Nothing reaches the broker, so theexternalRefstays usable.
2. Read the acknowledgement
Store
regulatoryId now. It is the order’s id in regulatory reporting, and the key that ties the order to its trades, mints and burns. tokenAddress is the on-chain address of the CET the order mints, and chainId the chain it is on.
3. Follow it as it fills
Fills arrive pushed, without a request:order_updated: one frame per change to the order, carrying the order as it stands. ReadstatusandleavesQuantity; zero means nothing is left working.trade_updated: one frame per execution. Deduplicate ontradeId.mint_updated: one frame per mint, once the CETs are on chain. See step 4.
get_order: see After a disconnect.
4. Reconcile the CETs
CETs are minted in pieces, as the order fills. Each mint covers the shares filled since the previous one:amount = executedQty − previousMintedQty. A 250-share order that fills 100 and then the remaining 150 mints 100 and then 150. Sum amount, never executedQty.
Read every mint of the order by its regulatoryId:
- From the order: every
get_orderanswer carries the order’smints. - From a transaction on chain: send its hash as
get_mintstxHashand you get that mint and the executions it paid for. On Solana the mint’s memo also ends with itstraceId, after the final colon, whichget_mintstakes too.
mint_updated, with the same shape, once the CETs are on chain. That can be minutes after the fill. Its txHash usually follows within a minute, in a second mint_updated for the same mint. A push is delivered at most once, so get_mints is how you catch up after a gap.
Before you treat a mint’s executions as final, check executionsComplete is true. A mint is reported once it is on chain; there is no pending state. Mints and burns explains the memo, the handle and the edge cases.