Quote and submit orders
Follow an order from a wallet-bound quote through submission to its ledger-confirmed outcome.
Programmatic trading uses a trade key authorized for one Canton Party. Start with a quote, submit or prepare an order, and read its final status. A quote estimates an outcome; an HTTP response acknowledging an order does not mean it filled.
Before the first order
- Create and authorize a trade key.
- Keep the authorized
walletConnectionIdfrom the account's connected wallets. The connection must belong to the Party that authorized the key. - Fund the trading balance through the supported app flow. An API key cannot deposit or withdraw funds.
- Resolve both instruments as
{ "admin": "…", "id": "…" }. Names and tickers are display labels, not unique instrument identifiers. - Check the current runtime capabilities and the selected pool. Use its actual terms and quote; legacy preview constants are not universal pool economics.
The order lifecycle
For an eligible hosted Party, POST /api/v1/orders/hosted submits the order instead of returning commands for your own signer.
1. Request a quote
Send a signed POST /api/v1/swaps/quote:
{
"buyInstrument": {
"admin": "<token-instrument-admin>",
"id": "<token-instrument-id>"
},
"sellInstrument": {
"admin": "<CC-instrument-admin>",
"id": "Amulet"
},
"sellAmount": "1",
"slippageBps": 100,
"walletConnectionId": "<your-authorized-connection-UUID>",
"allowPartialFill": false
}The placeholders must be replaced with the selected instruments and your authorized connection. For a sell, reverse the instruments and set sellAmount to the token amount.
sellAmount is a decimal string with up to ten fractional digits. slippageBps is an integer from 1 to 5000; 100 basis points is 1%. The default is 100. Choose the tolerance deliberately.
Inspect the quote before continuing:
| Field | How to use it |
|---|---|
quoteId | Bind the subsequent order to this quote. |
expiresAt | Prepare and submit within its validity; refresh expired quotes. |
buyAmount, minimumBuyAmount | Expected output and the slippage-protected minimum. |
feeCc, feeLineItems, feeConfig | Display the actual applicable fees. |
wallet, networkId | Verify the wallet context and network. |
authority, execution, settlement | Inspect the quote's model and execution context. |
fill, grossCcUsed, unspentCc, graduates | When returned, explain a partial fill or graduation and the amount actually used. |
When a pool's lifecycle or quote model changes, obtain a new quote. A graduation can change the venue from curve to AMM. Do not silently reuse an old quote across that transition.
2. Choose the submission path
External Party
Call POST /api/v1/orders/prepare with a signed request, an idempotency key, and this body:
{
"quoteId": "<quote-UUID>",
"walletConnectionId": "<your-authorized-connection-UUID>"
}The response includes actAs, commands, disclosedContracts, packageIdSelectionPreference, commandId, and expiresAt. Submit the returned commands as the authorized Party through its Ledger API integration: prepare the transaction, sign the prepared transaction hash with the Party key, and execute before expiry.
Keep the returned command ID for reconciliation. Do not change the returned commands or claim completion from a wallet submission hint; the ledger-confirmed result is authoritative.
Hosted Party
For a Party the deployment is permitted to submit for, send the same body to POST /api/v1/orders/hosted. The backend submits the order and returns its current status. This path is restricted to eligible hosted Parties; a trade key does not make an arbitrary wallet hosted.
Interactive Supa wallet
A Party whose key is held by the Supa wallet through Privy cannot sign headlessly. Use the app's wallet review and signing flow. The customer trade-key routes do not turn an interactive wallet into a background trading signer.
3. Follow the outcome
Poll with your customer read or trade key:
curl --fail-with-body --silent --show-error \
-H "X-API-Key: $SUPANOVA_API_KEY" \
"https://launch-api.supanova.app/api/v1/orders/$COMMAND_ID/status"| Status | Meaning for your integration |
|---|---|
pending | The order has not yet reached an observed open or final state. |
open | The order is open on the ledger. |
filled | Read settled for actual input, output, fees, and any partial fill. |
rejected | Inspect error and reason; do not report a fill. |
cancelled | The order was cancelled. |
expired | The order expired. A new attempt needs a fresh quote. |
Poll at a bounded interval and respect the rate limits. Keep commandId, requestId, and any returned ledger update IDs for support and reconciliation.
Cancel an open order
POST /api/v1/orders/{orderId}/cancel/prepare returns a cancellation command for the Party to sign and submit. This uses the on-ledger orderId, not the submission commandId. It does not cancel merely by returning the prepared command.
An order can fill before the cancellation lands. Refresh its status and handle ORDER_NOT_OPEN instead of assuming cancellation succeeded.
Recover without duplicating an order
After a timeout, reconcile the existing command or retry the identical operation with its original idempotency key and a fresh request signature. A changed payload under the same key is a conflict. Use a new key only for a new logical operation.
Handle quote expiry, insufficient balance, unavailable execution, a paused pool, and venue changes as distinct failures. Read error handling before adding automatic retries.