Audience
This surface is for partners running off-platform copies of the trade log — typically auditors and regulator-tech integrations. It is not for retail wallet flows; for a single user’s own trades useGET /api/me/trades.
Two endpoints:
GET /api/v1/partner/trades— incremental, cross-wallet trade feed.GET /api/v1/partner/reconciliation/snapshot— window-aggregate cross-check.
Authentication
Both endpoints use API-key auth.- Header:
X-Api-Key: ps_live_<keyId>_<secret> - Required scope:
partner:trades:read - The scope itself is read-only, but it is not exclusive: a key can
carry
partner:trades:readtogether with write scopes such asorders:writeorvault:write. If you want an audit-only credential, ask for a key that holdspartner:trades:readalone, and store any key that also holds a write scope as a trading credential. - Web-app user session tokens (
Authorization: Bearer) are explicitly rejected on these endpoints — they are partner-only. - A
multi_walletkey must still sendX-User-Walleton these requests, as on every request (see API keys); the feed itself is not filtered by that wallet.
partner:trades:read to your key.
Trades feed
Cross-wallet executed-trade feed. Cursor-paginated and incremental by modification time.Query parameters
Response — 200 OK
PartnerTrade:
PartnerTradeFee:
takerFee + makerFee, so do not
read takerFee as the trade total. A BUY leg is charged in
OUTCOME_TOKENS and a SELL leg in USDC, so the two legs of one fill
are often in different currencies: sum them per currency, and don’t
convert OUTCOME_TOKENS to USDC without applying the trade price. A leg
reads { amount: '0', currency: 'USDC', tokenId: null } only when it has
no fee row: a settlement_failed trade (it never settled, so no fee was
taken on either leg, even if an earlier pull showed one), trades from
before 28 April 2026, or an in-flight trade whose row has not been
written yet (that one shows its fee on a later pull).
PartnerTradeSide (identical shape on taker and maker):
maker.side is always reported as the opposite of taker.side. On a
binary-market fill where both parties bought (one YES, one NO) or both
sold, the maker actually traded the same side as the taker.
Example
Behaviour notes
- Idempotency. A single trade may surface twice — once when matched
(
status='matched',settledAt: null), again when settlement lands (status='settled',settledAt: <iso>). Partners are expected to upsert bytradeId. - In-walk re-emit. The same trade can re-emit within a single cursor walk if its settlement lands between page N and N+1. Same upsert rule applies.
modifiedSincemust stay constant across all cursor pages of a single drain.- Settlement failures are included with
status='settlement_failed'— do NOT filter them out client-side. A failure does not always movemodifiedAt, so a trade you stored asmatchedorsettlement_pendingcan fail without showing up again on your incremental pull. Periodically re-pull a trailing window (for examplemodifiedSince= now − 24 h) and upsert, so rows that were not yet final pick up their final status.
Status codes
Rate limit
- Per partner (one bucket shared by all of your API keys): 600 requests / minute by default. The limit scales with your account’s rate tier, which PredictStreet can raise.
- Per IP: 1000 requests / minute (defence-in-depth on egress IP).
Reconciliation snapshot
Window-aggregate cross-check for a partner’s local copy of trades. Returns counts, sums, and a deterministic content hash over the trade ids in the window.Query parameters
The
from / to bounds use the same max(createdAt, settledAt)
expression as the trade feed’s modifiedSince. The window aligns 1:1
with trades the partner pulled via ?modifiedSince=.
Response — 200 OK
Fingerprint algorithm
sha256 of the trade ids in the window, sorted lexicographically as
decimal strings and joined by commas:
[from, to)):
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
(SHA-256 of the empty string).
Stability
Snapshots of past windows are cached for up to 1 hour, live windows for
60 seconds.
Status codes
Rate limit
- Per partner (shared by all of your API keys): 60 requests / minute by default, scaled by the same account rate tier (recon is meant for periodic polling, not high-frequency).
- Per IP: 200 requests / minute.