# py-clob-client vs polymarket-client vs PMXT vs CCXT: which Python client to write against Polymarket

One archived, one official, two multi-venue abstractions. Which to write against, what the abstraction removes, and where each one keeps your signing key.

*https://predictionmarkets.tools/compare/polymarket-python-clients*

- https://predictionmarkets.tools/tools/py-clob-client.md
- https://predictionmarkets.tools/tools/polymarket-client.md
- https://predictionmarkets.tools/tools/pmxt.md
- https://predictionmarkets.tools/tools/ccxt.md

## Four answers to a question that only looks like one question

"How do I trade Polymarket from Python" has four packages behind it, and they are not four versions
of the same thing. One is archived and its publisher says it does not work. One is the vendor's own
current SDK. Two are unified clients that reach this venue alongside six or fourteen others, and
they charge for that reach in a currency the cards state plainly and nobody budgets for: the
abstraction removes the differences that make these venues worth comparing in the first place.

The grid above has the licences, the prices and the release rhythms. What follows is the three
things that decide the choice and are on none of the four cards alone.

## One of them is dead, and the place you install it from does not say so

[py-clob-client](https://predictionmarkets.tools/tools/py-clob-client) is archived. Its README opens with a warning that the client
is no longer functional and should not be used for new or existing integrations, and names the
replacement. That is the vendor's own statement about the vendor's own package.

Two details make it worse than an ordinary deprecation. The last release is v0.34.6 on 2026-02-19
while the last commit on `main` is 2026-05-25 — three months of work landed after the last artifact
was cut, so even a reader who decides to fork and patch is reading source that was never shipped.
And the warning lives on the repository, not on the package index: `pip install py-clob-client`
succeeds today with nothing to tell you. The failure mode is not that the reader is warned and
proceeds. It is that the reader never sees the warning, because the one surface they touch is the
one that carries none.

It also never did two things a first integration needs. It shipped no WebSocket module, so books
were polled. And it never set the on-chain allowances — the ERC-20 and conditional-token approvals
for three separate exchange contracts had to be sent from outside the library, which its own card
records as the most common first failure for new users. Those approvals outlive the process that
made them, which matters to the next section.

## Where the key lives, and whether it can be narrowed

This is the criterion, not a footnote. Every one of these four can move funds, and they answer
"where does the signing key sit" four different ways.

[polymarket-client](https://predictionmarkets.tools/tools/polymarket-client) is the only one that answers "can it be narrowed" with
yes. Its read path has no credentials in it at all — `PublicClient` and `AsyncPublicClient` are
separate classes, so a notebook pulling prices never touches key material and cannot be made to.
`SecureClient` takes a local private key, derives the Level 2 credentials during construction,
classifies the wallet type and picks the signature type from that. It ships scoped, revocable
session keys, and it brings the approval step inside the library — `approve_erc20`,
`approve_erc1155_for_all` and `get_trading_approvals_state` are methods now, where the predecessor
had a link to a gist. The blanket approval you set by hand and forget is the thing session keys
exist to replace.

[CCXT](https://predictionmarkets.tools/tools/ccxt) signs locally with venue-native credentials and narrows by capability rather
than by key: its MCP server keeps keys on the machine and puts trading, withdrawals and raw
endpoints behind opt-in tiers that are off by default. That is a real answer for an agent setup,
and it is not the same as a revocable key.

[PMXT](https://predictionmarkets.tools/tools/pmxt) is the one to read carefully. Its quickstart — the default path — puts a PMXT
API key and your private key in the same constructor. The vendor's documentation says its server
never sees the private key and does not set out where signing happens instead. For a key that can
move funds, "the documentation says so" is the weakest form of that assurance, and the card says as
much. The self-hosted mode is the answer: install `pmxt-core`, construct a venue client with no
PMXT key, and the SDK talks to venues directly with your own credentials. Note that the same switch
also decides what you can trade — hosted writes cover three venues, and Kalshi writes need
self-hosting either way. One flag, two unrelated consequences.

And in that self-hosted mode the credentials stop being one thing: a Polygon private key plus an
optional proxy address and a signature type for Polymarket, an API key plus an RSA private key for
Kalshi, an API key plus an EIP-712 signing key for Limitless. Three different kinds of secret
behind one constructor is the abstraction leaking at precisely the point where a leak costs money.

## What the unified model charges you

Both multi-venue clients flatten the same three levels — an event, a market hanging off it, and an
outcome as the tradeable unit. CCXT's prices are probabilities between 0 and 1, `amount` is a number
of shares and `cost` is the collateral spent. PMXT's card puts the cost of that in one sentence: a
venue that does not fit the hierarchy fits it anyway.

What gets flattened is not incidental. It is the short list of things that make the venues in this
catalogue different from each other:

**Who resolves.** Nothing in `fetchOrderBook` says whether the outcome is decided by a token-holder
vote on an oracle, by a regulated exchange against a named source, by an automated price feed, or
by a team by hand some days after the deadline — and on [Limitless](https://predictionmarkets.tools/tools/limitless-api) a market
the rules cannot be applied to is refunded at the amount staked rather than at the dollar a winning
share would have paid. That is a different failure mode from a disputed oracle vote, and neither
one has a field in a unified position object.

**How the price is made.** CCXT's own card notes that most of the venues it reaches run an order
book but Myriad is priced against a curve, and that `fetchTradeQuote` exists precisely because an
executable quote on an automated market maker is not the same object as a book. The unified call
returns both under one name. On a curve the number that decides the trade is slippage, not the fee,
so a fee comparison across a unified client compares the smaller half.

**Who may trade at all.** CCXT's card states it exactly: the library will happily construct an
authenticated client for an exchange that will not serve you. Limitless declines US order placement;
Kalshi and the US Polymarket exchange want a verified account first. The abstraction has no place to
put that, so you find out at the order.

**Settlement.** Both multi-venue cards carry a single settlement value that is the majority case
among the venues reached rather than a property of the library — five of CCXT's seven settle in
stablecoin on-chain while Kalshi settles in dollars. A field that is true of most of what a library
touches is a field that is wrong about the rest of it.

There is a fourth cost that is plainer. Coverage inside the abstraction is not uniform, so
`exchange.has[methodName]` is required reading rather than optional: Kalshi carries `editOrder` and
`fetchSettlements` and Polymarket does not; Polymarket carries batch `createOrders`,
`fetchOrderTrades` and `fetchTradingFee` and Kalshi does not; Limitless declares `fetchBalance`
false; Binance's prediction class has no candles. Live streaming exists for three of the seven.
Calling `fetchTickers()` with no arguments raises on six of them, and the documentation names four.
One interface over seven venues is one interface over seven different subsets.

## What "maintained" means on each of these, in the same units

Release feeds and commit feeds answer different questions, and on these four they disagree in
instructive ways.

CCXT ships about weekly — 39 releases in the six months to 2026-09-19. Its two language packages are
not in step: PyPI was on 4.5.81 on 2026-09-19 while npm was still on 4.5.78 from 2026-09-07, which
matters if a Python research process and a TypeScript executor are meant to agree about a venue.
Its documentation lags its code in both directions at once — the prediction page names five venues
where the repository lists seven, and the machine-readable list says no prediction class has
WebSocket support while three of them do.

polymarket-client is four months old: 34 releases since 2026-05-21, last commit 2026-09-18, twelve
open issues and eleven open pull requests. That is an actively developed project rather than a
settled one, and 0.10.0 on 2026-09-10 was a breaking minor that moved data reads onto a new
contract. Pin the exact version and read the release notes; that is the trade for the predecessor
being dead.

PMXT shipped 322 releases between 2026-01-03 and 2026-07-18 and then stopped, with the last commit
on the same day. It is not archived and the tracker is open — but the tracker holds 1,236 open
issues against a repository eight months old, which means it cannot tell you whether your problem is
known. For a library whose entire job is tracking fifteen moving APIs, two months of silence is the
most important fact about it.

py-clob-client stopped releasing in February and stopped committing in May, and is archived.

## The recommendation

**Writing against Polymarket's international platform and nothing else: polymarket-client.** It is
better than the archived predecessor on every axis, and better than both multi-venue clients on
everything except reach — it has the discovery calls the predecessor lacked, synchronous forms the
CCXT prediction namespace does not offer at all, the approvals in the library, and the only scoped
key of the four. Pin the version, keep reads on `PublicClient`, require Python 3.11, and budget for
the one thing it cannot give you: there is no testnet or paper target, so the first order you place
is real. If your interpreter is pinned below 3.11, that move comes first.

**Already running py-clob-client in production: migrate, and read the guide with one eye open.** The
vendor's migration guide maps the interim `py-clob-client-v2` onto the new client, so a reader
coming from the original is reading instructions written one generation after their code.

**Kalshi and Polymarket in one process: CCXT, and check `has` before every call.** It is free,
MIT-licensed, actually maintained, and the only client here that reaches both. Accept that the
prediction namespace is async-only in Python, that live streaming covers three of its seven venues,
and that you are reading somebody else's translation of each exchange. But if the second venue is
there to be *compared* with the first rather than traded alongside it, write the fan-out yourself
over the two official SDKs — [kalshi-python-sync](https://predictionmarkets.tools/tools/kalshi-python-sync) and polymarket-client —
because resolution, jurisdiction and the pricing mechanism are what you are comparing and are
exactly what the unified model removes.

**PMXT: only for a venue nobody else reaches, only self-hosted, and only after checking the feeds.**
It lists fifteen venues, which is wider than anything else here, and that is the single axis on
which it wins. Against it: the July pause, the tracker, hosted writes that cover three venues, and a
pricing page whose plans are all personal use only — a clause a team discovers after building on the
free tier.

**Reading prices rather than trading: none of these.** The venue's own HTTP APIs need no client
library at all — [polymarket-gamma-api](https://predictionmarkets.tools/tools/polymarket-gamma-api) for discovery,
[polymarket-clob-api](https://predictionmarkets.tools/tools/polymarket-clob-api) for books and prices — and neither asks you to
carry a signing stack to read a number.

## FAQ

### Which Python package is the right one to start a new Polymarket integration with?

polymarket-client, which is Polymarket's own unified SDK and the migration target the archived predecessor names in its README. Start on PublicClient, which needs no credentials at all, and pin the exact version — it is on the 0.x line and its own README says minor releases may break.

### Can I still use py-clob-client if I do not need anything new?

Polymarket says no. The repository is archived and the README says the client is no longer functional and should not be used for new or existing integrations. The install channel carries no such warning, so pip succeeds and tells you nothing.

### Do I need CCXT or PMXT to reach more than one venue?

Only if you want one vocabulary over all of them. Two official SDKs plus a hundred lines of your own mapping is more code and no translation in the middle — and if the reason for the second venue is to compare it with the first, the differences you are comparing are exactly what a unified model flattens.

### Which of these four keeps my private key furthest from anyone else?

polymarket-client and CCXT both sign locally with a key you hold, and polymarket-client is the only one of the four that can narrow it — it ships scoped, revocable session keys. PMXT's hosted quickstart puts its own API key and your private key in one constructor; its self-hosted mode is the one where venue credentials stay on your machine.

### Does any of these reach Polymarket US?

Not usefully. polymarket-client exports one environment and every host in it is a polymarket.com host; CCXT's prediction namespace does not list the US exchange. PMXT lists it among fifteen venues, but its hosted write path covers three venues and the US exchange is not one of them. The US exchange has its own SDK.
