Skip to main content

0.10.0

  • Breaking change: trade, activity, position, and Combo feeds now use server cursors and automatically retry transient rate limits. Restart scans with a new first page; previously saved cursors are not reusable. Replace market filters with conditionId and top-level start/end with window. Time windows accept epoch seconds or Date values; window: "full" requests full history. Condition filters accept at most 20 distinct IDs.
  • Breaking change: listPositions(...) now covers open, redeemable, and closed positions. Replace listClosedPositions(...) with status: PositionStatus.Closed, and listMarketPositions(...) with a public client’s listPositions({ conditionId }). Market-holder results are individual positions rather than groups by outcome. The default Open status includes redeemable positions.
  • Breaking change: secure listPositions(...) always selects the authenticated wallet and rejects user: null. Use a public client to list a market’s holders.
  • Breaking change: position rows expose currentSize, currentPrice, totalSize, and explicit fee-exclusive entry economics. Money, size, price, and PnL values use decimal strings; entryFeesUsdc is disclosed separately and must not be deducted from entryCostUsdc again. Optional feed metadata now uses undefined for absent values, and returned timestamps use epoch milliseconds.
  • Breaking change: request vocabularies now use exported enums, including SortDirection, TradeFilterType, PositionFilterType, PositionSortBy, ComboPositionSortBy, and TipSide. Replace the removed Side type with OrderSide.
  • Added migration activity through ActivityType.MIGRATION and MigrationActivity, plus tip activity through ActivityType.TIP and TipSide. Combo positions now support ComboPositionStatus.Redeemable as a sole status filter.
  • Breaking change: Combo activity includes positionId on every row and removes transactionAt, logIndex, and moduleId. Use timestamp for the activity time.
  • Breaking change: listMarketHolders(...) now returns a paginator. Pass conditionIds and pageSize; minBalance is measured in display shares. Optional includePnl adds gross holdings and position economics for one condition ID with a page size of at most 100. Merge outcome groups across pages by assetId.
  • Breaking change: fetchPortfolioValue(...) returns one PortfolioValue with a decimal-string value, and accepts conditionIds instead of market. Position and portfolio reads also canonicalize PolyV2 condition IDs.
  • Added fetchUserStats(...), fetchUserPnl(...), and fetchUserVolume(...) for account analytics, with authenticated-wallet defaults on secure clients. Breaking change: replace fetchTradedMarketCount(...) with the exact distinct-market count on fetchUserStats(...). It returns null for an unknown user.
  • Breaking change: replace fetchPriceHistory(...) with cursor-paginated listPriceHistory(...). Pass assetId and exactly one time selection: interval, start with optional end, or asOf. Replace minute-based fidelity with bucketSeconds; omit it for automatic resolution. Explicit ranges span at most 15 days. Each point includes a decimal-string price, epoch-millisecond timestamp, and resolutionSeconds.
  • Breaking change: replace listOpenInterest(...) with fetchOpenInterest(...) and pass conditionIds for selected markets. Values represent priced gross open interest in USDC.
  • Breaking change: fetchEventLiveVolume(...) accepts eventIds and returns cumulative taker volume in shares, with market rows in markets and a decimal-string takerVolumeTotal.
  • Breaking change: builder rankings now return cursor-paginated BuilderStanding rows. Builder volume returns complete BuilderVolumePoint date buckets; bucketLimit bounds buckets rather than builder rows. Replace timePeriod with window for rankings or interval for volume. Use BuilderVolumeInterval.Year for yearly buckets.
  • Breaking change: trader rankings use cursor pagination, window, and sortBy; the list no longer accepts user or userName filters. Use fetchTraderLeaderboardStanding({ user }) for one wallet’s standing. Added listBiggestWinners(...) with market and Combo variants.
  • Added fetchResolutions(...) for resolution lifecycle lookups by question, condition, or event, with typed timestamps, transaction metadata, payouts, and finality. Unset values are omitted.
  • Combo leg markets now preserve question, groupItemTitle, sportsMarketType, line, and outcomes. Trade activity tolerates unknown outcome metadata.

0.9.0

  • Order estimation, preparation, creation, and placement now accept protocol-neutral assetId values. Structured PolyV2 position IDs select PolyV2 routing automatically, while tokenId remains available as a deprecated alias.
  • Added fetchTradingApprovalsState(...) for reading a wallet’s missing trading approvals without a signer or transaction workflow. Malformed approval-check responses now raise UnexpectedResponseError.
  • Markets and events now expose their protocol through version, and markets expose Combo eligibility through market.state.comboStatus. Combo status values introduced after this release pass through as strings.
  • Secure account reads now reject invalid request values and user: null with UserInputError instead of silently selecting the wallet or throwing an untyped error.
  • Session Key authorization and revocation submissions now allow up to five minutes for relayer validation and broadcast.
  • Breaking change: revokeSessionKey(...) now resolves to void once the Session Key leaves the active registry. The backend continues canceling orders and finalizing the on-chain revocation asynchronously. See Revoke a Session Key.
  • Team entries on event and team-list responses now preserve their ordering value.
  • Breaking change: removed legacy AMM fields from market and event models, along with the marketMakerAddresses filter on listMarkets(...). Responses that still contain the removed fields continue to parse, but those values are ignored. Use the supported CLOB metrics where applicable.

