Skip to main content

Get reconciliation data for an account

GET 

/api/v1/reconciliation/:accountId

Returns full reconciliation data for the account grouped by symbol. Includes broker positions, UTM trades, unlinked executions, discrepancy summaries, and reconciliation status per symbol. The top-level ignoredInWindow field counts orphan ignored executions at or after the account's utmStartDate so the UI can prompt the user to bulk-restore them after moving the date earlier (#422); it is always 0 when no UTM start date is set. Access is denied if the account does not belong to the authenticated user.

The unlinked / pending-review buckets are capped to a rolling 14-day window by default. Pass showAll=true to drop the window and fall back to the account's utmStartDate (or no lower bound if unset). The response includes windowDays, executionsBeyondWindow, and showingAll so the UI can render the windowing pill.

Every execution row carries signalStrategyId and signalStrategyName: the strategy of the signal that produced the execution's order (via Execution -> Order -> Signal), or null when the fill has no UTM order or the order has no signal. The match UI compares these against a candidate trade's strategyId / strategyName so a cross-strategy link is flagged before the operator confirms it.

Each orphan execution (pending_review, no linked trade) carries a suggestions array of Tier 2 auto-match candidates (#418), each \{ tradeId, score, matchedOn: \{ symbol, side, qtyDeltaPct, timeDeltaMinutes \}, candidateSummary \}, highest score first and capped at three. A trade whose strategy differs from the orphan's signal strategy is never suggested; the strategy gate applies only when both strategies are known. The array is empty when auto-match is disabled or no candidate clears the configured minimum score. Nothing is ever linked without an explicit user action; the array is a suggestion only. Linked, unlinked, and ignored executions omit the field.

Each symbol also carries a linkedExecutions array (#1107): the real broker fills (source broker_fill) already attached to one of the symbol's trades, each with its tradeId. The UI surfaces these behind a "Show linked fills" disclosure so a fill linked to the wrong trade can be pulled back out and unlinked or re-matched, rather than only being visible nested under its trade. Synthetic position-import and manual fills are excluded - they are managed from the trade itself.

Each symbol with no discrepancy and one or more pending-review fills also carries a remnants array (#1197): historical unlinked-fill groups that no longer back the current position. Each remnant has a kind (closed_round_trip), realisedPnl (sell proceeds minus buy cost), the grouped fills, the latest executedAt, and a preStartDate flag (true when the latest fill predates the account's utmStartDate). summary.remnantCount totals them across symbols. The top-level utmStartDate is the account's start date (or null), surfaced so the reconcile banner can render the cutoff and offer the bulk "ignore everything before" action without a second call.

Each symbol also carries a residueTrades array (#1360, findings 1 and 6): "expired_no_order" lifecycle-residue trades for the symbol - stranded pre-allocations auto-hidden from trades above and from summary.unreconciledTrades (see #1106, GET /reconciliation/set-aside) because they carry no reconciliation work of their own. A residue shell is nonetheless very often the rightful owner of an unmatched order or fill surfacing elsewhere on the same symbol, so it is still listed here as a link-to-trade candidate, separately from the routine queue. Never includes "zero_quantity_superseded" residue (a superseded trade was genuinely replaced and is not a valid link target). Excludes residue the user has already restored from Set aside - that trade is back in trades instead.

Request​

Responses​

Full reconciliation data grouped by symbol