Skip to main content
Testnet values — not real money. Any concrete feeRateBps, k, or bps numbers quoted on this page apply to the ADI-testnet deployment (chainId 99999) and are placeholder rates used for partner integration and load-testing — no real money flows. The formula (fee = k × P × (1 − P) × outcomeTokens) and the integration contract (market.feeTakerBps as the canonical signing input) are stable across environments.

The formula

  • P is the execution price, 0 < P < 1.
  • k is a period-specific coefficient.
  • outcomeTokens is the number of outcome tokens traded.
  • The curve peaks at P = 0.5 (max uncertainty) and decays to 0 at the extremes.
  • Both sides of every fill pay this fee. The exchange contract charges each leg of a fill at the feeRateBps the user signed into the EIP-712 Order, deducted from the asset that leg receives (collateral on SELL, outcome tokens on BUY). Every signed Order carries the market’s live feeTakerBps, so there is no zero-fee maker leg.

Why quadratic (not linear)?

At the same feeRateBps, the linear min(P, 1−P) curve (Polymarket’s default) charges twice as much at the top of the book. Away from P = 0.5 the two curves converge, and both reach zero at the extremes. Fee per outcome token, in units of k (feeRateBps / 10_000): Effective feeRateBps ↔ k: feeRateBps = k × 10_000. The platform default rate (makerBps / takerBps, the same for every wallet) is available at GET /api/me/fee-tier.

Three fee surfaces — which one to use

The API exposes three fee values; partners often ask which one “actually applies.” Short answer:
Only market.feeTakerBps belongs in the signed Order. Signing with the platform period rate or your tier rate produces a digest that doesn’t match the CTFExchange reconstruction → bad_signature on every order. Always pull feeTakerBps from the per-market response and pass it into your signing helper unmodified.
A worked example for a market whose rate is overridden to 100 while the platform default is 140: The on-chain charge uses 100 because that is what the signed Order carries, and each /api/me/fees row records the fee amount taken on that leg. There is no per-wallet discount at fill time.

Charging direction

The asset the fee is taken in is determined by which side of the fill each party held — the same rule applies regardless of maker/taker role:
  • Seller (whichever side is sending outcome tokens for collateral): fee deducted from collateral proceeds. fee_collateral = k × P × (1−P) × outcomeTokens.
  • Buyer (whichever side is sending collateral for outcome tokens): fee deducted in outcome tokens. fee_tokens = k × (1−P) × outcomeTokens.
Both give the same USD value for the same fill — just denominated in the asset that side is receiving. On a single match the contract charges both legs; per-fill /api/me/fees carries one row per denomination per trade (unit ∈ {USDC, OUTCOME_TOKENS}, role ∈ {maker, taker}).

How fees appear in the response

Trade rows from GET /api/me/trades and GET /api/orders/{id}/fills carry fee together with feeUnit (and feeTokenId for in-kind fees):
Read feeUnit before interpreting fee. This is a BUY leg, so the fee is denominated in outcome tokens — the in-kind share haircut, not dollars. The seller-side collateral formula k × P × (1 − P) × outcomeTokens yields a different quantity in a different asset, so the two are not interchangeable: never sum fee across legs without checking feeUnit first. The synchronous trades[] in the POST /api/orders/place / place-batch response carries fee only, with no feeUnit. It is the trade-level USDC figure k × P × (1 − P) × quantity, even on a BUY leg that was charged in outcome tokens, so read the per-leg fee from the endpoints above or GET /api/me/fees. For per-fill audit, use GET /api/me/fees.

On-chain equivalence

The off-chain fee matches the on-chain fee charged by CTFExchange at settlement time, modulo integer-division rounding (≤ 1 atomic USDC unit). Same feeRateBps value signs into the EIP-712 Order.

Fee cap

Contract enforces feeRateBps ≤ MAX_FEE_RATE_BIPS (1000). Peak-at-0.5 at the cap is 2.5%. Raising requires Board approval and redeploy.

Examples

Rebates

The schedule covers fees. Rebates to market makers are a separate programme and are not reflected in /api/me/fees. They are paid on the cadence set in your market-maker terms (weekly or monthly). Contact partners@predictstreet.com.