How to place a prediction market order from code

Five clients that actually submit orders, and the three things between a working script and a fill — the key, the wallet approvals and the eligibility check.

Pick the venue first, because there is no portable order. Kalshi has an official generated Python client and a better third-party one; Polymarket has its own SDK for the on-chain exchange and a separate one for the US exchange, which share nothing; Limitless publishes its own async client. The library is the easy part. The credential, the wallet approvals and whether you may place an order at all are the rest.

The short way

Pick the venue, then the client. There is no portable order here: Kalshi and Polymarket are unrelated systems with different identifiers, different price units, different signing schemes and different answers to who may place an order at all.

For Kalshi, the current official Python SDK is kalshi_python_sync or kalshi_python_async — not the older kalshi-python package, which Kalshi's own documentation marks as deprecated. For Polymarket's on-chain exchange, polymarket-client is the package Polymarket's documentation names, and the import is polymarket rather than the distribution name. For Polymarket US it is a different SDK entirely, against a different host, with a different credential.

The credential comes out of the environment, never out of the file:

# Kalshi: the API key id, plus the path to the RSA private key it was registered against.
export KALSHI_API_KEY_ID="..."

What the options are

Kalshi, official. Seventeen API modules covering markets, events, orders, order groups, portfolio, historical and live data, generated from the OpenAPI specification and released on a weekly cadence — thirty-one versions since December 2025. Authentication is an API key id plus an RSA private key, with RSA-PSS request signing. Two things to know before you plan around it: it requires Python 3.13 or newer, which rules out most production images in use today, and it ships no WebSocket at all, because the streaming half of the Kalshi API lives in a separate specification.

Kalshi, third-party. pykalshi is MIT and exists largely because of that gap: an OrderbookManager that applies the WebSocket deltas and hands back the current book, automatic retries, pandas output, typed exceptions, Python 3.9 and up, and five runtime dependencies a person can actually check. It reads KALSHI_API_KEY_ID and a path to your key file from the environment and signs in process. It is one person's library, it does not cover the whole API by its own admission, and it learns about an API change when something breaks.

Polymarket, on-chain. polymarket-client ships four clients, and the split is the useful part: PublicClient and AsyncPublicClient need no credentials at all, while SecureClient and AsyncSecureClient take a local private key and can trade. SecureClient.create() derives the Level 2 API credentials and the wallet address from the signer key, classifies the account as a plain EOA, a Polymarket proxy, a Gnosis Safe or a Deposit Wallet, and picks the signature type from that. Orders are EIP-712 typed data signed in your process; the package posts signatures rather than credentials.

Polymarket, US. polymarket-us-python is a thinner, different animal: httpx for transport, pynacl for Ed25519 signing, sync and async clients, and a credential that is an exchange API key id plus a base64-encoded Ed25519 secret. There is no wallet key and no on-chain signing, because the US exchange settles in dollars — which removes the whole class of approval failures below, and adds an identity check instead.

Limitless. limitless-sdk is async throughout, on aiohttp and python-socketio, with GTC, FAK and FOK orders on both the CLOB and NegRisk multi-outcome markets, signed locally with eth-account against a cached copy of the venue contract addresses. It is one of the few official venue clients here whose last release and last commit are the same day.

Where this breaks

The key is three different objects wearing one word. An RSA private key registered against a Kalshi account, used to sign each request. An Ed25519 secret issued from a developer page on a Polymarket US account. And, on the on-chain venues, a Polygon signing key which is the key that can move the collateral — there is no read-only version of it to hand over. Where your key lives when software trades for you is the page for that decision rather than a paragraph here. The practical rule from the cards: prefer a library that separates reading from trading the way polymarket-client does in its type system, and know which of the three you are handing over.

The wallet and its approvals are work, and they are where a first order actually fails. On Polymarket the allowance step used to be a linked gist; polymarket-client now carries approve_erc20, approve_erc1155_for_all, get_trading_approvals_state, a gasless relayer path and split_position, merge_positions and redeem_positions inside the library. On-chain operations still cost gas. Polymarket US has none of this, which is the single largest difference between two SDKs published by the same vendor.

The eligibility check is not in the library and cannot be worked around by it. The limitless-sdk README states that Limitless restricts order placement from US locations for regulatory and sanctions reasons and asks builders to check their location before placing an order — reading is not what is restricted, placing an order is. Polymarket US issues API keys only from the developer page of an account that has completed identity verification, and that gate sits on the WebSocket streams as well as on the writes. What you have to prove about yourself to trade is where that whole question lives.

