Skip to main content

Account Freshness and Reconciliation

Account REST views combine presentation projections with authoritative nonce and risk data. A successful read means the endpoint answered; it does not by itself prove that every projection has incorporated the write you just saw.

Current production workaround

Until the explicit freshness metadata described below is deployed and verified on the public API, use the authoritative bootstrap route after a deposit, fill, cancel, nonce fence, reconnect, risk rejection, or uncertain write:

GET /api/v1/accounts/{account}/bootstrap?fresh=true

The path value is the 20-byte engine account. It is different from the 32-byte accountIdHex used by trading-account control-plane endpoints.

Retain the receipt or private event that triggered the refresh. Compare its cursor/batch context with the response asOf. As a temporary cross-check, compare asOf.batchId with engine_truth_batch_id from GET /api/v1/health; if either value is missing, stale, or cannot be shown to cover the receipt, treat freshness as unknown. Inspect the returned nonce window, balances, positions, open orders, stateVersion, projectionVersion, and projectionLagMs when those fields are present. Older deployed responses may omit newer projection metadata, so absence is unknown rather than fresh. projectionLagMs is legacy presentation metadata and is not an authoritative batch-backlog measurement.

If the view is behind, wait with jitter and repeat the fresh bootstrap read. Do not reuse a nonce reported by an older view, and do not place or size a new order from balances that have not incorporated the terminal event.

Source of truth by question

QuestionEvidence to use
Was the HTTP request admitted?Submit response or durable receipt for the same idempotency/action identity
Did the order fill, rest, cancel, or reject?Terminal receipt plus private execution/drop-copy event
Which action nonce is usable?Fresh bootstrap or nonce-state replay window, not a cached account card
What balance can size the next order?Fresh bootstrap after the relevant terminal event is reflected
Is new placement allowed?Readiness/status plus account reconciliation; HTTP 200 status alone is insufficient

Freshness contract rollout

The next server contract adds these fields to account/bootstrap responses:

FieldMeaning
viewBatchIdExact batch cut backing the returned balances and account view.
authorityHeadBatchIdCurrent EngineTruth head from the existing short-lived health cache, or the local batch only on a genuine writer plane; null when authority is unavailable or stale.
lagBatchesauthorityHeadBatchId - viewBatchId only when both are coherent and authority is not behind the view; otherwise null.
authorityHeadSourceengine_truth_cache, local_writer, core_bootstrap_authority, or unknown. core_bootstrap_authority means the platform bootstrap obtained the authority view through the narrow Core route.
projectionAgeMsElapsed wall-clock time since the local derived snapshot was published; null when unknown. It is age, not backlog, and can grow while the account is idle.
syncStatussynced, degraded, pending, or unknown. pending covers an on-chain fallback that has not resolved yet and the Core-bootstrap pending_unknown_account state.

The invariants are stricter than a timestamp heuristic:

  • synced means both batch ids are known and equal, and lagBatches is 0;
  • degraded means the authority head is ahead and lagBatches is positive;
  • unknown means the authority is unavailable, stale, or lower than the view, and lagBatches is null;
  • projectionAgeMs alone never determines syncStatus.

For example, viewBatchId: 1472056, authorityHeadBatchId: 1472076, lagBatches: 20, and syncStatus: "degraded" is a view that must not size the next order. An unavailable authority is represented by a null authority and lag, authorityHeadSource: "unknown", and syncStatus: "unknown".

Rollout status

These fields are not yet available on production. Use the current workflow above until the server returns them and public readback is verified.

Treat the new fields as usable only after all of these are true:

  • the backend build containing the fields is deployed;
  • the public route returns them for the target account;
  • their batch/cursor advances past the receipt or event being reconciled; and
  • the documented stale/unknown states have been exercised in acceptance tests.

Escalation

If a fresh view does not advance, stop dependent placement and send support the two request ids, UTC window, environment, receipt/event cursor, and sanitized freshness fields. Never send raw authentication headers, signatures, API secrets, private keys, or private request bodies. Use the template in Troubleshooting HTTP integrations.