Create a paper account to test against
One call provisions a paper account with a starting balance and a seeded position, so your first reads return real data and your first orders run the real pipeline without real money.
-
Provision the account
Section titled “Provision the account”POST /api/v1/sandbox/paper-account. Every field is optional and{}is a valid body — the defaults arebaselineUsd"50000",symbol"BTC.HL"andseedDemoPositiontrue. The credential must befullTrading; this route compares the tier for exact equality, soreadonlyandliquidationboth get403 tier_insufficient. Noprop:managescope is involved.Terminal window curl -s https://api.troncharts.xyz/api/v1/sandbox/paper-account \-H "authorization: Bearer $TOKEN" \-H "x-tenant-slug: $TC_TENANT_SLUG" \-H 'content-type: application/json' \-d '{"baselineUsd":"50000","symbol":"BTC.HL","displayName":"integration rehearsal"}'# → 201 { accountId, accountNumber, propTenantId, templateId,# mode: "paper", demoPositionSeeded: true, ws: { hint } }const sandbox = await sdk.sandbox.paperAccount({baselineUsd: '50000',symbol: 'BTC.HL',displayName: 'integration rehearsal',})const accountId = sandbox.accountIdThe new account is linked into the calling credential’s ownership scope, so it shows up in
GET /api/v1/accountsand you can address it byaccountIdfrom here on. Field-by-field detail lives on Paper accounts. -
Read the seeded state back
Section titled “Read the seeded state back”The account is funded and holding the demo position the moment the 201 lands.
/statereturns balance and equity per venue;/positionsreturns what it holds.Terminal window curl -s https://api.troncharts.xyz/api/v1/accounts/$ACCOUNT_ID/state \-H "authorization: Bearer $TOKEN" \-H "x-tenant-slug: $TC_TENANT_SLUG"# → { accountId, accountNumber,# perVenue: [ { venue, exchange, equityUsd, balanceUsd, marginUsedUsd,# marginAvailableUsd, unrealizedPnlUsd, … } ] }const state = await sdk.accounts.state(accountId)const { positions } = await sdk.accounts.positions(accountId)console.log(state.perVenue, positions.length) -
Point your order flow at it
Section titled “Point your order flow at it”Send the sandbox
accountIdin the OMS body. It is optional onPOST /api/v1/oms/intentsand defaults to the session’s active account, which a bearer credential does not have — so name it explicitly. Use"venue": "paper"; against a non-paper account that is rejected400 paper_venue_requires_paper_account.Terminal window curl -s https://api.troncharts.xyz/api/v1/oms/intents \-H "authorization: Bearer $TOKEN" \-H "x-tenant-slug: $TC_TENANT_SLUG" \-H 'content-type: application/json' \-H "idempotency-key: $(uuidgen)" \-d '{"accountId":"'"$ACCOUNT_ID"'","venue":"paper","symbol":"BTC.HL","side":"buy","type":"market","qty":"0.01"}'The paper engine matches synchronously, so a market order comes back as
201 { intentId, state: "filled", syncFill: { qty, avgPrice } }. The full body schema is on Orders & OMS.
Next: Place your first order · Read balance, positions and open orders · Stream account updates