Working doc for integrating Dimes Multiply (leverage-on-Polymarket middleware) into Olympus. Scope for v1 is manual leverage trading only (no copy-trade fan-out).
Source docs: https://docs.dimes.fi/ · index at https://docs.dimes.fi/llms.txt
- Dimes Multiply is a middleware that issues a CFD-style leveraged synthetic over Polymarket positions. The user posts USDC margin on Polygon; Dimes' Underwriting Facility (institutionally-sourced, "$50m+/month capacity") fills the matching YES/NO hedge directly on Polymarket and gives the user a synthetic that pays
(P_now − P_entry) × leverage × size, bounded by Polymarket's $0–$1 outcome range. - Dimes does not create markets, host orderbooks, compete with PM venues, or do user acquisition. It's pure middleware.
- Underlying venue today: Polymarket only. Possible future: Kalshi, Hyperliquid, Limitless, Opinion.
- User never holds Polymarket CTF tokens directly — only the synthetic, keyed by
on_chain_position_key. Settlement is in USDC. - Dimes never holds user funds longer than a single tx.
- Live on Polygon mainnet, chain ID 137 only.
- USDC is USDC.e (bridged) —
0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174(same token Polymarket uses).
Production:
| Contract | Address |
|---|---|
Vault (LeveragedPredictionVaultV1) |
0xECF933ccDf7ebc6a0658c77E070cFe51ebe5328A |
| USDC.e | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 |
| Polymarket CTF | 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 |
Sandbox:
| Contract | Address |
|---|---|
| Vault | 0xefF55c64B8E971eEbBbbc2037593588e0F271dE2 |
| Fake USDC | 0xD477EDbe627E94639d7E92119Ca62a461c6ce555 |
| Fake CTF | 0x8B859B4459A75b50e07D345F6b1998F27540F758 |
USDC approvals go to the Vault address. Vault uses transferFrom to pull; "never holds user funds for longer than it takes to execute."
| Prod | Sandbox | |
|---|---|---|
| REST base | https://api.dimes.fi/v1 |
https://api-sandbox.dimes.fi/v1 |
| WS base | wss://api.dimes.fi/v1/ws/... |
wss://api-sandbox.dimes.fi/v1/ws/... |
| API key prefix | dm_live_skey_… |
dm_sbx_skey_… |
| Resource IDs | dm_pos_…, dm_off_…, dm_mkt_… |
dm_pos_sdx_…, etc. |
| Chain | Polygon mainnet | Polygon mainnet |
| Swagger | — | https://api-sandbox.dimes.fi/v1/customer-docs |
| Demo repo | — | dimes-fi/dimes-demo-ui (React + Vite) |
Sandbox uses fake USDC (minted on request by Dimes team) and a fake CTF. Live Polymarket market data is read-only; fills are simulated against the fake CTF. Keys are env-scoped and not interchangeable.
- TypeScript, package:
@dimes-dot-fi/sdk(npm). - Sub-entries:
@dimes-dot-fi/sdk— HTTP client, quote engine, error types. No peer deps.@dimes-dot-fi/sdk/react— hooks + provider. Peer deps:react >=19,@tanstack/react-query >=5.@dimes-dot-fi/sdk/contract— on-chain tx builders + signature verification. Peer dep:viem >=2.
import { DimesClient, ApiKeyAuth } from "@dimes-dot-fi/sdk";
const client = new DimesClient({
auth: new ApiKeyAuth({
apiKey: process.env.DIMES_API_KEY,
walletAddress: "0x1234...abcd",
}),
});- Two auth schemes:
- Partner API key —
Authorization: Api-Key dm_live_skey_…. Used to mint user JWTs, read partner limits. - User JWT —
Authorization: Bearer <jwt>. 1-hour lifetime. Keyed on(wallet_address, partner_id). Used for quotes, positions.
- Partner API key —
- Mint a JWT:
POST /prediction-markets/tokenswith body{ "wallet_address": "0x…" }→ returns{ token, expires_at }. - Key rotation: two keys per environment can be active simultaneously for zero-downtime rotation. No auto-expiry. Rotate via Dimes team.
- Market browsing is public (no auth).
Quote (POST /prediction-markets/quotes, JWT, rate-limited 1 req/sec/wallet):
Request:
{
"market_ticker": "will-btc-hit-100k-2026",
"effective_side": "yes",
"leverage_bps": 50000,
"notional_usd_pips": "250000000",
"slippage_bps": 300,
"provider": "polymarket",
"allow_revision": false,
"order_type": "fok",
"min_fill_bps": 5000
}Response (abridged — full version has ~30 fields):
{
"id": "dm_off_abc123",
"entry_price_usd": "0.65",
"origination_fee_bps": 125,
"protocol_origination_fee_bps": 100,
"partner_origination_fee_bps": 25,
"polymarket_trading_fee_bps": 100,
"liquidation_fee_bps": 1000,
"current_liquidation_price_usd": "0.35",
"total_user_amount_usd": "562.50",
"expires_at": "2025-06-01T10:05:00.000Z",
"position_seed_hex": "0xa1b2c3d4…",
"on_chain_position_key": "0x1a2b3c4d…",
"polygon_vault_contract_address": "0x…",
"contract_signature": "0xabc…",
"signature_expiry": "1717236300"
}Quotes expire in 15 seconds. There's a draft → promote variant for better UX (POST /draft-quotes then POST /promoted-quotes/{id}).
On-chain open — two user txs:
// 1. Approve USDC to Vault
usdc.approve(vault, total_user_amount_usd_pips * 100);
// 2. Create position
vault.createPosition(positionSeed, marketId, tokenId, /*…*/);Backend detects, places hedge on Polymarket, emits position.opened over WS.
Close — single user tx:
vault.requestClose(on_chain_position_key);Backend sells the hedge, distributes proceeds. Only the original position owner can call this.
| Method | Path | Auth | Notes |
|---|---|---|---|
GET |
/prediction-markets/markets |
public or JWT/API-key | cursor pagination via limit, starting_after, ending_before |
GET |
/prediction-markets/markets/search?query=… |
same | |
GET |
/prediction-markets/markets/{ticker} |
same | 404 = customer_market_not_found |
GET |
/prediction-markets/contract-info |
public | returns evm_chain_id, vault address |
POST |
/prediction-markets/tokens |
API-key | mint user JWT |
POST |
/prediction-markets/quotes |
JWT | 1 req/sec/wallet |
POST |
/prediction-markets/draft-quotes |
JWT | same limit |
POST |
/prediction-markets/promoted-quotes/{draft_id} |
JWT | same limit |
GET |
/prediction-markets/positions |
JWT | filterable by status, market, token |
GET |
/prediction-markets/positions/{id} |
JWT | |
GET |
/prediction-markets/positions/{id}/transactions |
JWT | open/close/liquidation/settle/etc tx hashes |
GET |
/prediction-markets/partner-limits |
API-key |
Conventions: snake_case fields, kebab-case paths, list envelope { data: [...], has_more: bool }, monetary values returned as both pips (string) and USD (string).
status enum: pending | open | unwinding | closing | settling | closed | settled | liquidated | cancelled. Also state: active | inactive.
Nested objects: entry, current, risk, fees, timing.
Key risk fields:
risk.health_bpsrisk.current_liquidation_price_usdrisk.liquidation_buffer_bpsrisk.liquidation_fee_bpsrisk.margin_buffer_usd
Key timing fields:
timing.is_settlement_pendingtiming.is_voidedtiming.market_close_timetiming.market_status
Transport: Socket.IO. URLs:
| Scope | Prod |
|---|---|
| Partner positions | wss://api.dimes.fi/v1/ws/prediction-markets/positions |
| User positions | wss://api.dimes.fi/v1/ws/prediction-markets/user-positions |
| Partner markets | wss://api.dimes.fi/v1/ws/prediction-markets/markets |
| User markets | wss://api.dimes.fi/v1/ws/prediction-markets/user-markets |
Auth: API key for partner gateway (auth: {apiKey}), JWT for user gateway (auth: {token}).
Position events: position.created, position.opening, position.opened, position.close_requested, position.closed, position.settled, position.liquidated, position.force_unwound, position.reverted, position.cancelled.
Market events: market.discovered, market.eligibility_changed, market.max_leverage_changed.
User-gateway notification events: ORDER_FULFILLMENT_RETRYING, PARTIAL_OPEN_PROGRESS, PARTIAL_OPEN_FLOOR_MISSED.
Envelope:
{ "id": "evt_…", "type": "resource.action", "created_at": "...", "data": {...} }No heartbeat documented — we'll need to ask about reconnect/replay semantics.
Three patterns Dimes recognizes (all are Polymarket-specific wallet types):
- Polymarket Safe — 1-of-1 Gnosis Safe.
- Polymarket Proxy — EIP-1167 minimal proxy. No off-chain signatures supported.
- Polymarket Deposit Wallet — ERC-1967 proxy, default for new Polymarket API users. Uses EIP-712 signing with domain
{ name: "DepositWallet", version: "1", chainId: 137, verifyingContract: depositWalletAddress }. Uses a push-funded atomic 3-call batch so no separate USDC approval tx is needed. Limited to one create per tx.
Critical rule: the
wallet_addresspassed toPOST /quotesmust be the address that ends up asmsg.senderon-chain — for all three patterns that's the contract address, not the owner EOA.
Privy and generic AA wallets are not mentioned in the docs. Olympus uses Privy embedded EOAs + Gnosis Safes — compat is the #1 open question.
Set dynamically per market by depth/spread/slippage:
| Tier | Leverage | Liquidity profile |
|---|---|---|
| Deep | 8–10× | top-of-book ≥ 2–3% of notional depth, slippage ≤ 30–50 bps |
| Mid | 4–6× | aggregated depth ~1–2% at active bucket, slippage ≤ 75 bps |
| Thin / volatile | 2–3× | <1% depth or slippage >1% |
- Min leverage: 2×. Max leverage: 10×.
- J-factor recalculates every venue update.
- During the position, J-factor can reduce leverage as microstructure deteriorates (depth drains, spreads widen, fill rates degrade). The reduction is conditional on microstructure, not scheduled against time. Each reduction pushes the liq price further away.
Dimes protocol fees (all to Dimes, all on top of partner fee + venue fee):
| Fee | Rate | Base |
|---|---|---|
| Entry / origination | 2.0%–2.5%, scaled with leverage | collateral × leverage |
| Time-based | 0.05% / day, continuous | borrowed only: collateral × (leverage − 1) |
| Liquidation | 10% | protocol-provided capital: notional − collateral |
Partner origination fee: custom bps we set per quote, paid to a partner-controlled receiver wallet. Sits on top of the protocol fee.
Polymarket venue fees (peak per-leg at $0.50, round-trip ≈ 2×):
- Geopolitics 0%
- Sports 0.75%
- Finance / Politics / Tech 1.00%
- Culture / Economics / Weather / Other 1.25%
- Mentions 1.56%
- Crypto 1.80%
Polymarket builder rewards can be earned by passing a builder code (mechanism not detailed).
- Trigger: YES position liquidates when
underlying_price ≥ liquidation_price; NO position whenunderlying_price ≤ liquidation_price. - Full close only, no partial liquidation.
- Two-stage warning system precedes liquidation (mechanism not detailed).
- After liquidation: hedge unwound, remaining collateral credited to user, final PnL reflected in UI.
- Protected unwind mode: if liquidity is insufficient, Dimes "pauses new exposure until safe execution is possible."
- Onchain liquidation proof published per liquidation, containing position ID, timestamp, liquidation price, venue price data, signature of internal hedge unwind. Front-ends and users can audit.
Quote Pending → Hedging → Active → (Deleveraging) → Liquidation | Settlement Pending → Settled
Plus side-paths: Voided (market cancelled, YES/NO both pay $0.50, is_voided: true) and Reverted (open failed — revert_reason is one of exchange_unavailable, slippage_exceeded, unknown).
Supported:
- Binary markets
- Simple categorical markets
- Continuous-hedging markets (no jump-to-settlement risk)
- Markets with a clearly defined jump-to-settlement window
Explicitly excluded:
- Markets that "can resolve at any time" with unreliable hedging.
Eligibility gates: liquidity (depth, spread, orderbook stability, fill rate, update frequency, volume, holder distribution), resolution (stable pricing, prices within eligible ranges, current exposure within caps), venue (reliable price feed, predictable settlement, safe hedging path).
Exposure caps: market-level cap = fraction of hedgeable depth; side-level caps = independent YES vs NO.
- Global notional cap (system-wide).
- New entries rejected when venue goes erratic or stops updating.
- New entries rejected when spreads/depth move outside safe ranges; "rejected until conditions stabilize."
Envelope:
{ "error": { "type": "…", "code": "…", "message": "…", "params": {} } }| Type | HTTP | Meaning |
|---|---|---|
INVALID_REQUEST_ERROR |
400 / 404 / 409 | bad params or business-rule violation |
AUTHENTICATION_ERROR |
401 / 403 | bad/missing API key or JWT |
RATE_LIMIT_ERROR |
429 | includes Retry-After header |
API_ERROR |
5xx | Dimes-side problem |
Retryable codes: internal_server_error, too_many_requests, request_already_in_progress. Backoff exponentially from 1s. Everything else (validation, leverage caps, eligibility) is non-retryable.
Notable error codes: customer_auth_invalid_wallet_address, customer_market_not_found, quote_market_not_eligible, risk_engine_market_closed, quote_leverage_below_minimum, quote_leverage_exceeds_maximum, quote_leverage_exceeds_model_max, quote_user_position_limit_exceeded, quote_market_position_limit_exceeded, quote_entry_depth_too_low, notional_selector_insufficient_liquidity, quote_user_capital_exceeded, quote_market_capital_exceeded, quote_total_capital_exceeded.
"Leverage by Dimes" attribution lockup is required directly under the leverage selector. (Color/sizing rules not detailed.)
- Partner sets
partner_origination_fee_bps; Dimes keeps all protocol fees (entry, time, liquidation). - No geo restrictions imposed by Dimes; partner is responsible for compliance in their jurisdictions.
- No KYC obligation imposed.
- No SLA, service "as is", no warranties.
- Termination: 14 days written notice for convenience; immediate for material breach uncured within 7 days, regulatory events, insolvency/fraud.
- Liability cap = trailing 12 months of fees paid.
- Partner is forbidden from caching, modifying, or delaying Dimes-provided market state data.
- User data collected by partner remains the partner's responsibility.
Only the items that would actually block writing code for a manual leverage trading v1.
Olympus users have a Privy embedded EOA and (post-migration) a Gnosis Safe that holds the funds. Most active users trade from the Safe.
- Is the Polymarket Safe path you support compatible with a standard 1-of-1 Gnosis Safe owned by a Privy EOA, or do you require Polymarket's specific Safe deployment + guard/module config?
- Does
createPositionaccept EIP-1271 signatures so the Safe is the signer, or does the EOA owner sign? - Does the Vault support a gasless / meta-tx path for open and close (we'd run the relayer), or does every user need MATIC for gas?
- Anyone integrated Privy with the SDK already? Any known gotchas with
viem+ Privy + your EIP-712 typed-data shape?
- Which Polymarket categories are live in prod today, and is there a single field (beyond
accepting_new_positions) to ask "is this specific market eligible right now"? - Multi-outcome (>2) categorical markets — supported, or binary-only?
- In-play live sports: how do you handle orderbook gaps around goals — does J-factor preempt, or do users get liquidated by the jump?
- Is
current_liquidation_price_usdmonotonic for the life of the position, or does J-factor move it as leverage decays? (We need to know before we render a liq line.) - What's the price source for the liquidation trigger — mid, best bid/ask, VWAP?
- Can "remaining collateral" after liquidation ever go negative for the user, or is the user's downside bounded at their posted margin?
- For voided markets ($0.50 payout): confirm the exact formula for what the user gets back.
- Is there a min/max cap on
partner_origination_fee_bpswe can charge? - Partner origination fee — paid on open only, or also on close / liquidation?
- Polymarket builder rewards — how do we plug in our builder code, and do they come to us directly or through Dimes?
- JWT is 1h. We'll cache per-user JWTs in Redis — any cap on concurrent active JWTs per partner?
- Beyond the documented 1 quote/sec/wallet, is there a partner-level qps cap on quotes, positions read, or WS subscriptions?
- Do you know if Ares allows copy-trading with leverage today? Curious how they architected it — we may build this in v2.
- 14-day termination for convenience: what happens to open user positions on termination — forced close at mark, or settle to resolution?
Dimes Integration Q&A
Responses to your integration questions. Everything below is grounded in the live docs:
Q1. Wallet model
Q1.1 — Compatible with a standard 1-of-1 Gnosis Safe owned by a Privy EOA, or do you require Polymarket's specific Safe deployment + guard/module config?
A standard 1-of-1 Gnosis Safe works. That is exactly our "Polymarket Safe" pattern. The vault does not care whether
msg.senderis an EOA or a contract, and we require no guard or module config on the Safe. The one hard requirement: thewallet_addressyou pass toPOST /quotesmust be the address that will bemsg.senderon-chain, which for the Safe path is the Safe contract address, not the owner EOA. The wrong address fails the on-chain signature check.Context worth flagging: Polymarket now onboards net-new users onto deposit wallets (ERC-1967 proxy via their deposit-wallet factory), so Safe and Proxy are effectively existing-wallet / legacy paths. Your migrated users who already hold Safes are fine on the Safe path. Any brand-new user you provision should be on a deposit wallet (see Q1.3, that path is gasless).
Q1.2 — Does
createPositionaccept EIP-1271 so the Safe is the signer, or does the EOA owner sign?The owner EOA signs. Standard Safe flow: encode the vault
createPositioncalldata, wrap it in a SafeTx, the owner signs the SafeTx hash, thenexecTransactionis submitted and the Safe executes the vault call. Same pattern as any other transaction you would route through the Safe. Note the vault's own authorization is thecontract_signaturecarried in the quote (signed by our authorized signer), which is separate from the Safe owner's signature.Q1.3 — Gasless / meta-tx path for open and close, or does every user need MATIC?
Depends on wallet type:
relayer-v2.polymarket.com/submit), which requires Polymarket builder API credentials. No MATIC needed by the user.execTransaction(owner, your backend, or a relayer you run), so you can sponsor gas from your own infra if you want. We do not run a gasless relayer for the Safe/Proxy paths today.Net: put new users on deposit wallets and gas is a non-issue. The Privy-held-funds path works, but the user (or you) pays gas.
Q1.4 — Anyone integrated Privy with the SDK yet? Gotchas with viem + Privy + your EIP-712 shape?
Nobody has wired up Privy yet, so no battle-tested gotcha list. Ares had no issues with Turnkey. We added a Privy example in our demo UI (https://github.com/dimes-fi/dimes-demo-ui/blob/main/README.md) and created a new section in our doc for you: https://docs.dimes.fi/for-developers/privy-integration.
Q2. Markets
Q2.1 — Which categories are live in prod, and is there a single field beyond
accepting_new_positionsto check per-market eligibility?Live categories in prod are
cryptoandsportonly. Anything else is rejected withQUOTE_MARKET_UNSUPPORTED_CATEGORY. We usually support several hundred markets each day. We plan on expanding this coverage in Q3.accepting_new_positionsis the single field to check. For the per-side breakdown, readsided_eligibility.{yes,no}.accepting_new_positions(a market can accept YES but not NO), andrejection_reason_code(orsided_eligibility.{yes,no}.rejection_reason_code) tells you why a side is closed. Filter the markets list with?accepting_new_positions=trueto get only currently-eligible markets.Q2.2 — Multi-outcome (>2) categorical markets: supported or binary-only?
Supported, but underneath everything is binary. A multi-outcome market decomposes into a set of YES/NO markets, and each one independently supports leverage or not, at its own max leverage. The same
accepting_new_positions/sided_eligibilitycheck applies per sub-market. To map a Dimes market to its Polymarket counterpart, use thepolymarketobject on every market (polymarket.condition_id,polymarket.yes_token_id,polymarket.no_token_id,polymarket.slug); it is always present, since all live markets are Polymarket-sourced.Q2.3 — In-play live sports: how do you handle orderbook gaps around goals? Does the risk engine preempt, or do users get liquidated by the jump?
Two layers, and the second is where our real edge sits.
First, entry is gated: live markets that are too thin or too risky to enter are screened out up front via codes like
QUOTE_ENTRY_SPREAD_TOO_WIDE,QUOTE_ENTRY_DEPTH_TOO_LOW,QUOTE_ENTRY_BID_DEPTH_TOO_LOW,QUOTE_TRADING_WINDOW_CLOSING, and the excluded-sport / excluded-market-type codes. So the worst live states never accept new positions.Second, on an open position the first-line control is force-unwind / deleveraging (the position is partially unwound as risk rises), with liquidation as the backstop, not the default. The edge is that this deleveraging engine is trained on hundreds of thousands of market hours and uses that experience to minimize liquidations. It is sport, microstructure, and time-aware: the model undersdtands that a tied soccer game is allowed to carry less leverage in the final 15 minutes than in the first half (enforced through deleveraging), since a late goal is the sharpest swing the book can take, while that dynamic is much less pronounced in basketball, which scores more progressively.
Over the last 3 weeks this has held our liquidation rate to ~8%, versus a ~55% counterfactual over the same period without the proactive deleveraging engine: https://x.com/dimes_fi/status/2066893342546260020. This is where Dimes is really strong and this model is the reason we were able to secure institution credit underwriting to fund the margining of leverage positions.
On a genuinely discontinuous jump (a goal that clears whatever level the engine has already deleveraged to), a position can still be liquidated by the gap. The final protection there: the user's downside is bounded at posted collateral.
effective_collateralis floored at 0, so a jump can liquidate the position but can never push the user negative or beyond their margin. They cannot lose more than they put in, regardless of gap size.Q3. Risk / liquidations
Q3.1 — Is
current_liquidation_price_usdmonotonic for the life of the position, or does the engine move it as leverage decays?It moves. Do not treat it as static, and do not recompute it yourself from an LTV formula. The liquidation threshold is not pure LTV math (it incorporates the unwind-first / liquidate-last-resort logic), and it shifts as the position deleverages and conditions change. We give it to you live:
risk.current_liquidation_price_usd(and_pips) onGET /positions, plus push updates over WebSocket. Render your liq line off that live field rather than freezing the value from the quote.Q3.2 — Price source for the liquidation trigger: mid, best bid/ask, or VWAP?
The trigger references the bid (you would be exiting into the bid). Note the
mark_pricewe surface for PnL display is the mid, so do not conflate the two: PnL / mark = mid, liquidation trigger = bid.Q3.3 — Can "remaining collateral" after liquidation go negative, or is downside bounded at posted margin?
Bounded, never negative.
effective_collateralis floored at 0. On any exit (close, liquidation, settlement, void) we run the same waterfall: cover fees and repay the loan first, then the user gets whatever remains. The remainder can be 0 but never below it. The user's max loss is their posted collateral.Q3.4 — Voided markets ($0.50 payout): exact formula for what the user gets back.
A void pays $0.50 per token (50/50, no winner). We then apply the standard close waterfall:
where
loan_outstandingis the borrowed portion (notional - collateral) andfees_outstandingis accrued lifetime fee + accrued venue fee (no liquidation fee on a void). Fees and loan come off the top, the user receives the rest, floored at 0. You will see this land asresult.proceeds_usdon the settled position, withresult.realized_pnl_usd = proceeds - collateral.Q4. Fees & revenue share
Q4.1 — Min/max cap on
partner_origination_fee_bps?The partner origination fee is a per-integration parameter you set, layered on top of the protocol origination fee. The combined rate shows up as
origination_fee_bps=protocol_origination_fee_bps+partner_origination_fee_bpson the quote. There is no min/max.Q4.2 — Origination fee on open only, or also on close / liquidation?
Our origination fee is on open only. We take no fee on close.
Q4.3 — Polymarket builder rewards: how do we plug in our builder code, and do rewards come to us directly or through Dimes?
Send us your builder code and we wire it into the transaction flow. Your builder code (not ours) is what is attached on-chain, so your fees and volume attribution route to you directly through Polymarket's normal path, not through Dimes. This is the Ares setup: you take builder-code fees applied on every trade. The deposit-wallet relayer flow already runs on builder API credentials, so this slots in naturally.
Q5. Auth & rate limits
Q5.1 — JWT is 1h. We will cache per-user JWTs in Redis. Cap on concurrent active JWTs per partner?
No cap on concurrent active JWTs. You can cache them, but honestly we would not bother with Redis for this. Mint a fresh JWT on trading-terminal / UI load and refresh it every ~30 min, well before the 1h expiry. The only relevant limit is the JWT generation endpoint itself: 180 req/min per partner, which is far above what session-based minting needs.
Q5.2 — Beyond 1 quote/sec/wallet, any partner-level qps cap on quotes, positions read, or WS subscriptions?
The documented throttles:
/quotes,/draft-quotes,/promoted-quotes) per walletThe 1/sec applies only to the quote endpoints, because each quote pulls a lot of data from Polymarket and we throttle to stay under their limits. That is a worst case: with a warm cache (multiple partners quoting the same markets) you can effectively exceed 1/sec. No separate cap on WebSocket subscriptions to worry about.
For real-time UI, do not poll. Subscribe over WebSocket to market and position updates (run it in the frontend per-user, or index it in your backend). Our demo UI already does this and we can share the example. And if your UI needs more quote throughput than the 1/sec worst case allows, we can stand up additional / custom endpoints and tune per-partner limits to whatever your volume requires. Just tell us the shape of the load.
Q6. Copy-trading (v2, not v1)
Q6.1 — Does Ares allow copy-trading with leverage today, and how did they architect it?
Not yet. Ares has not built copy-trading with leverage. It is a strong idea and they will probably get to it, but it is not live today.
How it would map onto our rails: every position is a self-contained, signed quote that becomes an on-chain position keyed to one wallet, and leverage is a per-position parameter, not an account-level setting. So a follower wallet copies a leader simply by requesting its own quote for the same market / side / notional / leverage and signing with its own wallet. Leverage carries over for free because it is chosen per position. Nothing in our model blocks building this in v2.
One thing to frame carefully if you build it: a trade that is good at 1x is not twice as good at 2x. Leverage interacts with the path, not just the outcome. If the thesis ends up right but the match is heavily disputed with setbacks along the way, the position might have sometimes auto-deleveraged before settlement, so the 2x copier just carries additional financing cost for no real extra upside. It's situation specific, obviously. The product idea is very good. It just needs the right disclaimers around it so users understand that more leverage on a good call is not a free multiplier.
Q7. Legal
Q7.1 — 14-day termination for convenience: what happens to open user positions, forced close at mark or settle to resolution?
Termination stops new originations from the effective date, but existing open positions are honored and run to their natural resolution (or the user closes them normally during wind-down). We do not force-close at mark; that would crystallize user losses against the bounded-downside design.