Position Updates After TradesPosition data is updated after each trade execution. For real-time trade notifications that affect positions, use the gRPC Order Stream.
Positions are aggregated by symbol and account
Balances reflect current available and reserved amounts
Use the Order Stream for real-time execution updates that affect positions
Historical queries return the position state as of the specified time
The position ledger records every change to a position as a single entry, with both the delta (quantityChange, costChange, realizedChange) and the cumulative state immediately after the change (netPosition, cost, realized). Use it for reconciliation, point-in-time replay, and end-of-day reporting.
Both endpoints are scoped under read:positions (the same scope used for GetAccountBalance, ListAccountBalances, and the position queries on this section). Calls without read:positions fail with 403 Forbidden (REST) / PERMISSION_DENIED (gRPC).
The cumulative fields (netPosition, cost, realized) on each entry are the state immediately after the change. To reconstruct point-in-time position state, replay entries in update_time order.
The account in account=firms/{firm}/accounts/{id} must belong to the caller’s firm (extracted from the JWT firm_id claim). Cross-firm access is blocked at the gateway:
int64 fields are serialized as strings in JSON (e.g., "50" not 50) per the protobuf JSON mapping spec. Parse them as strings to avoid precision loss in languages with 53-bit integer limits.
GET /v1/positions/ledger/download?account=firms/ISV-Alice/accounts/alice-trading&start_time=2026-05-01T00:00:00Z
The download endpoint accepts the same query parameters as GET /v1/positions/ledger (account, symbol, start_time, end_time, page_size, page_token, newest_first).It streams raw CSV bytes from the upstream ledger as a passthrough; the gateway does not parse individual rows.
CSV passthrough caveat. Because the body is opaque to the gateway, ledger entries cannot be post-filtered row-by-row. The historical floor is still enforced upstream via start_time clamping, but no per-row filtering is performed on the CSV stream.
Empty result sets return a single empty chunk followed by EOF (HTTP 200 with an empty body). The gateway translates an upstream “stream returned a nil response” condition into an empty result.