Patterns we’ve seen work in production: pagination, retries, rate-limit handling, WebSocket reconnect, idempotency, testing strategy.
Engineering patterns we recommend when shipping a Predexon integration. None of this is required to make your first call work — it’s what separates a working prototype from a production system.
Rotate via the dashboard — keys are scoped per workspace, easy to revoke and re-issue.
Use one key per environment (dev / staging / prod)
Free tier covers dev easily. Use a separate Dev or Pro key for staging so you can verify rate-limit behavior matches prod.
Per-end-user keys (account-per-user platforms)
If you’re building an account-per-user product, you don’t need per-user Predexon keys. One platform key creates accounts on behalf of end users via the Trading API. End users never see the Predexon key.
/v2/polymarket/wallets/profiles accepts up to 20 wallets per call. /v2/polymarket/wallets/filter lets you filter server-side instead of pulling everything and filtering locally. Use them.
3
Stream instead of poll for live data
If you find yourself polling /v2/polymarket/trades every second, switch to the WebSocket trades channel. Streaming consumes WebSocket subs (cheap) instead of REST quota (expensive).
4
Upgrade tier or talk to us
Free is 1 req/s. Dev is 20 req/s. Pro is 100 req/s. Enterprise is custom. If you have a sustained workload above Pro, email us — we’ll discuss a custom rate before throttling you in production.
Trading API order placements aren’t idempotent by default — calling Place Order twice with the same body creates two orders. For at-most-once semantics:
import uuid# Generate one client_id per *logical* orderclient_id = str(uuid.uuid4())# Pass it in the request. If the network drops and you retry, pass the same client_id.order = session.post( f"{TRADE}/api/accounts/{account_id}/orders", json={ "venue": "polymarket", "market": {"tokenId": token_id}, "side": "buy", "type": "limit", "size": "10", "price": "0.50", "clientId": client_id, # ← reuse across retries },).json()
If the server already saw this clientId, it returns the existing order instead of creating a duplicate. Critical for any retry logic on the Trading API.
Mock your business logic that calls Predexon. The endpoints themselves should be hit in integration tests against real markets — that’s the only way to catch shape changes early.
Use low-volume markets for trading integration tests
Trading API has no sandbox. Test against real venues with $1 trades on illiquid markets — cheap real-world signal. Free tier is fine for this; trading endpoints don’t consume your Data API quota.
Replay historical WebSocket events for handler tests
Record real events to JSON files, replay them through your handler in tests. Lets you test without keeping a connection open.
Snapshot endpoint responses
Capture a real response, snapshot-test against it. When we ship a non-breaking field addition, your test still passes; when a breaking change ships, your test catches it.
Candles use seconds. Orderbook snapshots use milliseconds. WebSocket events use seconds except the orderbook channel (milliseconds). Always check the page reference.
Cents vs decimals
Polymarket prices are 0–1 decimals. Kalshi prices are 0–100 cents. Normalize on read.
condition_id vs token_id
A market has one condition_id and N token_ids (one per outcome). Candles by condition give you market-level OHLCV; candles by token give you per-outcome.
Aggregated vs per-venue positions
GET /api/accounts/{id}/positions returns per-venue rows by default. Pass ?aggregated=true to collapse cross-venue positions into one row per canonical outcome.
WebSocket plan gating
WebSocket requires Dev plan or higher. You won’t see this until you try to connect and get 403. Test early.