Changelog¶
All notable changes to this project will be documented in this file. Format follows Keep a Changelog.
[Unreleased]¶
[0.6.21] — 2026-04-10¶
Added¶
expand_userparameter onget_xtracker_trackingsandget_xtracker_user_trackings— flattens nesteduserdict into prefixed columns (userHandle,userPlatform, etc.).expand_trackingsparameter onget_xtracker_users— flattens nestedtrackingslist into rows with prefixed columns.expand_countparameter onget_xtracker_users(defaultTrue) — flattens_countdict into columns likecountPosts.examples/xtracker_overview.py— end-to-end demo of all 7 XTracker endpoints.
Fixed¶
get_xtracker_userandget_xtracker_trackingnow run throughpreprocess_dictso datetime fields (startDate,endDate,createdAt, etc.) are parsed aspd.Timestamp.get_xtracker_usermaterialises the nestedtrackingslist as aDataFrame[XTrackerTrackingSchema].get_xtracker_trackingpreprocesses the nesteduserdict.- Added
date,importedAt,lastSynctoDEFAULT_STR_DATETIME_COLUMNS. - Added
user,trackings,countto_EXPAND_PREFIXESso prefixed columns are datetime-parsed after expansion.
[0.6.20] — 2026-04-09¶
Added¶
- XTracker mixin — new
polymarket_pandas.mixins._xtracker.XTrackerMixinexposing all 7 endpoints of thextracker.polymarket.compost-counter API (no auth,{success, data, message}envelope auto-unwrapped). Powers the "# tweets / # posts in window" markets (Elon, Trump, Zelenskyy, etc.). - Methods:
get_xtracker_users,get_xtracker_user,get_xtracker_user_posts,get_xtracker_user_trackings,get_xtracker_trackings,get_xtracker_tracking,get_xtracker_metrics. - 5 new pandera schemas (
XTrackerUserSchema,XTrackerPostSchema,XTrackerTrackingSchema,XTrackerDailyStatSchema,XTrackerMetricSchema) and 2 TypedDicts (XTrackerUser,XTrackerTracking). _request_xtrackerrequest helper onPolymarketPandasusing a newxtracker_urlfield, plus MCP tool wrappers.- New
polymarket_pandas.parsersmodule with vectorized regex enrichers formarketsGroupItemTitle: classify_event_structure(data)— labels each event as Single-Outcome / negRisk Multi-Outcome / Non-negRisk Multi-Outcome / Directional / Bracketed.parse_title_bounds(data)— extractsboundLow,boundHigh,direction,thresholdfrom bracket / arrow titles.parse_title_sports(data)— extractsspreadLine,totalLine,sidefrom sports market titles ("Spread -1.5", "O/U 8.5", "Over 2.5").spreadLineis named to avoid colliding with the unrelatedMarketSchema.spreadAPI field.coalesce_end_date_from_title(data)— fills NaTmarketsEndDateby parsing the "Month Day" string in the title, inferring year frommarketsStartDatewith Dec→Jan rollover handling.PolymarketPandas.fetch_sports_event(sports_market_type, ...)— convenience method onGammaMixinthat finds an open event containing markets of the given type viaget_markets(sports_market_types=[...])and re-fetches the parent event with markets sliced byconditionId. Pass-through filter kwargs mirrorget_markets(limit,order,ascending,closed, date / liquidity / volume ranges,tag_id).examples/market_structures.py— end-to-end demo printing one representative event for each of the 5 core structures plus 5 hand-picked extras (BTC up/down daily, Sports Moneyline / Spreads / Totals / Both Teams to Score).- 22 new unit tests in
tests/test_parsers.pycovering the four parsers, plus 2 mocked HTTP tests intests/test_unit.pyforfetch_sports_event.
Fixed¶
EventSchema.negRisk— switched dtype frombooltopd.BooleanDtypeso the upstream API's null values survive validation. Livetest_get_eventswas crashing withCould not coerce data_container into type boolafter Polymarket started returning<NA>fornegRiskon some events.
[0.6.19] — 2026-04-09¶
Added¶
- Builder attribution on order placement: when
POLYMARKET_BUILDER_API_KEY/_SECRET/_PASSPHRASEare configured,place_order,place_orders,submit_order, andsubmit_ordersautomatically attachPOLY_BUILDER_*headers alongside L2 auth so matched fills are credited to the builder for rewards. Header-only — no changes to the signed EIP-712 order struct. _request_clob_private(..., attribute=True)keyword flag and_has_builder_creds()helper.builder_clienttest fixture and 4 unit tests covering header attach/skip behavior.
[0.6.17] — 2026-04-03¶
Fixed¶
ActiveOrderSchema.expiration— changed fromstrtopa.Timestamp(matches preprocessing)
[0.6.16] — 2026-04-03¶
Fixed¶
ActiveOrderSchema— added missingexpirationandcreatedAtfieldsPositionSchema— added missingendDateandeventIdfields
[0.6.15] — 2026-04-03¶
Added¶
PlaceOrderSchemaandSubmitOrderSchemapandera input validation forplace_orders/submit_orderspost_onlyparameter onplace_order,submit_order,place_orders,submit_orders- 15-order batch limit validation on
place_orders
Changed¶
SubmitOrderSchemauses camelCase column names (tokenId,orderType,postOnly,negRisk,tickSize,feeRateBps) to match API conventionOrderSchemais now an alias forPlaceOrderSchema
[0.6.14] — 2026-04-02¶
Changed¶
- Renamed
FIXIE_URLenv var toHTTP_PROXYfor proxy configuration
[0.6.13] — 2026-04-02¶
Added¶
- 13 new pandera schemas — every
pd.DataFrame-returning method now has a schema:TagSchema,SeriesSchema,CommentSchema,SportsMetadataSchema,TeamSchema,MidpointSchema,MarketPriceSchema,LastTradePricesSchema,BuilderVolumeSchema,PositionValueSchema,BridgeSupportedAssetSchema,BridgeTransactionSchema. Return types updated toDataFrame[Schema]. ms_int_datetime_columns— new preprocessing field for Unix-millisecond timestamps (createdTimeMs,estCheckoutTimeMs), parallel to the existingint_datetime_columns(seconds). Wired through client, sync WS, async WS.- 58 live integration tests covering all non-authenticated endpoints with pandera schema validation against real API responses.
Fixed¶
get_price_history— now extracts thehistorylist from the response dict and convertstto UTCdatetime64. Previously returned a singlehistorycolumn of raw dicts.get_bridge_supported_assets— now returns aDataFramewithtokenobject flattened viajson_normalizeintotokenName,tokenSymbol,tokenAddress,tokenDecimalscolumns. Previously returnedlist[dict].PriceHistorySchema.t— changed frominttoTimestamp.CurrentRewardSchema.sponsorsCount— changed frominttofloat(API returns NaN when absent).
[0.6.12] — 2026-03-31¶
Fixed¶
get_accounting_snapshotnow runspreprocess_dataframeon CSV data —valuationTimeparsed as datetime, numeric coercion applied.- Added
valuationTimetoDEFAULT_STR_DATETIME_COLUMNS.
Added¶
examples/accounting_snapshot.py— download and display user portfolio.
[0.6.11] — 2026-03-31¶
Changed¶
pd.Timestampaccepted in datetime filter params —get_price_history(startTs,endTs),get_user_trades/get_builder_trades(before,after),get_user_activity(start,end), and their_allvariants now acceptpd.Timestampin addition toint/str. Timestamps are auto-converted to Unix seconds (CLOB) or ISO-8601 (Gamma) as needed.filter_paramsnow also convertsdatetime.datetimeto ISO-8601.
[0.6.9] — 2026-03-31¶
Fixed¶
- Bool columns now use nullable
BooleanDtype— previouslyastype(bool)silently converted NaN toTrue. Now NaN is preserved aspd.NA. - Added 12 missing bool columns to
DEFAULT_BOOL_COLUMNS:acceptingOrders,automaticallyActive,enableOrderBook,ended,featured,live,negRisk,negRiskAugmented,new,requiresTranslation,showAllOutcomes,showMarketImages. These (and theirevents*/markets*prefixed variants) were staying asobjectdtype. - Added
finishedTimestamptoDEFAULT_STR_DATETIME_COLUMNS— sports eventseventsFinishedTimestampwas not being parsed as datetime.
[0.6.8] — 2026-03-31¶
Added¶
expand_rewards_configflag onget_rewards_markets_current,get_rewards_markets_multi,get_rewards_market,get_rewards_user_markets(and their_allvariants) — flattens nestedrewards_configlist into one row per config entry withrewardsConfig*prefixed columns.expand_tokensflag onget_rewards_markets_multi,get_rewards_market,get_rewards_user_markets— flattens nestedtokenslist into rows withtokensTokenId,tokensOutcome,tokensPricecolumns.expand_earningsflag onget_rewards_user_markets— flattens nestedearningslist into rows withearningsAssetAddress,earningsEarnings,earningsAssetRatecolumns.- Pandera schemas updated with all expanded field annotations.
examples/async_trades_orders.py— async client example fetching trades and active orders.
Fixed¶
- Unix-timestamp datetime columns (
createdAt,matchTime, etc.) from CLOB API were parsed as 1970 dates.preprocess_dataframenow auto-detects numeric strings/ints (>1e9) instr_datetime_columnsand converts withunit="s".
[0.6.7] — 2026-03-30¶
Fixed¶
expand_dataframeTypeError on NaN fields (e.g.eventsSeries).
[0.6.6] — 2026-03-30¶
Changed¶
- Replaced
pd.json_normalizewith manual list-of-dicts construction inexpand_dataframe— 2.8x faster, eliminatesPerformanceWarning: DataFrame is highly fragmented, and correctly preserves nested dicts for cascading expansion (fixesexpand_seriessilently not working).
[0.6.5] — 2026-03-30¶
Added¶
expand_outcomes=Falseflag onget_markets,get_events, and their_allvariants — explodesoutcomes,outcomePrices, andclobTokenIdsas parallel lists into one row per outcome. Takes precedence overexpand_clob_token_ids.feeScheduledict flattening — nested dict columns are automatically expanded into prefixed scalar columns (e.g.feeScheduleMaker,feeScheduleTaker). Configurable viadict_columnson the client.outcomePricesalways coerced tolist[float]— even withoutexpand_outcomes, list values are floats instead of strings.umaBond/umaRewardadded to numeric columns — auto-coerced from strings.
[0.6.4] — 2026-03-30¶
Added¶
- 11 new
_allauto-pagination methods —get_series_all,get_teams_all,get_comments_all,get_comments_by_user_address_all,get_positions_all,get_closed_positions_all,get_market_positions_all,get_trades_all,get_user_activity_all,get_leaderboard_all,get_builder_leaderboard_all. All available on bothPolymarketPandasandAsyncPolymarketPandas. - Explicit parameter signatures on all 22
_allmethods — mirrors base method parameters (minusoffset/next_cursor) for full IDE autocomplete and type checking. No more**kwargs.
Fixed¶
_autopagenow works correctly withexpand_*flags — pagination uses pre-expansion API record count (df.attrs["_raw_count"]) so offset tracking isn't inflated byexpand_dataframeorexplode.- Fixed
_autopageinfinite loop whenuse_tqdm=False— the stop condition (len_pages) was only updated inside the progress bar branch. - Fixed
eventsSeriesKeyError inget_markets— not all records have a series after event expansion; now guarded with column existence check.
Changed¶
- Default
limitset to300across all Gamma endpoints (get_markets,get_events,get_series,get_teams,get_comments,get_comments_by_user_address). Was500orNone.
[0.6.3] — 2026-03-30¶
Fixed¶
- PyPI release for v0.6.4 changes (intermediate version).
[0.6.2] — 2026-03-28¶
Added¶
- MCP server expanded to 74 tools — near-complete coverage of the Polymarket API. Only CTF on-chain ops, relayer ops, and batch DataFrame-input methods excluded.
- New MCP tools:
cancel_orders_from_market,send_heartbeat,get_order_scoring,create_api_key,delete_api_key,get_event_by_id,get_tag_by_slug/id,get_related_tags,get_market_tags,get_event_tags,get_series_by_id,get_sports_market_types,get_comment_by_id,get_comments_by_user,get_server_time,get_fee_rate,get_market_price,get_positions_value,get_live_volume,get_traded_markets_count,get_builder_volume,get_rewards_market,get_rewards_earnings,get_rewards_earnings_total,get_rewards_percentages,get_rewards_user_markets.
[0.6.1] — 2026-03-28¶
Added¶
- MCP server expanded to 47 tools — all SDK endpoints now exposed with every
API parameter. LLM controls output size via
max_rows. - 6 write tools:
build_order,place_order,cancel_order,cancel_orders,cancel_all_orders,derive_api_key. POLYMARKET_MCP_MAX_ROWSenv var for default table output size (default 200).- Each tool's
max_rowsparam overrides per-call (0=unlimited).
[0.6.0] — 2026-03-28¶
Added¶
- MCP server (FastMCP) — query Polymarket data from any MCP client (Claude Code,
Claude Desktop, etc.) with 22 read-only tools.
pip install polymarket-pandas[mcp]thenpolymarket-mcp. - Tags explorer page with all
get_tagsparameters. - All endpoint parameters exposed as interactive sidebar controls in explorer.
Fixed¶
- Added
umaResolutionStatusesto JSON columns for proper parsing. - Fixed
json_normalizePerformanceWarning with.copy()defragmentation.
[0.5.0] — 2026-03-28¶
Added¶
- Streamlit Explorer Dashboard — interactive dashboard for exploring all public
Polymarket endpoints with Plotly visualizations. 10 pages: Markets, Events, Series,
Orderbook, Prices, Positions, Trades, Leaderboard, Rewards, Bridge.
pip install polymarket-pandas[explorer]thenpolymarket-explore.
[0.4.1] — 2026-03-27¶
Fixed¶
- Fix pandera FutureWarning: use
pandera.pandassubmodule instead of deprecated top-level import.
[0.4.0] — 2026-03-27¶
Added¶
- 12 TypedDicts for dict-returning endpoints — IDE autocomplete for all keys.
- 11 specific CursorPage types (e.g.
OrdersCursorPage,UserTradesCursorPage) withdata: DataFrame[Schema]. - 22 pandera DataFrameModel schemas — field names verified against official
Polymarket OpenAPI specs,
strict=False,coerce=True. build_order(expiration=...)now acceptspd.Timestamp, ISO-8601 strings, ordatetimein addition toint.get_user_trades_all()andget_active_orders_all()— auto-paginate cursor methods.to_unix_timestamp()helper inutils.py.
Fixed¶
get_active_orders/get_user_trades— was wrapping pagination envelope into DataFrame columns. Now returns properOrdersCursorPage/UserTradesCursorPage.
Breaking¶
get_active_orders()andget_user_trades()now return cursor-paginated dicts instead of DataFrames. Access the DataFrame viaresult["data"].
[0.3.1] — 2026-03-26¶
Fixed¶
- Fix
AsyncPolymarketPandasmissingget_tick_size,get_neg_risk,get_fee_rateandpreprocess_dictmethods. Async wrapper generator now usescallable()to detect all public methods includingcachetools.cachedmethoddescriptors (102 methods, up from 98).
[0.3.0] — 2026-03-26¶
Added¶
AsyncPolymarketPandas— async version of the HTTP client using composition +ThreadPoolExecutor. All 98 public methods auto-generated asasync defwrappers. Supportsasync withcontext manager.AsyncPolymarketWebSocket— native async WebSocket client usingwebsocketslibrary. Supportsasync for event_type, payload in session:iteration, auto-reconnection with exponential backoff, and asyncsubscribe()/unsubscribe().amount_usdcparameter onsplit_position()andmerge_positions()— convenience alternative to raw base-unitamount(e.g.amount_usdc=1.0instead ofamount=1_000_000).- Auto-set credentials —
derive_api_key()andcreate_api_key()now automatically set_api_key,_api_secret,_api_passphraseon the client. preprocess_dict()— full type coercion (numeric, datetime, bool, JSON) for single-dict responses. Applied toget_market_by_id()andget_market_by_slug()so JSON-string fields likeclobTokenIdsare automatically parsed to Python lists.websockets>=13.0added to core dependencies.pytest-asyncioadded to dev dependencies.- 16 new async unit tests (
tests/test_async_unit.py).
[0.2.0] — 2026-03-26¶
Added¶
- CTFMixin — on-chain merge, split, redeem positions via Polymarket's
Conditional Token Framework contracts on Polygon. Requires optional
web3dependency:pip install polymarket-pandas[ctf]. - Order signing —
build_order()with full EIP-712 signing, tick-size-aware amount calculation, and automatic market parameter resolution. submit_order/submit_orders— high-level convenience methods that auto-fetchneg_risk,tick_size,fee_rate_bpsfrom the CLOB API (cached).submit_ordersaccepts a pandas DataFrame and batch-submits via the/ordersendpoint (groups of 15).instance_cachedecorator (utils.py) backed bycachetools— per-instance method caching with optional TTL. Used forget_tick_size(300s TTL),get_neg_risk, andget_fee_rate(permanent)._ENV_DEFAULTSdict — env var resolution deferred to__post_init__, soload_dotenv()can run before client construction.- Auto-derive
addressfromprivate_keywhen not explicitly set. proxy_url,rpc_url,timeoutfields on the client dataclass.- Column default tuples extracted to
utils.pyconstants (DEFAULT_NUMERIC_COLUMNS, etc.). LICENSEfile (Apache-2.0).CONTRIBUTING.mdwith development setup and PR guidelines.- PyPI publish workflow (
.github/workflows/release.yml) — triggered on GitHub release, uses trusted publisher (OIDC). - Custom exception hierarchy:
PolymarketError,PolymarketAPIError,PolymarketAuthError,PolymarketRateLimitError— all exported from the top-level package. - HTTP error mapping in
_handle_response: 401/403 →PolymarketAuthError, 429 →PolymarketRateLimitError, other non-2xx →PolymarketAPIError. - Auth guards
_require_l2_auth/_require_builder_authraisePolymarketAuthErrorwith a descriptive message before any network call is attempted. close(),__enter__,__exit__onPolymarketPandasfor proper connection-pool cleanup and context-manager support.py.typedmarker (PEP 561) — downstream type checkers now see the package's annotations.expand_column_listsutility inutils.py;"series"removed from prefix list (was generating unused column variants).- Relayer API endpoints:
check_safe_deployed,get_relayer_transaction,get_relayer_nonce,get_relayer_transactions,get_relay_payload,submit_transaction,get_relayer_api_keys. - Bridge API endpoints:
create_deposit_address,create_withdrawal_address,get_bridge_quote,get_bridge_supported_assets,get_bridge_transaction_status. - CLOB endpoints:
get_sampling_markets,get_simplified_markets,get_sampling_simplified_markets(cursor-paginated), plus_allvariants. get_builder_trades(CLOB, builder auth).get_rebates(CLOB, public).- Cursor-based auto-pager
_autopage_cursorand*_allhelpers for the three new cursor-paginated endpoints. PolymarketWebSocketwith channels:market_channel,user_channel,sports_channel,rtds_channel.PolymarketWebSocket.from_clientclass method to share column config with an existing HTTP client.- Unit test suite (
tests/test_unit.py) with 75+ tests, usingpytest-httpxfor HTTP mocking — no live API calls required. - CI workflow (
.github/workflows/ci.yml): lint, typecheck, unit tests. [tool.ruff],[tool.mypy],[tool.pytest.ini_options]inpyproject.toml.- Dev optional dependencies:
pytest,pytest-httpx,ruff,mypy,pandas-stubs. - PyPI classifiers and keywords.
Fixed¶
_round_normalnow usesDecimalwithROUND_HALF_UPto avoid float representation bugs (e.g.round(0.85 * 10) = 8instead of 9).cancel_orders_from_marketnow sends params as JSON body (was query string, causing "Invalid order payload" errors).- CTF
build_transactioncalls now passfromaddress (was zero-address, causing "approve from the zero address" reverts). - POA middleware injected for Polygon compatibility in CTF operations.
- EIP-1559 / legacy gas field conflict resolved in
_send_ctf_tx. filter_params(None)now returns{}instead ofNone, preventing a silentTypeErrorin callers.filter_paramsno longer callspd.notnullon list values (previously raisedValueError: The truth value of an empty array is ambiguousfor empty lists).OrderSchemaside validation aligned to uppercase"BUY"/"SELL"to matchbuild_orderoutput.
Removed¶
load_dotenv()at module import time — this was silently mutatingos.environfor any application that imported the library. Callers who relied on.envloading should callload_dotenv()themselves before constructing a client.- Overly tight upper-bound version pins on
eth-accountandhttpx.
[0.1.0] — Initial release¶
Added¶
PolymarketPandasHTTP client wrapping the full Gamma, Data, and CLOB REST APIs with automatic DataFrame output and type coercion.- Gamma API: markets, events, tags, series, sports, comments, search, profiles.
- Data API: positions, closed positions, market positions, top holders, positions value, leaderboard, trades, user activity, accounting snapshot, live volume, open interest, traded markets count, builder leaderboard, builder volume.
- CLOB public API: order book, prices, midpoints, spreads, last trade prices, fee rate, tick size, price history, server time.
- CLOB private API (L2 HMAC auth): user trades, orders (get/place/cancel), order scoring, heartbeat.
- CLOB auth management (L1 EIP-712): create/derive/get/delete API keys.
- Auto-pagination helpers
get_markets_all,get_events_all,get_tags_all. preprocess_dataframepipeline: snake → camelCase column rename, numeric / datetime / bool / JSON-string coercion, drop oficon/imagecolumns.