0.8.1

  • client.authorizeSessionKey(...) no longer accepts validUntil. This is a breaking change. Each Session Key authorization expires after 180 days. Revoke a Session Key to end access sooner.

0.8.0

  • Added protocol-neutral assetId and conditionId fields to CLOB reads, filters, realtime events, and Data API responses. The deprecated tokenId, tokenIds, and market aliases still work.
  • Position lifecycle methods now split, merge, and redeem ordinary PolyV2 positions. Redemption by position ID supports binary, negative-risk, and Combo positions.
  • setupTradingApprovals() and prepareTradingApprovals() now include the PolyV2 binary and negative-risk modules.
  • Combo market discovery now exposes whether a market is pending and excludes pending markets when selecting live RFQ legs.
  • Live volume reads now return null for empty market identifiers.
  • Renamed the low-level CTF and Router transaction builders and their error guards to contract-specific names. This is a breaking change for callers that import them directly.

0.7.0

  • Added scoped Deposit Wallet session keys through client.authorizeSessionKey(...), client.fetchSessionKeys(), and client.revokeSessionKey(...). Secure clients can use an authorized session signer for ordinary operations. Scopes default to ALL; known scopes are enumerated while newer scope strings remain usable.
  • Account notifications now use a NotificationType-discriminated union with a typed payload for every supported kind. fetchNotifications(...) omits kinds unknown to this SDK version and rejects a response when a recognized kind has a malformed payload.
  • RateLimitError.rateLimit now carries the Poly-RateLimit-* state returned with a rejection. Pass onRateLimitUpdate when creating a client to receive per-signer bucket, remaining, reset, tier, and warning updates from any response that reports them.
  • Order estimation, preparation, creation, and placement now accept PolyV2 position IDs and route them through Exchange V3 signing and trading approvals. Existing token-ID orders remain supported.
  • listComboPositions(...) now accepts either one status or an array of statuses.
  • RequestRejectedError.restriction distinguishes matching-engine restarts from post-only mode, and retryAfter falls back to the response body’s retry_after_seconds value when the header is absent. Batch post-only rejections now use the post_only_mode order error code.
  • Order preparation now tolerates insignificant floating-point drift on valid tick-grid prices and uses exact fixed-point amount calculations. CLOB salts that cannot round-trip through a JavaScript number are rejected before submission.
  • Breaking change: deprecated CtfConditionId type, use ConditionId` instead.

0.6.0

  • Added requester-side Combos RFQ support through client.requestComboQuote(...), client.acceptComboQuote(...), and client.waitForComboFill(...). You can also call fetchRfqStatus from @polymarket/client/actions. Authenticate requests with builderApiKey(...) or remoteBuilderSigning(...). Winning quotes can be stored as JSON, and SELL quotes include the exact post-fee netReceive. No-quote, decline, and expiry outcomes return values. Gateway rejections throw RfqRequestRejectedError.
  • Market outcomes now include a nullable PolyV2 positionId alongside the CLOB tokenId. New code should use the protocol-neutral ConditionId, ConditionIdSchema, OptionalConditionIdSchema, and toConditionId. The CTF-named aliases and market-level positionIds array remain available for compatibility but are deprecated.
  • Breaking change: client.fetchLastTradePrice(...) now returns LastTradePrice | null. It returns null when the token has not traded. client.fetchLastTradePrices(...) leaves untraded tokens out of the response, so match results by tokenId instead of array position.

0.5.0

  • Added a Perps dead man’s switch: session.armAutoCancel() schedules a one-shot cancel-all, session.disarmAutoCancel() clears it, and session.fetchAutoCancelStatus() reports the current deadline and daily trigger usage. Arming after the daily limit raises AutoCancelDailyLimitError.
  • Perps funding history and realtime funding events now include a required id, typed as PerpsFundingPaymentId.
  • Fixed session.placeOrder() missing private order updates that arrive before the command acknowledgement. When the caller omits a client order ID, the SDK now generates one before submitting the order.

0.4.0

  • Added PerpsSession.updateMargin, which adjusts isolated margin for an instrument position. Positive amount values add margin; negative values remove it.
  • Repeated order preparation now caches market configuration and platform and builder fees. If cached tick data rejects a limit or protected market price, the SDK fetches current metadata once before returning the input error.
  • Unprotected market orders now derive depth, price, tick size, and exchange selection from one live order book response. maxSpend remains an estimated all-in spend target based on recently resolved fees, not a hard cap.
  • AcceptedOrderResponse.orderId is now typed as OrderId.
  • Breaking TypeScript type change: OrderBook.tickSize is now a numeric TickSizeValue instead of a DecimalString.

0.3.0

  • Added typed 30-second and 60-second Chainlink TWAP realtime subscriptions. subscribe validates subscription input when called: an unsupported TWAP window throws UserInputError before the connection opens.
  • Added Perps account notifications: session.listNotifications(), session.fetchUnreadNotificationsCount(), session.markNotificationsRead(), and a notifications session WebSocket channel with typed notification events.
  • Perps fills pagination now uses the API-native cursor and adds a sort direction option (newest first by default). Previously issued SDK-encoded fills cursors no longer work.
  • Added the DEPOSIT, WITHDRAWAL, and TAKER_REBATE activity types. listActivity now returns all activity types by default, including deposits and withdrawals.
  • RequestRejectedError and RateLimitError now expose retryAfter from the Retry-After response header.
  • Fixes:
    • Open order createdAt and expiresAt now parse epoch-seconds wire timestamps correctly instead of treating them as milliseconds.
    • RFQ quote rejections now carry the granular Combos quote-validation error codes instead of a generic validation failure.
    • Deposit Wallet gasless and Collateral Return submits now self-heal nonce mismatches: when the relayer rejects a batch and reports the on-chain nonce, the SDK re-signs the batch with that nonce and resubmits it once.
    • Cursor-paginated reads no longer report the per-page item count as Page.totalCount. Use page.items.length instead.

0.2.0

  • Added client.waitForOrderFillSettlement(order), which waits until every fill in an order response reaches a terminal settlement outcome and returns the settlement transaction hashes. Matched order responses are no longer guaranteed to include transactionsHashes; use this method to obtain hashes reliably.
  • ClobTrade.status is now typed with the shared TradeStatus enum instead of a plain string.
  • Added Collateral Return support: planCollateralReturn returns an inspectable plan and executeCollateralReturnPlan signs and submits it for Deposit Wallet, Safe, and Proxy accounts, returning a transaction handle.
  • Added isolatedOnly to PerpsInstrument, indicating whether the instrument supports only isolated margin.
  • Added volume-based fee tiers to the Perps fee schedule: each PerpsFeeScheduleEntry carries a tiers array of PerpsFeeTier values, including negative maker rebate rates.
  • Perps withdrawal statuses are now forward-compatible: known statuses are enumerated in PerpsKnownWithdrawalStatus, which adds failed, and statuses introduced after a release flow through as plain strings instead of failing the response parse.
  • Deprecated the PerpsWithdrawalStatus value alias; migrate enum member access:
  • Fixed offset-paginated list methods silently stopping after the first page when pageSize reached the server’s limit cap. pageSize is now validated per endpoint and values above the cap are rejected with UserInputError. A full page reports hasMore: true; when a collection ends exactly on a page boundary, the final page is empty.
  • Limit and protected market order prices must be a multiple of the market tick size. Off-grid prices (for example 0.007 on a 0.005 tick market) are now rejected client-side instead of by the exchange after signing.

0.1.0

  • Graduated the SDK to the stable 0.x release line, marked Perps APIs as experimental, and removed deprecated compatibility APIs.
  • Added Perps support for reduce-only orders, account stats, cancel-all, TP/SL metadata and placement, batched fill and trade frames, and stricter order request validation.
  • Added conditionId aliases to CLOB order book, open order, trade, and builder trade models while keeping market available as a deprecated alias.
  • Typed CLOB cancellation results with branded OrderId values for canceled and notCanceled keys.

0.1.0-beta.18

  • setupTradingApprovals and prepareTradingApprovals no longer request approvals for the retired CLOB v1 Neg Risk Adapter.
  • Streams drop unknown or unreadable WebSocket frames instead of closing the connection. RFQ quoter sessions no longer fail with TransportError on an unrecognized frame; a caller waiting on an unreadable acknowledgement fails through its acknowledgement timeout instead.
  • Removed RfqKnownInboundMessageSchema from @polymarket/bindings; each RFQ inbound message schema declares its own object shape directly.

0.1.0-beta.17

  • RFQ quoter sessions now keep running when the server introduces new error codes. RfqErrorCode is an open type: known codes are enumerated in RfqKnownErrorCode, and unrecognized codes flow through rejection errors as plain strings.
  • Deprecated the RfqErrorCode value alias; migrate enum member access:
  • Added ConnectionLostError carrying the WebSocket close code and reason. Losing an RFQ session connection now rejects in-flight operations and fails the session iterator with it, instead of ending the event loop silently. Closing the session still ends iteration cleanly.
  • Streamed market and user events normalize empty-string optional decimal fields (for example a trade’s feeRateBps or a price change’s bestBid and bestAsk) to null.
  • Batch price reads (fetchPrices, fetchMidpoints, fetchSpreads) return TokenId-keyed records of branded decimal strings.
  • Perps sessions handle fills and trades frames that batch multiple entries.

0.1.0-beta.16

  • Added RESOLVED_PARTIAL to ComboPositionStatus so Combo positions that resolve at a fractional payout (for example a voided leg) parse correctly instead of failing validation.

0.1.0-beta.15

  • Combo activity now parses the canonical type field returned by the Data API, instead of deriving lifecycle actions from legacy fields.

0.1.0-beta.14

  • Added SDK pagination for Combo lifecycle activity and server-cursor pagination for Combo positions.
  • Added Combo position sync request fields and exposed outcome and redeemable on Combo positions.
  • Branded Combo activity row IDs.
  • Breaking beta change: Combo activity and position fields now use wallet, amount, and payout; Combo activity rows no longer expose moduleKind.

0.1.0-beta.13

  • Added listMarketClarifications for reading market clarification text with SDK-owned pagination and market, event, state, question, and transaction filters.
  • Fixed legacy Proxy wallet gasless execution and added live Safe and Proxy wallet coverage.
  • Resolve closed markets when preparing market position redemptions.
  • Gasless transaction handles now wait for relayer transactions to reach confirmed state before resolving.

0.1.0-beta.12

  • Require GTD limit order expirations to be at least 3 minutes in the future.

0.1.0-beta.11

  • Support CLOB order tick sizes 0.005 and 0.0025.
  • Pagination request cursors now infer the branded pagination cursor type.

0.1.0-beta.10

  • Preserve already-deployed legacy UUPS Deposit Wallets when createSecureClient resolves the default wallet, while new Deposit Wallet deployments use the beacon factory path.

0.1.0-beta.9

  • Added PriceHistoryInterval and SearchSort exports, preserved groupItemTitle on normalized markets, and published expectPrivateKey from @polymarket/types.

0.1.0-beta.8

  • RFQ quoter sessions now emit typed trade events for confirmed Combos fills.
  • RFQ rejection errors now expose errorId values and parse INVALID_SIGNATURE and INTERNAL_ERROR codes.

0.1.0-beta.7

  • Added parentEventId to Event so child events can link back to their parent event.
  • Added maxPrice and minPrice protection fields to market order requests.
  • Handle legacy multi-outcome markets more safely: listMarkets skips markets that cannot be represented by the binary market model, and fetchMarket returns a typed SDK error for unsupported markets.
  • Normalize empty-string order and activity fields to SDK values: decimal amounts become "0", missing maker order fee rates become null, and missing trade or position market icons become null.
  • Parse Combo trade activity rows with an isCombo discriminated union.
  • Support new Combos RFQ websocket error codes for balance, allowance, and pre-execution reservation failures.
  • Broad user websocket subscriptions now omit market filters so all-market streams receive trade events.
  • Retry rejected JSON-RPC eth_call batches by splitting them into smaller batches.

0.1.0-beta.6

  • Point Combos RFQ endpoints at the production domains: combos-rfq-api.polymarket.com (REST) and combos-rfq-gateway-quoter.polymarket.com (quoter WebSocket).

0.1.0-beta.5

  • Added listComboMarkets for fetching the Combo market catalog with typed bindings and SDK-owned pagination. See Combos.
  • Parse RFQ quote rejections that use the SUBMISSION_WINDOW_CLOSED gateway error code.

0.1.0-beta.4

  • Added Combos support for multi-leg RFQ positions. See Combos.
  • Reject whitespace-only search queries and trim leading or trailing search input.
  • ConditionId is now deprecated in favor of CtfConditionId; existing ConditionId exports remain available as deprecated aliases.

0.1.0-beta.3

Secure client setup now defaults to the Deposit Wallet flowcreateSecureClient can now derive and use the signer’s deterministic Deposit Wallet when you omit wallet. If you already know which Polymarket wallet you want to use, keep passing wallet.
If you want to keep account selection explicit, no change is required:
setupTradingApprovals() now waits internallyYou no longer need to wait on the returned handle. Call the method once before trading; it is safe to call again if approvals are already set.
Gasless setup helpers are deprecatedYou no longer need to call isGaslessReady() or setupGaslessWallet() in the normal setup path. Create the secure client, then set up trading approvals.

0.1.0-beta.2

First beta release of the unified TypeScript SDK. Install the beta package with your package manager: