pmxt.Polymarket(pmxt_api_key=...) does when an API key is set. Self-hosted is the advanced escape hatch — you run pmxt-core on your own machine and the SDK talks to localhost. Both expose the same SDK surface; the difference is where execution happens and who holds keys.
At a glance
Hosted (pmxt_api_key set) | Self-hosted (no API key) | |
|---|---|---|
| Install footprint | pip install pmxt / npm i pmxtjs | SDK + pmxt-core local server |
| Who holds the API key? | You (backend secret) | Not used |
| Who holds venue credentials? | PMXT escrow contract (USDC custody only) | You, on your machine |
| Trading auth (writes) | Your EIP-712 signature, signed locally | Raw venue credential (private key, Kalshi RSA, etc.) |
| Reads | trade.pmxt.dev/v0/user/... | Direct to the venue API |
| Writes | trade.pmxt.dev/v0/trade/{build,submit}-order | Direct to the venue API |
| Custody | USDC in PMXT PreFundedEscrow | You retain venue-native custody |
| Latency | ~150–300ms round-trip | Limited by venue + your network |
| Trading venues | Polymarket, Opinion | Every venue PMXT supports |
| Read-only venues | All catalog venues via Router | All catalog venues via Router |
| Infra to run | None | One local process |
| Regulatory custody | PMXT escrow as counterparty | You as direct counterparty to the venue |
When hosted is the right choice
- You’re building a web or mobile app and want to keep
pmxt_api_keyserver-side while end users keep their private keys client-side. - You want one HTTP surface across Polymarket and Opinion without learning each venue’s order schema.
- You want PreFundedEscrow custody instead of managing venue-native accounts.
- You don’t want to operate the pmxt-core process, manage upgrades, or run a sidecar.
When self-hosted is the right choice
- You need sub-100ms latency — colocated arbitrage, market-making, latency-sensitive HFT-style strategies.
- You prefer raw venue credentials — Polymarket L2 API keys, Kalshi RSA keys, Smarkets sessions — and don’t want PMXT in the custody path.
- You have regulatory custody requirements that mandate direct counterparty status with the venue.
- You want to trade on venues not yet supported by hosted (Kalshi, Limitless, Smarkets, Probable, Myriad, etc.).
- You’re an OSS contributor developing or debugging pmxt-core itself.
What’s identical either way
The SDK surface is the same. Code written against hosted will run against self-hosted with no changes except dropping thepmxt_api_key argument:
fetch_markets, fetch_order_book, create_order, fetch_positions — same signatures, same response shapes.
What differs subtly
fetch_balance: hosted returns escrow USDC; self-hosted returns the venue-native balance (e.g. Polymarket’s CLOB-proxy USDC). Same shape, different source. See the migration guide for the implications.Positionfields: hosted may surfaceNone/undefinedonentry_price,current_price,unrealized_pnl,outcome_labelwhen the server doesn’t yet have the data. Self-hosted always populates them.- Catalog UUIDs vs venue IDs: hosted-mode
create_orderrequires catalog UUIDs (market_id,outcome_id). Self-hosted accepts the venue-native ID directly. See Catalog UUID vs venue ID. - Error classes: hosted produces
HostedTradingErrorsubclasses with semantic parents (InsufficientEscrowBalanceis alsoInsufficientFunds). Self-hosted produces the parent classes directly. Catch the parent and you handle both paths. See Hosted errors.

