Fee ledger entries
Each trade producesFeeLedgerEntry rows — one per role (maker /
taker). Both legs are charged: every order is signed with the taker
fee rate, so maker rows carry value too. See
Fees for the PS_QUADRATIC_V1 curve.
Read unit to tell a USDC fee from an in-kind one: a SELL-side fee is
taken in USDC, while a BUY-side fee is taken in OUTCOME_TOKENS —
the share haircut — denominated in the token named by tokenId. Note
token is the market’s collateral symbol (always USDC) and is not
the fee denomination.
cursor
echoed back as nextCursor. limit is capped at 500 (default 100).
Response:
amount is a decimal string with 18 fractional digits; parse it with a
decimal library, not a float.
Pagination
Keyset-paginated, same scheme as Trades: each response carries an opaquenextCursor — pass it back as
?cursor=<nextCursor> for the next (older) page. nextCursor is null only on
the last page. limit caps the page (max 500, default 100). The legacy
?before=<ISO-8601> still works but cursor is preferred (unique tiebreaker —
a single match writes both the maker and taker fee rows with the same
createdAt, so a timestamp-only cursor would skip one at a page edge).
Fee tier
tier is always 0, and makerBps
equals takerBps because every order is signed with the taker rate and
the contract charges each leg its own signed rate. takerBps is the
platform default — an individual market may override it, so
/api/markets/{slug} .feeTakerBps is authoritative for a specific
order.
Reconciling against on-chain
Fee ledger rows carry no transaction hash — join ontradeId. The
matching row in GET /api/me/trades
carries status, txHash (set once the settlement transaction is
broadcast) and settledAt. Fee rows are written when the trade is
matched and removed if that trade’s on-chain settlement fails, so a
failed trade leaves neither a trade row nor a fee row behind.