The package a search result gives you is archived. py-clob-client is MIT, archived, and carries Polymarket's own notice that it is no longer functional and should not be used for new or existing integrations. The PyPI page carries no warning at all, so the install succeeds with nothing to tell you. The replacement is polymarket-client. Two other names on PyPI make this worse: the bare polymarket distribution is an unrelated 2024 package and polymarket-sdk is an unrelated 2026 one, and both install cleanly. Which Python client to write against Polymarket is the head to head.

A 200 is not always a fill. On Polymarket US the per-entry outcome of a batch create is delivered on the private order stream rather than in the HTTP response, and canceledOrderIds is an echo of the request rather than a confirmation — if you are not holding the socket, you do not know what happened. Tools with a streaming feed covers which venues put what on which channel.

If you outgrow this

If the strategy needs more than one venue, CCXT and PMXT are the two abstractions in this catalogue, and tools that cover more than one venue is the listing with what each of them flattens to get there.

And before writing the loop that runs it unattended, read what running a bot does not solve. The things that break a production order path are rate limits, trading hours, a market clarification changing the question under an open position, and resolution taking days — none of which is a property of the client you picked above.

The approaches, in order

Cards in the catalogue that do this, ordered editorially. Paid placement does not affect this order.

  1. 1.Kalshi Python SDK (sync and async)

    Kalshi's current official client, regenerated from the OpenAPI spec on a weekly cadence. REST only, Python 3.13 or newer, no public source.

    Kalshi's current official Python client - weekly releases, Python 3.13 only, no source.

    FreeFree tier

  2. 2.pykalshi

    The MIT third-party Kalshi client with what the generated one leaves out — WebSocket streaming, a local order book, retries and typed errors.

    Unofficial Kalshi client with what the generated SDK leaves out - streams and retries.

    FreeFree tierOpen source

  3. 3.polymarket-client

    Polymarket's own SDK for the on-chain exchange, with reads and trading split across separate classes so a price script never holds key material.

    Polymarket's own unified Python SDK - sync and async, data through order signing.

    FreeFree tierOpen source

  4. 4.Polymarket US Python SDK

    The US exchange from Python. An Ed25519 exchange credential rather than a wallet key, and none of the on-chain approval steps in the way.

    Official SDK for Polymarket US - installs as polymarket-us, unreleased since January.

    FreeFree tierOpen source

  5. 5.limitless-sdk

    Limitless's own async client, signing CLOB and NegRisk orders in process; its README asks builders to check their location before placing one.

    Limitless Exchange's own async Python SDK - CLOB and NegRisk orders, WebSocket, MIT.

    FreeFree tierOpen source

FAQ

Is there one library that places orders on every venue?

Two try. CCXT implements order placement across all seven venues in its prediction namespace, and PMXT covers hosted writes on Polymarket, Opinion and Limitless with Kalshi writes needing its self-hosted path. Both cost you exchange-shaped errors in exchange for one vocabulary, and neither removes the per-venue credential, approval or eligibility work below.

Can I test an order without real money?

On Kalshi, yes — it runs a full demo environment on separate hosts with separate credentials, which is the only sandbox in this catalogue. pykalshi has no paper mode of its own and wiring it to the demo is your job. Limitless states plainly that there is no sandbox, no testnet and no mock mode, and suggests minimum-size live orders on a low-volume market instead.

Why does pip install py-clob-client still work?

Because PyPI carries no warning even though the repository does. py-clob-client is archived and its README says the client is no longer functional and should not be used for new or existing integrations; the migration target is polymarket-client. The install succeeds today with nothing to tell you, which is why it is still the answer most search results give.

Does the SDK ever see my private key?

On the on-chain venues it holds it in process to sign locally, which is the design rather than a lapse — polymarket-client and limitless-sdk both build and sign the payload in your program and post the signature. On the US exchange there is no wallet key at all — the credential is an exchange API key id plus a base64-encoded Ed25519 secret, issued from a developer page.

Sources

  1. Python quickstart Polymarket, read
  2. kalshi-python-sync project page Python Package Index, read
  3. limitless-sdk repository Limitless Exchange, read
  4. Environments Polymarket US, read

The catalogue next door

This page names a handful of cards. The rest of them are in Trading Clients, SDKs & Bots, each filled in against the same schema, with the fields to narrow it yourself.

Last updated . Corrected in place: this is a reference page, not a dated post.