# Accounts & positions

Everything readable about an account hangs off one prefix:
`/api/v1/accounts/{accountId}/*`. All reads work on any credential tier.

## The reads

| Endpoint | Returns |
| --- | --- |
| `GET /state` | Equity, balance, margin used and available, and unrealised PnL — one row per venue under `perVenue`, as USD-suffixed decimal strings. |
| `GET /positions` | Open positions across every venue. |
| `GET /orders` | Working and recent orders. Cursor-paginated. |
| `GET /trades` | Closed round-trip trades. Cursor-paginated. |
| `GET /fills` | Individual executions. Cursor-paginated. |
| `GET /funding` | Deposit / withdraw / transfer ledger. Cursor-paginated. |

```bash
curl -s https://api.troncharts.xyz/api/v1/accounts/$ACCOUNT_ID/positions \
  -H "authorization: Bearer $TOKEN" \
  -H "x-tenant-slug: $TC_TENANT_SLUG"
```

```ts
const state = await sdk.accounts.state(accountId)
const { positions } = await sdk.accounts.positions(accountId)
const page = await sdk.accounts.trades(accountId, { limit: 200 })
```

## Fills vs trades

They answer different questions, and mixing them up is the most common
reconciliation bug:

- A **fill** is one execution. A single order can produce many.
- A **trade** is a closed round trip — an entry matched with its exit, carrying
  realised PnL.

Compute volume from fills. Compute PnL from trades.

## Listing and creating accounts

| Endpoint | Does |
| --- | --- |
| `GET /api/v1/accounts` | Every account your credential owns. |
| `POST /api/v1/accounts` | Create an account. |
| `GET /api/v1/accounts/{id}` | One account's summary. |
| `PATCH /api/v1/accounts/{id}` | Update name, settings. |
| `PATCH /api/v1/accounts/{id}/suspension` | Suspend or restore. Needs the `prop:manage` scope — see [Blocking vs suspending](https://docs.troncharts.xyz/docs/launch/prop-accounts/#blocking-vs-suspending). |
| `POST /api/v1/sandbox/paper-account` | Provision a sandbox account to rehearse against. |

Start every integration against a sandbox account. It exercises the identical
order path with no real money.

## History & reconciliation

The reads above are the live view. These four answer *what actually happened*,
and the first one carries a fact that changes what your blotter can show.

| Endpoint | Returns |
| --- | --- |
| `GET /api/v1/accounts/{id}/order-history` | Every order **the venue saw** — including orders placed directly in the venue's own interface, which never passed through this platform. Filter by `venue`, `symbol`, `status` (`open`, `filled`, `canceled`, `rejected`, `triggered`, `expired`); cursor-paginated. |
| `GET /api/v1/accounts/{id}/state/history` | The equity and margin time series behind any charted account view. `venue`, `from`, `to`, `limit` (max 5000, default 1000). |
| `GET /api/v1/accounts/{id}/events` | The account's own audit log. `kind`, `venue`, `from`, `to`; cursor-paginated, `limit` max 500. |
| `POST /api/v1/accounts/{id}/manual-trades` | Import an off-platform round trip so it lands in the same PnL surface. |

:::caution[`/orders` and `/order-history` are not the same list]
`/orders` is the platform's order book — what went through the OMS.
`/order-history` is the **venue's**. If a trader also places orders in the
venue's own UI, those exist only in the second list. A blotter built on
`/orders` alone will look correct and be incomplete, and the discrepancy
surfaces as unexplained position drift.
:::

Importing a manual trade takes the round trip, not two legs:

```bash
curl -s https://api.troncharts.xyz/api/v1/accounts/$ACCOUNT_ID/manual-trades \
  -H "authorization: Bearer $TOKEN" \
  -H "x-tenant-slug: $TC_TENANT_SLUG" \
  -H 'content-type: application/json' \
  -d '{
    "symbol": "BTC.HL",
    "side": "long",
    "qty": 0.5,
    "entryTime": "2026-07-01T12:00:00Z", "entryPrice": 61000,
    "exitTime":  "2026-07-02T09:30:00Z", "exitPrice":  63250,
    "fees": 12.4
  }'
```

`side` is `long` / `short` — the position's direction, not a buy/sell. Both
timestamps are ISO 8601, and `fees` is optional.

## Reports

The account reads above are the live view. For historical reconciliation use
the reports surface, which is built for range queries and export:

| Endpoint | Returns |
| --- | --- |
| `GET /api/v1/reports/orders` | Order history over a window. |
| `GET /api/v1/reports/fills` | Fill history. |
| `GET /api/v1/reports/positions/closed` | Closed positions. |
| `GET /api/v1/reports/daily-pnl` | Daily realised PnL. |
| `GET /api/v1/reports/funding` | Funding-payment history. |
| `GET /api/v1/reports/statements` | Statement documents. |

## Analytics

Derived performance reads, if you'd rather not compute them yourself:
`GET /api/v1/analytics/performance`, `/per-symbol`, `/equity-curve`, and
`/risk-metrics`.

## Streaming instead of polling

Do not poll `/state` or `/positions` in a loop. Subscribe to
[`/ws/risk`](https://docs.troncharts.xyz/docs/realtime/risk/) — position, margin, balance, and order state
are pushed as they change, and the snapshot handlers give you the initial state
on connect.