Accounts & sessions API
Create accounts, open sessions, advance the clock, and read financials.
A trading account is a persistent, named, cash-only container with a continuous balance that carries day to day. Each account has a fixed engine, and you trade it one day at a time through sessions. See Accounts & trading days for the concepts. All endpoints require authentication.
Replaying past trading days is account-less — it lives under /practice/sessions, not under an account. Accounts are for live and bot trading only.
Engines
| Engine | What it does |
|---|---|
live_sim |
Paper-trades today's real session against the live tick stream. Past sessions are frozen. The only engine that ships now. |
broker_* |
Reserved for upcoming broker integrations — not yet available. Creating one returns 409 engine_not_available. |
Every account on /accounts is a live (manual) account — the type field is always manual. Trading bots are a separate surface, created and managed via the Bots API (not yet launched — those endpoints return 404 feature_unavailable until bots go live); they never appear in the /accounts list or resolve through /accounts/{id}. Trading is 0DTE SPX-index options only: cash-only, no equities, no overnight positions, so the carried balance is a single number.
Account endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/accounts |
List your live accounts |
POST |
/accounts |
Create an account |
GET |
/accounts/{id} |
Get one account |
PATCH |
/accounts/{id} |
Rename, archive, or edit starting capital |
DELETE |
/accounts/{id} |
Delete an account |
Create an account
curl -s https://api.0dtespx.com/accounts \
-X POST -H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{
"name": "Iron condors",
"engine": "live_sim",
"starting_capital": 100000,
"description": "Defined-risk study account"
}'
starting_capital ranges from 1000 to 10000000. name is required (≤ 80 chars) and must be unique among your active accounts. engine is fixed for the account's life. type defaults to manual. The response is the account object:
{
"id": "f3c88e1a-…",
"name": "Iron condors",
"description": "Defined-risk study account",
"engine": "live_sim",
"type": "manual",
"starting_capital": "100000",
"cash_balance": "100000",
"current_value": "100000",
"status": "active",
"created_at": "2026-06-21T12:00:00Z"
}
cash_balanceis the settled carry — it never folds in unsettled intraday P&L.current_valueis the live net-liquidation value when a session is open on the account, otherwise it equalscash_balance.
Creating a broker_* account returns 409 engine_not_available; a bot type returns 400.
Edit or archive an account
PATCH accepts any of name, description, status, starting_capital — only the fields you send are applied.
# rename
curl -s -X PATCH https://api.0dtespx.com/accounts/$ACCT \
-H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Condors — 2025"}'
# archive (blocked while a session is open)
curl -s -X PATCH https://api.0dtespx.com/accounts/$ACCT \
-H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{"status":"archived"}'
starting_capital is the ledger's day-0 input. It is immutable once a live_sim account has traded (409 capital_immutable), and it cannot change while a session is open (409 session_open).
DELETE /accounts/{id} soft-deletes the account and returns 204. It is blocked while a session is open (409 session_open) — cash carry is driven by settlement, never by deletion.
Session endpoints
A session is one trading day under an account. Orders, positions, transactions, and history all live under a session.
| Method | Path | Purpose |
|---|---|---|
GET |
/accounts/{id}/sessions |
List trading days (newest first) |
GET |
/accounts/{id}/sessions/current |
The open live session, or null |
GET |
/accounts/{id}/sessions/head |
Default landing session, or null |
GET |
/accounts/{id}/sessions/{sid} |
Get one session |
POST |
/accounts/{id}/sessions |
Open (or re-open) today's session |
DELETE |
/accounts/{id}/sessions/{sid} |
Delete a session |
GET |
/accounts/{id}/sessions/{sid}/history |
Per-second financial history |
/current returns the open live session for a live / broker account, or null. /head is the default landing session — the open day if any, else the latest settled day.
Open a session
A live_sim account opens today's session — the body is empty and the date is implicitly today:
curl -s https://api.0dtespx.com/accounts/$ACCT/sessions \
-X POST -H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{}'
- Live (
live_sim) — opens today's session at the latest tick with the carried cash balance, gated on market hours and fresh market data (400if the market is closed or live data is unavailable). Re-requesting today's session while it is open returns it (200). - Broker engines →
409 engine_not_available.
To replay a past trading day, use the account-less /practice/sessions endpoints instead.
The response is the session object:
{
"id": "9a1b…",
"account_id": "f3c88e1a-…",
"date": "2025-01-15",
"opening_balance": "100000",
"starting_capital": "100000",
"status": "open",
"ended": false,
"time": "2025-01-15T14:30:00Z",
"start_time": "2025-01-15T14:30:00Z",
"end_time": "2025-01-15T21:00:00Z",
"available_buying_power": "100000",
"net_liquidation_value": "100000",
"unrealized_profit_loss": "0",
"realized_profit_loss": "0",
"profit_loss": "0"
}
opening_balanceis the carried cash the day opened with;starting_capitalmirrors it for wire continuity (net_liquidation_value = starting_capital + intraday P&L).statusis the authoritative lifecycle field —open,settled, orabandoned.endedis a convenience flag that istrueonce the day has settled (status == settled).- A settled session also carries
closing_balance(the cash it settled to, carried into the account) andsettled_at. - While a live day is
openit carriessettles_at— when the day is expected to settle (end_timeplus a few minutes). After the close, that's when the settled, replayable day should appear in the list.
The full object also breaks financials out into equities vs equity-options components (all zero for SPX-only trading).
A live session's clock is the real clock — it has no clock control. Advancing or rewinding a replay is a practice-only feature (PATCH /practice/sessions/{sid}); account sessions expose no clock endpoint. Once a live day settles you can review it read-only via the ?at= query parameter (see live trading).
Delete a session
curl -s -X DELETE https://api.0dtespx.com/accounts/$ACCT/sessions/$SID -H "Authorization: $TOKEN"
A live session that has traded cannot be deleted (409 session_traded; it settles at the close, so cash carry is never driven by deletion). A live session with no orders is abandoned and the day's slot is freed (204).
Per-second history
curl -s "https://api.0dtespx.com/accounts/$ACCT/sessions/$SID/history?interval=5" \
-H "Authorization: $TOKEN"
Returns an array of per-second snapshots (net liquidation value, P&L, buying power, fees, …) for charting. Sampled at 1-second resolution; pass ?interval=<seconds> to down-sample. History is recomputed and stored whenever you create or delete an order.
Practice sessions (account-less)
Replaying past trading days doesn't use an account. Practice is a one-click, account-less $100,000 sandbox: each day opens at the market open (9:30 AM ET) with a fixed $100,000. The endpoints mirror the account session shapes but carry no account_id and no mode, and you don't choose a starting capital.
| Method | Path | Purpose |
|---|---|---|
GET |
/practice/sessions |
List your practice days (newest first) |
POST |
/practice/sessions |
Open a new practice day |
GET |
/practice/sessions/{sid} |
Get one session |
PATCH |
/practice/sessions/{sid} |
Advance/rewind the replay clock |
DELETE |
/practice/sessions/{sid} |
Delete a practice day |
GET |
/practice/sessions/{sid}/history |
Per-second financial history |
GET |
/practice/sessions/{sid}/orders |
List orders |
POST |
/practice/sessions/{sid}/orders |
Place an order |
GET |
/practice/sessions/{sid}/orders/{orderId} |
Get one order |
DELETE |
/practice/sessions/{sid}/orders/{orderId} |
Cancel a pending order |
GET |
/practice/sessions/{sid}/positions |
List positions |
GET |
/practice/sessions/{sid}/transactions |
List transactions |
Open a practice day
curl -s https://api.0dtespx.com/practice/sessions \
-X POST -H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{"date":"2025-01-15"}'
date can be any past trading date, opened in any order. Each POST opens a new, independent session, so a day can hold multiple simulations (each returns 201). Practice days don't carry into one another, so deleting one never disturbs the others. To edit a previously settled day, rewind its clock with PATCH (below).
The response is a session object without account_id or mode, with the fixed $100,000:
{
"id": "9a1b…",
"date": "2025-01-15",
"opening_balance": "100000",
"starting_capital": "100000",
"status": "open",
"ended": false,
"time": "2025-01-15T14:30:00Z",
"start_time": "2025-01-15T14:30:00Z",
"end_time": "2025-01-15T21:00:00Z",
"available_buying_power": "100000",
"net_liquidation_value": "100000",
"unrealized_profit_loss": "0",
"realized_profit_loss": "0",
"profit_loss": "0"
}
Advance the clock
A fresh practice session is parked at start_time. Move the clock with PATCH:
curl -s https://api.0dtespx.com/practice/sessions/$SID \
-X PATCH -H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d '{"time":"2025-01-15T17:00:00Z"}'
The response is the same shape, with time filled in and all financials recomputed at the new moment. time must satisfy start_time ≤ time ≤ end_time, or you get 400. Moving time is read-only — it recomputes positions, delta, P&L, and buying power from existing trades; it never writes orders or transactions. Setting it backward reverts not-yet-filled orders to pending and hides later trades; rewinding a settled day back before the close re-opens it for editing.
Setting the clock to end_time (the 4:00 PM ET close) finalizes the day: it settles, status becomes settled (ended flips to true).
Orders, positions, transactions, and history
The /practice/sessions/{sid}/orders, /positions, and /transactions sub-resources are identical in shape to their account-session counterparts — see orders and positions & transactions for the request/response bodies; only the path prefix differs (/practice/sessions/{sid}/… instead of /accounts/{id}/sessions/{sid}/…). Per-second history behaves the same as above and accepts ?interval=<seconds> to down-sample.
Next: place orders and read positions. For today's real-time session, see live trading.