Skip to main content
Your integration maintains a local projection of each participant’s orders, positions, and cash. This page describes the operating pattern that keeps that projection correct, and the read APIs that anchor it to authoritative state.

The operating pattern

Streams are the system of record; reads are anchors. The firm-scoped Drop Copy execution and position streams drive your projection in real time. Unary reads exist for discovery, user-driven views, and reconciliation — they are not polling feeds.
  • Replay before new work. Persist a stream response’s resume_token only after every record in it is durably applied. Reconnect with the last committed token; deduplicate replayed events by stable exchange IDs.
  • Single active subscriber. Run one leader-elected consumer per firm, environment, and stream. Followers take over from the durable cursor — never one subscription per pod, and never one stream per customer.
  • Reconcile after gaps. After an outage: resume and replay the streams first, then compare your projections against the reads below, and surface freshness caveats rather than presenting incomplete state as final.
  • No cron pollers. Reads are triggered by onboarding, user views, bounded workflow recovery, reconnect reconciliation, or an incident — not recurring schedules.
A process restart is not a cold start. Resume from your persisted checkpoint against your existing local database — don’t re-run the unary reads below.
“Cold start” means true first contact for a firm/account/environment your integration has never seen before — no persisted resume_token or resume_time, and no local projection to reconcile against. If you already persist your checkpoint, a restart just reconnects with it and keeps applying deltas to the state you already have, deduplicating anything replayed. Only a genuine no-checkpoint start (or a checkpoint too old to resume) falls back to the reads below.

Reconciliation reads

The anchors are the standard gRPC read APIs — the same polymarket.v1 services documented under Institutional API, called with your partner credentials over TLS with a Bearer token. Full message definitions are in the proto download; the tables below map each reconciliation concern to its RPC.
These are low-volume anchors, not a data-access layer. Every RPC below is rate-limited per firm and must not be polled.
The correct architecture is stream-first: build your local database from Drop Copy and Order Stream, serve reads from that database, and call these RPCs only for cold-start hydration, point-in-time queries, and gap recovery — never as a substitute for a subscription. See Rate Limits for the full list; SearchOrders, SearchExecutions, and SearchTrades, for example, are capped at 12 requests/minute, and sustained call volume against any of these endpoints will get throttled.

Cash balances — polymarket.v1.PositionAPI

An account balance is the authoritative cash figure for one account and currency, plus the risk context used to size orders — see Balance Data for the full field reference. This balance read is the authoritative confirmation required by the safe-sweep precondition: confirm the released amount here before creating a sweep.

Stream it instead

Streaming equivalent: no dedicated balance-push stream exists — derive live balances from Balance Ledger deltas instead of polling this RPC.
  • Apply CreateBalanceLedgerSubscription entries (before_balance / after_balance) to your projection as they arrive.
  • Reserve GetAccountBalance / ListAccountBalances for a true first-time cold start and the safe-sweep confirmation above.
  • On an ordinary restart, resume from the last update_time you persisted and keep applying deltas to the balance you already have — don’t re-fetch it.

Positions — polymarket.v1.PositionAPI

A position tracks net quantity, cost basis, and realized P&L for one account and symbol — see Position Data for the full field reference.

Stream it instead

Streaming equivalent: CreatePositionChangeSubscription on the Drop Copy stream keeps positions current in real time.
  • Call ListAccountPositions to hydrate a brand-new projection (true cold start) or to answer point-in-time (as_of_time / as_of_date) queries a stream can’t answer — not on every process restart.
  • A restarting service persists its position projection alongside the stream’s resume_token and reconnects with that token; a routine restart is never a reason to re-fetch positions.

Orders — polymarket.v1.ReportAPI

An order carries its full lifecycle state — quantity, price, fills, and status — see Order Message Structure for the full field reference (the same fields these reads return).

Stream it instead

Streaming equivalent: CreateOrderSubscription on the Order Stream is snapshot and stream on one connection — no unary call is needed for cold start.
  • Open with the default snapshot_only: false; the first message carries a snapshot of every currently-open order, then update messages push executions continuously.
  • This request carries no resume_token, so a restart simply reconnects and gets a fresh snapshot for free — there’s no checkpoint to persist for this one.
  • Reserve SearchOrders / GetOrder for one-off lookups the live snapshot doesn’t cover (e.g. a specific historical/closed order by ID).
  • Drop Copy’s execution and Trade Capture Report subscriptions, by contrast, carry a resume_token and no snapshot — hydrate firm-wide historical fills once via SearchExecutions / SearchTrades on true cold start, then resume the stream with the persisted token on every subsequent restart instead of re-querying.

Cash ledger — polymarket.v1.FundingAPI

A ledger entry records a single cash-balance change with its before/after amounts — see BalanceLedgerEntry Fields for the full field reference.

Stream it instead

Streaming equivalent: CreateBalanceLedgerSubscription is the streaming equivalent here — it replays from resume_time and then pushes new entries live.
  • Use GetAccountBalanceLedger only for paginated historical lookups and CSV exports, not as a live feed.
  • Persist the update_time of the last applied entry and pass it back as resume_time on reconnect — a restart resumes the stream from that point, it does not re-run history from the beginning.
Joining orders to funding. For funded orders, clord_id equals the funding_request_id returned by CreateFundedOrder — and SearchOrders filters by clord_id directly. Keep the exchange order_id as the canonical venue identifier, and persist the create response’s correlation fields so ledger rows, stream events, and sweeps all join cleanly.

Settlement Sweeps

The planned cash-movement API these reads gate.

Drop Copy Stream

The firm-scoped execution stream that drives your projection.

Order Stream

Real-time order and execution updates for your accounts.

Rate Limits

Per-endpoint limits for the reads on this page.