Skip to main content
The quote is the authoritative number for what a trade costs. Read feeBreakdown and totalCostIncFees before the user commits (see Quotes & smart routing). After the trade, GET /execution/orders reports fees.quoted (the quote-time snapshot) and fees.actual for reconciliation. There are no up-front or recurring fees. We only make money when you do, starting at 20% of the fees you charge users, with volume-based discounts available.

Fee kinds

feeBreakdown.totalCost is price times shares plus venue, builder, bridge, and gas fees. It excludes app and referral fees. totalCostIncFees includes everything.

Venue fees

Each venue sets its own taker fee. GET /venue-markets returns it per market as feeRate, feeExponent, and feeBasis (fill, fill_in_game_only, winnings, or exit). null means AGG does not have the fee, not that it is free. Use these fields to render fee-inclusive price levels, and use the quote for the real cost. Formulas and a per-venue table: Venue fees.

Builder fee

Polymarket and Hyperliquid attribute order flow to a builder. Set your own builder code per venue in the admin dashboard. Without one, the platform default applies. See Builder codes.

App fee

Your app fee is the fee you charge your users. Configure rates per app in the admin dashboard under Fees. It applies to buys only, in basis points of the routed notional. On a managed buy the quote reserves the app fee out of maxSpend, and the fee is collected after the fill on the amount actually filled. feeBreakdown.appFee is the maximum, if the buy fills in full. Per-trade override. A request that carries your x-app-api-key can replace the rate for one trade with appFeeBips (0 to 10000; 0 waives it) on the quote or a direct order. The quote then reads feeBreakdown.appFeeCategory: "override". Without an API key the request returns 400 with a message starting app_fee_override_requires_api_key. On a sell it returns app_fee_override_buy_only. The platform share applies to an overridden fee the same way. A common split is a fixed total shared with a referrer: appFeeBips: 20 with no referrer, or appFeeBips: 10 with referrerFeeBips: 10 when there is one. The user pays 20 bips either way. Self-custody fills collect the app fee differently. See Self-custody trading.

Referral fee

A referral pays a third party out of the same trade. It is a second fee next to the app fee, in basis points of the routed notional, and it goes entirely to referrer. AGG takes no share of it. Send these on the quote or on POST /execution/orders. They need x-app-api-key. Without it the request returns 400 with a message starting referral_requires_api_key. The fill uses the quote’s referral and cannot change it. The quote echoes the accepted referral as referral: { referrer, feeBips, payer, payerAddress?, quotedFeeUsd }. A user-paid referral also appears in feeBreakdown.referralFee. An app-paid referral is not a user cost and never does.

User-paid

The referral is reserved from maxSpend next to the app fee and collected the same way as the app fee.

App-paid

The user pays nothing. You pay the referrer from referralPayerAddress. After the trade fills, a request for that wallet appears in pendingSignatures on GET /execution/status, with purpose: "referral_payout" and signerAddress set to your wallet. Answer it on POST /execution/fill/{quoteId}/signatures: Without referralPayoutChainId, the payout goes on the trade’s fee chain, or Polygon when that chain is not EVM. Sending referralPayoutChainId with a user-paid referral returns 400 with referral_invalid. On HyperCore the referrer receives spot USDC on Hyperliquid. The first payout to a referrer with no Hyperliquid account costs an extra 1 USDC that Hyperliquid charges to create it. Your wallet must hold the payout plus that 1 USDC, or the transfer is refused. The payout request appears only after the trade is already filled, so keep polling status past the terminal state until it shows up, and handle it from your backend:
The request expires 15 minutes after it appears. If it is never answered, the trade stays filled and the referral is recorded as expired. A partial fill pays the quoted amount. A failed fill pays nothing. In self-custody, the same pendingSignatures list also holds the trader’s own requests. A client that prompts the connected wallet must skip requests whose signerAddress is not its own.

Where a referral cannot be paid

A Kalshi buy settles from Solana USDC, where an EVM referrer cannot be paid. The quote carries a warning with reason: "referral_unpaid_on_solana", the user is not charged the referral, and nothing is paid. A user-paid referral on a Hyperliquid fill is sent to the referrer on HyperCore. Hyperliquid charges the sender 1 USDC to activate an address that has never received a HyperCore deposit. If the referrer’s address is not activated, the referral transfer either costs the user that 1 USDC or, if they can’t cover it, is rejected and the referral is not paid. The quote carries a warning with reason: "referrer_not_activated_on_hypercore", and the trade still executes. Fund the referrer’s HyperCore address once, with any amount, to clear it.

Reconciling

GET /execution/orders reports fees.quoted.referralFeeRaw and fees.actual.referral per trade: { referrer, payer, feeBips, dueRaw, paidRaw, status }, where status is confirmed, failed, expired, or skipped.

Withdrawal fees

POST /execution/withdraw/preview returns the fee as feeRaw and the amount the recipient gets as receiveAmountRaw. Fees come out of the withdrawal amount. See Funding & withdrawals.