CCXT

CCXT vs PMXT

PMXT and CCXT both unify prediction-market venues. They differ on venue count, hosted service versus plain library, custody and signing, and language coverage.

PMXT describes itself on GitHub as "CCXT for prediction markets. PMXT is a unified API for trading on Polymarket, Kalshi, and more." CCXT ships prediction-market support of its own in the ccxt.prediction namespace, so the two genuinely overlap.

The question that decides between them is not which normalises Polymarket better. It is whether you want a hosted service in the path of your trading, and how much of the rest of the market you also need to reach.

TL;DR

  • Pick PMXT if prediction markets are the whole job and you want the widest venue list — its compliance matrix names 15 venues against CCXT's 7 — plus a hosted catalog that searches and matches the same question across venues.
  • Pick CCXT if you want a library with nothing between you and the venue: 7 prediction venues and 104 spot/derivatives exchanges behind one interface, in 8 languages, with keys that never leave your process.
  • The overlap is smaller than the tagline suggests. PMXT's default mode is a metered hosted API with a free tier and paid plans; CCXT has no service, no API key of its own and no meter. PMXT can also be self-hosted, which narrows the gap considerably.

At a glance

CCXTPMXT
Prediction venues7 — Polymarket, Kalshi, Limitless, Myriad, Opinion, plus Binance and Hyperliquid prediction products15 listed in core/COMPLIANCE.md
Crypto spot / derivatives exchanges104, same unified APInone
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java, RustTypeScript (pmxtjs), Python (pmxt)
Default network pathyour process → the venueyour process → PMXT's hosted API → the venue
Self-hosted optionit is the only modeyes — pmxt-core, no API key, requests go direct to venues
Service API key requirednoyes for hosted mode (pmxt_api_key); no for self-hosted
Meteringnonecredits — "1 REST call = 1 credit. 1 WebSocket message = 0.1 credits."
Order signingin-process, always (EIP-712 for Polymarket, RSA for Kalshi)self-hosted: your keys locally. Hosted: "end-to-end hosted trading with PreFundedEscrow custody"
WebSocketswatch* on 3 of the 7 prediction venueshosted plans cap concurrent streams (5 / 20 / 100 by tier)
Raw endpoint accessyes — 128 Polymarket and 74 Kalshi endpoints as implicit methodsnot documented as a unified feature
Cross-venue market matchingnoyes — shared catalog, fetch_matched_market_clusters
Costfreefree tier (25,000 credits/month), then $29.99 and $99.99/month
LicenceMITMIT
Popularity43.8k GitHub stars · 4.7M PyPI + 494k npm installs/month (one package, every venue)2.1k GitHub stars · 8.6k PyPI (pmxt) + 9.9k npm (pmxtjs) installs/month

Figures verified September 2026 against CCXT v4.5.77, the pmxt-dev/pmxt repository (2,114 stars, 262 forks, MIT, not archived, last commit 18 July 2026), pmxt.dev's docs and pricing pages, and install counts from npm and PyPI.

The same job, written both ways

Find a market and read its order book

import ccxt from 'ccxt';

const exchange = new ccxt.prediction.polymarket ();

const events = await exchange.fetchEvents ({ 'query': 'election', 'limit': 5 });
const outcome = events[0].markets[0].outcomes[0].outcome;  // a "MARKET:LABEL" handle

const book = await exchange.fetchOrderBook (outcome);
console.log ('best bid:', book.bids[0]);

Two things differ. CCXT starts from fetchEvents and addresses the tradeable unit with a portable outcome handle; PMXT's data methods take an outcomeId, which its API reference documents as venue-native — a CLOB token id on Polymarket, a market ticker on Kalshi. And the CCXT client is talking to gamma-api.polymarket.com and clob.polymarket.com directly, with no key at all for public data.

Read your balance and positions

import asyncio
import ccxt.prediction

async def main():
    exchange = ccxt.prediction.polymarket({
        'privateKey': '0x...',     # EOA key — derives the L2 creds and signs orders in-process
        'walletAddress': '0x...',  # your Polymarket account (proxy) wallet
    })
    balance = await exchange.fetch_balance()
    positions = await exchange.fetch_positions()
    print(balance['USDC']['total'], len(positions))
    await exchange.close(True)

