Skip to main content
From a fresh pmxt_api_key to a confirmed position on Polymarket in under a minute. For the full hosted model, see Hosted trading.
Hosted writes today: Polymarket, Opinion, and Limitless. Other venues are read-only via the hosted catalog; use self-hosted for venue-native trading where the venue exposes writes. Check Feature Support & Compliance for per-venue support.

1. Get an API key

Go to pmxt.dev/dashboard, create a key, and copy it. It looks like pmxt_live_... and works immediately.

2. Install the SDK

3. Construct a hosted client

A hosted trading client takes three things: your PMXT API key, the wallet address you’ll trade from, and the private key for that wallet (used only to sign EIP-712 messages locally — it is never sent to PMXT). The SDK auto-wraps private_key into an EthAccountSigner / EthersSigner for you.
PMXT is non-custodial by construction: the SDK signs locally and your key never leaves your machine. For production, a practical habit is to keep only the float you’re actively trading in this wallet. See Security.

4. Approve and deposit USDC into escrow

Hosted trades execute against your balance in the non-custodial PreFundedEscrow contract. The first time you trade, you need to approve the escrow to pull USDC from your wallet and make an initial deposit. The fastest way is the dashboard. Open pmxt.dev/dashboard, connect the wallet that matches 0xYourWallet, and use the Deposit flow. Your wallet (MetaMask, Rabby, WalletConnect, etc.) prompts you to sign each transaction — PMXT never sees your private key.
  1. Go to pmxt.dev/dashboard and connect the same wallet address you passed to the SDK.
  2. Click Deposit and enter the USDC amount.
  3. Approve the USDC allowance in your wallet (one-time per token).
  4. Confirm the deposit transaction in your wallet.
Approval and deposit are one-time setup. Subsequent trades just spend from escrow until you withdraw. See Escrow Lifecycle for the full deposit / withdraw flow.
If you’re scripting deposits (CI, treasury automation, custom wallet integrations), client.escrow builds unsigned transactions you sign and broadcast with your own wallet library (web3, ethers, viem, etc.).

5. Find a market and place your first order

client.fetch_markets queries the venue’s live catalog and returns markets you can trade directly. Pass any returned outcome straight to create_order — no UUID lookup required.
The hosted trading API accepts either the venue-native identifier (returned by client.fetch_markets) or a catalog UUID (returned by Router) — whichever you have. The SDK picks the right wire field automatically. See Catalog UUID vs Venue ID when cross-venue identity matters.
outcome= requires a MarketOutcome instance, not a bare dict — passing a raw dict raises AttributeError. Use the object you got from client.fetch_markets()[i].outcomes[j] (or router.fetch_markets()[i].outcomes[j]) as shown above. If you only have string ids, pass them explicitly instead: client.create_order(market_id="...", outcome_id="...", side="buy", ...).
What PMXT abstracts vs what leaks through from the venue. PMXT unifies the order shape across venues, but a few Polymarket rules pass through as-is. Polymarket enforces two independent minimums on marketable BUY orders — a 5-share minimum AND a **1notionalminimumandthehigherofthetwobinds.At1 notional minimum** — and the higher of the two binds. At 0.138/share the 5-share rule alone would only require 0.69,butthe0.69, but the 1 rule raises the effective minimum to 8 shares (1.10);a5sharebuyatthatpriceisrejectedbythevenuewithinvalidamountforamarketableBUYorder(1.10); a 5-share buy at that price is rejected by the venue with `invalid amount for a marketable BUY order (0.69), min size: 1and PMXT surfaces it asOrderSizeTooSmall. Market orders are **budget-capped** (a buy spends exactly amountUSDC, a sell sells exactlyamountshares —slippage_pctis ignored). Hosted **limit** orders are supported viaclient.create_order(order_type=“limit”, price=…, amount=…)and the same 5-share and $1 marketable-BUY minimums apply; limit BUY and SELL are supported, and both usedenom=“shares”` in hosted SDK requests.

6. Verify the fill

Hosted positions appear immediately on fetch_positions. The position’s size is your share count; the remaining USDC sits in fetch_balance.
The id returned by hosted create_order is a PMXT internal task id, not a Polymarket (or other venue) order id. Calling Polymarket’s own order-lookup with it will return nothing. Use client.fetch_order(id) — the hosted SDK knows how to resolve the task and reports the live status (queued, fulfilling, fulfilled, failed, no_fill). A fresh create_order returns status="queued" because the venue submit happens asynchronously; poll fetch_order (or pass wait=true) to get the venue-confirmed outcome.
That’s it — you placed a real trade through hosted PMXT. From here:
  • Escrow lifecycle — deposits, withdrawals, the request/claim timelock.
  • Hosted errors — what each error means and how to recover.
  • Signing — the EIP-712 protocol underneath create_order.
  • Self-hosted — when to skip hosted and run pmxt-core yourself.