Only managed quote and fill accept
mode: "paper". Direct orders reject it. Reads listed below take the same mode so paper rows are not mixed with live ones.
Paper trading prices quotes against the current book and writes simulated balances, orders, and positions. It never submits to a venue and never runs a bridge, custody transfer, deposit, withdrawal, or redemption. Do not show a paper balance as a funded wallet.
The signed-in user’s paper account is the one whose externalId is user:<aggUserId>. It is created the first time they request paper balances, positions, a quote, or a fill. Keep paper and live state visually separate.
User quote and fill
A paper quote must be filled withmode: "paper". A live fill cannot execute a paper quote. Switching modes needs a fresh quote.
mode until terminal is true.
Pass mode: "paper" on these reads as well:
POST /execution/orders is live only. It has no mode field and rejects one with 400.
UI components
Set paper mode once onAggProvider. HomePage, EventMarketPage, PlaceOrder, and UserProfilePage read it when no executionMode prop is passed.
executionMode on one component when it must differ from the provider. Hide deposit, withdrawal, and redemption controls in a paper-only experience.
Admin accounts
These methods are onAggClient, not a separate admin client. Configure apiKey on a server-side client. Never call them from the browser. The route authorizes x-app-api-key only. Do not send a user bearer token.
The signed-in user sees the account whose externalId is user:<aggUserId>. externalId is unique per app. Creating one that already exists returns a validation error. Look it up with List paper trading accounts instead of creating it again.
resetPaperTradingAccount clears open positions and sets cash. Order history survives a reset. setPaperTradingBalance changes cash only. Amounts are 6-decimal integer strings. initialBalance, balance, and spend also accept numbers. Prefer the raw string for a repeatable fixture.
On placePaperTradingOrder, clientOrderId is stored for traceability only. It is not an idempotency key. The order prices against the current book and comes back filled or rejected.
Testing
Sign in a test user, read paper balances and checkPAPER_USD is present, quote an open market with mode: "paper", fill it, and poll to a terminal state. Then read paper orders and positions.
Negative paths: fill a paper quote without mode: "paper" and expect a rejection. Switch from paper to live only with a fresh quote. Paper pages show no deposit, withdrawal, bridge, or redemption.
For a repeatable run, reset the user:<aggUserId> account first, pick outcomes from current discovery, and use a scenario-owned clientOrderId on backend orders so logs map fixtures to orders.