asyncio.run(main())

The PMXT snippet is shorter because the hosted API resolves the wallet for you. The CCXT snippet is longer because it holds the key that signs. Which of those you prefer is the real decision on this page.

Where the differences actually bite

Prediction markets are not the only market

This is the largest difference and it does not show up in a feature table. CCXT's prediction classes extend PredictionExchange, which extends the same base as the 104 crypto exchanges. fetch_order_book, create_order, cancel_order, fetch_positions, watch_order_book have the same names and the same return structures on ccxt.prediction.polymarket as on ccxt.binance.

If your strategy hedges a Kalshi position on a Binance perpetual, or prices a Polymarket outcome against an implied vol you pull from Deribit, that is one dependency and one data model in CCXT. PMXT covers prediction venues only, so a mixed book means two libraries and two sets of structures.

Venue coverage runs the other way inside prediction markets

Be honest about the direction: PMXT's compliance matrix lists Polymarket, Polymarket US, Kalshi, Limitless, Probable, Baozi, Myriad, Opinion, Metaculus, Smarkets, Hyperliquid, Gemini Titan, SuiBets, Rain and Hunch — 15 venues. CCXT ships 7. If your target venue is Smarkets, Metaculus, Probable or Rain, CCXT does not have it today and PMXT does.

Hosted service versus library

PMXT's own documentation splits this cleanly. Hosted mode is the default: "PMXT's hosts give you a shared catalog, cross-venue search, and end-to-end hosted trading with PreFundedEscrow custody." Self-hosted mode is described as "No API key, no external dependency. Your requests go directly to the venues," installed as pmxt-core and spawned locally by the SDK.

CCXT only has the second shape. There is no CCXT service, so there is no key to rotate, no credit balance to top up, no rate tier, and no third party whose availability your order entry depends on. The published PMXT plans meter REST calls at one credit each and WebSocket messages at 0.1 credits, with 25,000 credits and five concurrent streams on the free tier. A book-watching bot on a busy market can move through that budget quickly, which is a sizing question you never have with a plain library.

Custody and signing

On CCXT the private key stays in the process. ccxt.prediction.polymarket takes a privateKey, derives the Polymarket L2 credentials from it and signs each order with EIP-712 locally; ccxt.prediction.kalshi RSA-signs each request with a PEM key you supply. Nothing is forwarded to a third party, because there is no third party.

PMXT's self-hosted mode is described the same way — venue-native credentials, used locally. Its hosted trading path is described differently, as "end-to-end hosted trading with PreFundedEscrow custody". Whether pre-funded escrow is acceptable is a risk decision, not an engineering one, and it is worth making deliberately rather than by accepting the default constructor.

Eight languages

CCXT is written once in TypeScript and transpiled to JavaScript, Python, PHP, C#/.NET, Go, Java and Rust, with the same method names and return structures in each. The prediction classes come along: ccxt.prediction.polymarket() in Python, new ccxt.prediction.polymarket() in C#, ccxtprediction.NewPolymarket() in Go. PMXT publishes TypeScript and Python clients.

Nothing is hidden

Every endpoint in each prediction venue's API is generated as a callable implicit method with signing, rate limiting and error mapping applied — 128 for Polymarket, 74 for Kalshi, 58 for Limitless. Unified coverage never becomes a ceiling; if the venue exposes something CCXT has not modelled yet, you can still call it.

What PMXT does better

  • More prediction venues. 15 against 7. Metaculus, Smarkets, Probable, Baozi, SuiBets, Rain, Hunch, Gemini Titan and Polymarket US have no CCXT equivalent today. If one of those is your venue, the comparison ends there.
  • Cross-venue market matching. The hosted catalog matches the same underlying question across venues and exposes it through fetch_matched_market_clusters, with relation types and confidence scores. Deciding that a Kalshi contract and a Polymarket outcome are the same event is a genuinely hard problem, and CCXT does not attempt it — you would build that yourself.
  • A hosted catalog you do not have to run. Cross-venue search served from PMXT's infrastructure means no crawling, no normalising and no storage of your own, with a free tier at 25,000 credits per month to try it.
  • A documented migration path off the Dome API. The repository advertises a drop-in Dome API replacement with an automatic codemod, which is a concrete piece of work done for a specific set of users.

If prediction markets are the entire scope of your system, you want the widest venue list available, and cross-venue question matching is a feature you would otherwise have to build, PMXT is the better fit.

Migrating from PMXT to CCXT

On the six venues both cover — Polymarket, Kalshi, Limitless, Myriad, Opinion and Hyperliquid — the shapes map closely. The main change is that CCXT threads a single outcome handle through every method where PMXT passes marketId and outcomeId separately.

What you are doingPMXTCCXT
Construct a clientpmxt.Polymarket(pmxt_api_key=..., wallet_address=...)ccxt.prediction.polymarket({'privateKey': ..., 'walletAddress': ...}) — no service key
Discover marketsfetchMarkets({ query })fetch_events({'query': ..., 'limit': ...}), or fetch_markets() for a volume-ordered browse
Address the tradeable unitoutcomeId — venue-native (CLOB token id, Kalshi ticker)the outcome handle "MARKET:LABEL", or the venue's outcome id
Order bookfetchOrderBook(outcomeId)fetch_order_book(outcome, limit)
CandlesfetchOHLCV(outcomeId, params)fetch_ohlcv(outcome, timeframe, since, limit)
TradesfetchTrades(outcomeId, params)fetch_trades(outcome, since, limit)
New ordercreateOrder({ marketId, outcomeId, side, type, amount, price })create_order(outcome, type, side, amount, price)
Cancel ordercancelOrder(...) where the venue supports itcancel_order(id, outcome)
PositionsfetchPositions()fetch_positions(outcomes)
BalancefetchBalance()fetch_balance()
Streamshosted WebSocket streams, metered per messagewatch_order_book / watch_trades on Polymarket, Myriad and Opinion
Cross-venue question matchingfetch_matched_market_clusters()no equivalent — keep PMXT, or build it
A venue CCXT does not haveSmarkets, Metaculus, Probable, Baozi, Rain, Hunch, …no equivalent — keep PMXT for those
Anything not listedthe same endpoint as an implicit method (128 on Polymarket, 74 on Kalshi)

Nothing stops you running both: PMXT for the venues and the cross-venue catalog CCXT does not cover, CCXT for the six it does plus every crypto exchange you hedge on.

FAQ

Does CCXT support Polymarket and Kalshi? Yes. Both are in the ccxt.prediction namespace, alongside Limitless, Myriad, Opinion and the Binance and Hyperliquid prediction products — 7 venues as of v4.5.77. Public market data needs no credentials; trading takes a privateKey (and walletAddress for Polymarket and Hyperliquid). See the prediction markets guide.

Which covers more prediction markets, CCXT or PMXT? PMXT. Its compliance matrix lists 15 venues; CCXT ships 7. CCXT covers those 7 alongside 104 crypto spot and derivatives exchanges behind the same unified API, which is the trade the two are actually making.

Do I need an API key or a subscription to use CCXT for prediction markets? No. CCXT is an MIT-licensed library with no service behind it — you supply the venue's own credentials for trading and nothing else. PMXT's hosted mode uses a pmxt_api_key with a credit meter and a free tier; its self-hosted pmxt-core mode needs no key either.

Where does my private key go? With CCXT, nowhere. Orders are signed in your process — EIP-712 for Polymarket, RSA request signing for Kalshi — and only the signed payload reaches the venue. PMXT's self-hosted mode is described the same way; its hosted trading path is described as using PreFundedEscrow custody, which is a different trust model.

Can I stream prediction-market order books over WebSocket with CCXT? On 3 of the 7 venues — Polymarket, Myriad and Opinion — using watch_order_book, watch_trades and the other watch* methods directly on the ccxt.prediction.<id> client, keyed by the same outcome handle the fetch* methods take. The remaining four are REST-only in CCXT today.

Is CCXT's prediction support a separate package? No. It is the prediction namespace inside the same ccxt package, under the same MIT licence, with no paid tier.

Next steps

On this page