API · Troubleshooting

This page takes the exact error strings the Polymarket CLOB returns and explains each one: what it means, why it usually happens, and the fix, with code for the official clients. Polymarkets.co.il is an independent guide, not Polymarket. Every string, address and method name below was checked on 25 October 2026 against the official documentation (docs.polymarket.com), the official repositories under github.com/Polymarket and, for the Deposit Wallet contracts, the verified source and live reads on Polygon. Where a cause is only reported by developers on GitHub, we say so.

Quick answers: the four errors developers hit most
  • not enough balance / allowance when selling: the CLOB cannot see your outcome tokens or their approval. Refresh the cache with update_balance_allowance using asset_type=CONDITIONAL and the token_id you are selling, and make sure the client has the right signature_type and funder. Details.
  • maker address not allowed, please use the deposit wallet flow: the account trades through a Deposit Wallet (every wallet created since 4 May 2026), but your order uses an EOA, proxy or Safe as maker. Sign as the Deposit Wallet (signature type 3), ideally with the unified SDK. Details.
  • the order signer address has to be the address of the API KEY: the order was signed for a different address than the one your API key belongs to. Create the API key and sign the order with the same client setup. Details.
  • order_version_mismatch: you are still on the V1 client (py-clob-client 0.34.x or @polymarket/clob-client), which stopped working on 28 April 2026. Move to the unified SDK. Details.
Check your client first. As of 25 October 2026:
  • Current: the unified SDKs, polymarket-client 0.14.0 on PyPI (import polymarket) and @polymarket/client 0.14.0 on npm. Rust: polymarket_client_sdk_v2 0.7.0 (repo rs-clob-client-v2).
  • Deprecated but still working: py-clob-client-v2 1.2.1 and @polymarket/clob-client-v2 1.2.0. Both now point to the unified SDK.
  • Dead since the 28 April 2026 exchange upgrade: py-clob-client 0.34.6 and @polymarket/clob-client 5.8.1 (repositories archived). Orders they sign are rejected.
Code below is labelled with the client it was written for.

Every CLOB error comes back as JSON with an error field, for example {"error": "not enough balance / allowance"}. Order responses can instead carry "success": false and the reason in errorMsg. Read that field first: the message is usually more specific than the HTTP status.

not enough balance / allowance

What it means. The CLOB checked your account before accepting the order and found too little to cover it, or no approval for the exchange to move it. For a BUY it checks pUSD; for a SELL it checks the outcome tokens (the conditional tokens) of that exact token_id. Polymarket's docs say the CLOB "rejects buy orders without the pUSD approval and sell orders without the outcome token approval". An allowance error names one missing spender at a time.

Why it happens most often when you SELL

  • You checked the wrong asset. A Polymarket team member explained on GitHub (py-clob-client issue #265) that sell orders check your conditional token balance, not collateral. Query and refresh AssetType.CONDITIONAL with the token_id, not COLLATERAL.
  • The CLOB's cache is stale. The CLOB keeps its own view of your balances and approvals. Polymarket's docs say to refresh the conditional allowance for each outcome before its first sell order (GET /balance-allowance/update).
  • The client points at the wrong wallet. If your shares sit in a proxy, Safe or Deposit Wallet, the client needs that wallet as funder and the matching signature_type. In py-clob-client-v2 the balance calls send the client's signature type and ignore the signature_type field inside BalanceAllowanceParams, so build the client right.
  • Open orders reserve the shares. The docs define the largest order you can place as your balance minus what your open orders still reserve. A resting sell for the same shares blocks a second sell.
  • The buy has not settled yet. A matched trade moves through MATCHED, MINED and CONFIRMED. Developers report (issue #287 on py-clob-client) that selling the full size right after an instantly matched buy can fail while a slightly smaller sell, or the same sell a little later, goes through. Treat this as reported behaviour, not documented.
  • Negative-risk market. On CTF negative-risk markets the CLOB also checks approvals for the Neg Risk Adapter 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296. If the error names that address, the wallet is missing those approvals.
  • Buys only: collateral must be pUSD (since 28 April 2026), with enough left after open buy orders.

Fix: refresh the conditional allowance (py-clob-client-v2 1.2.1)

# pip install py-clob-client-v2   (deprecated, still works; unified SDK below)
import os
from py_clob_client_v2 import (
    ApiCreds, AssetType, BalanceAllowanceParams, ClobClient, SignatureTypeV2,
)

client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key=os.environ["PK"],                         # the signing key
    creds=ApiCreds(
        api_key=os.environ["CLOB_API_KEY"],
        api_secret=os.environ["CLOB_SECRET"],
        api_passphrase=os.environ["CLOB_PASS_PHRASE"],
    ),
    signature_type=SignatureTypeV2.POLY_PROXY,    # 1 proxy, 2 Safe, 3 Deposit Wallet
    funder=os.environ["FUNDER"],                  # the wallet that holds the shares
)

token_id = "YOUR_OUTCOME_TOKEN_ID"
params = BalanceAllowanceParams(asset_type=AssetType.CONDITIONAL, token_id=token_id)
client.update_balance_allowance(params)           # refresh the CLOB's cache
print(client.get_balance_allowance(params))       # check balance and allowance

Same fix in TypeScript (@polymarket/clob-client-v2 1.2.0)

import { AssetType, ClobClient, SignatureTypeV2 } from "@polymarket/clob-client-v2";

const client = new ClobClient({
  host: "https://clob.polymarket.com",
  chain: 137,
  signer: walletClient,                 // viem wallet client for your signing key
  creds,                                // { key, secret, passphrase }
  signatureType: SignatureTypeV2.POLY_PROXY,
  funderAddress: process.env.FUNDER,
});

await client.updateBalanceAllowance({ asset_type: AssetType.CONDITIONAL, token_id: tokenId });
console.log(await client.getBalanceAllowance({ asset_type: AssetType.CONDITIONAL, token_id: tokenId }));

Fix with the unified SDK (polymarket-client 0.14.0)

The unified clients set up approvals for you. Per the docs, setup_trading_approvals() checks what exists and submits only what is missing, and order placement can recover a missing exchange allowance on its own and retry. Neither covers the Neg Risk Adapter, so add those two approvals once.

# pip install polymarket-client
import os
from polymarket import AsyncSecureClient, RelayerApiKey

client = await AsyncSecureClient.create(
    private_key=os.environ["SIGNER_PRIVATE_KEY"],
    wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
    api_key=RelayerApiKey(                         # needed for gasless approvals
        key=os.environ["POLYMARKET_RELAYER_API_KEY"],
        address=os.environ["POLYMARKET_RELAYER_API_KEY_ADDRESS"],
    ),
)
await client.setup_trading_approvals()

# CTF negative-risk markets: approvals for the Neg Risk Adapter
adapter = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296"
await (await client.approve_erc20(
    token_address="0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",   # pUSD, for buys
    spender_address=adapter, amount="max")).wait()
await (await client.approve_erc1155_for_all(
    token_address="0x4D97DCd97eC945f40cF65F87097ACe5EA0476045",   # Conditional Tokens, for sells
    operator_address=adapter, approved=True)).wait()

print(await client.get_balance_allowance(asset_type="CONDITIONAL", asset_id=token_id))

Positions in Polymarket Protocol V2 markets live in the PositionManager contract, not in Conditional Tokens. For those, the asset type is CONDITIONAL-V2 with the position ID. py-clob-client-v2 only knows COLLATERAL and CONDITIONAL, so use the unified SDK or the raw endpoint there.

The approvals the CLOB checks (docs, Set Up Trading Approvals, 25 Oct 2026)
TokenApproved toCall
pUSD 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFBStandard Exchange 0xE111180000d2663C0091e4f400237545B87B996B, Neg Risk Exchange 0xe2222d279d744050d28e00520010520000310F59, Neg Risk Adapter 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296, Polymarket V2 Exchange 0xe3333700cA9d93003F00f0F71f8515005F6c00Aaapprove(spender, max)
Conditional Tokens 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045Standard Exchange, Neg Risk Exchange, Neg Risk AdaptersetApprovalForAll(operator, true)
PositionManager 0x006F54F7f9A22e0000CC2AB60031000000ae9fEFPolymarket V2 ExchangesetApprovalForAll(operator, true)
Approving NegRiskCtfCollateralAdapter (0xadA2005600Dec949baf300f4C6120000bDB6eAab) does not count as the Neg Risk Adapter approval: they are different contracts.

signature_type and funder: which values for a proxy, Safe or Deposit Wallet

Many balance and signer errors come down to these two settings. The signing key (your EOA, or a session key) signs; the funder is the wallet that actually holds pUSD and shares.

Account typesignature_typefunder
Deposit Wallet (default for wallets deployed since 4 May 2026)3, POLY_1271the Deposit Wallet address
Proxy Wallet (older email, Magic or Google accounts)1, POLY_PROXYthe proxy wallet address
Safe Wallet (older MetaMask or Rabby accounts)2, POLY_GNOSIS_SAFEthe Safe address
Plain EOA (only if allowlisted for trading)0, EOAnone; the EOA itself

Your account wallet address is in the profile menu on polymarket.com. With the unified SDK you do not set these numbers: the client resolves the wallet type (client.account.walletType in TypeScript, client.wallet_type in Python). If you call GET /balance-allowance yourself and get Invalid signature_type, the value is not one the endpoint accepts; the docs' own Deposit Wallet example sends signature_type=3.

maker address not allowed, please use the deposit wallet flow

What it means. The exchange refused the address in the order's maker field and asks you to trade through a Deposit Wallet instead. This string is not in Polymarket's error reference yet, but the docs explain the background: every account wallet deployed on or after 4 May 2026 is a Deposit Wallet, and a plain EOA can only be the trading wallet if it is allowlisted.

Usual causes.

  • You sign with signature_type=0 (EOA) on a key that is not allowlisted.
  • A newer account set up with type 1 or 2 and a proxy or Safe as funder. Developers have reported this error for both setups since May 2026 (py-clob-client-v2 issues #48, #51 to #53, #61, #116).
  • The account has no Deposit Wallet deployed yet.

Fix. Use the Deposit Wallet as maker and funder with signature type 3. The unified SDK does this for you; omit wallet and it uses the default Deposit Wallet flow, or pass the wallet address from your polymarket.com profile.

// npm install @polymarket/client viem      (@polymarket/client 0.14.0)
import { createSecureClient, OrderSide } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";

const client = await createSecureClient({
  wallet: process.env.POLYMARKET_WALLET_ADDRESS,   // your Deposit Wallet
  signer: privateKey(process.env.POLYMARKET_PRIVATE_KEY),
});
console.log(client.account);   // walletType 3 = DEPOSIT_WALLET

await client.placeLimitOrder({ assetId, side: OrderSide.BUY, price: "0.52", size: "10" });

In Rust, the docs show the same with polymarket_client_sdk_v2 0.7.0: .funder(deposit_wallet).signature_type(SignatureType::Poly1271) on the authentication builder. The Rust SDK places orders for an existing Deposit Wallet but does not deploy one. A developer report (py-clob-client-v2 issue #111, August 2026) found the legacy Python client could not produce the nested signature a Deposit Wallet needs, which is another reason to move to the unified SDK.

the order signer address has to be the address of the API KEY

What it means. Your L2 API key belongs to one address and the order was signed for another. Its sibling, the order owner has to be the owner of the API KEY, is documented as: the maker in the order does not match the address associated with your API key.

Usual causes.

  • API credentials created with one key, orders signed with another (for example after rotating keys or copying .env files between bots).
  • For proxy and Safe accounts: the signing key is the EOA and the funder is the proxy or Safe. Swapping them, or leaving out funder and signature_type, breaks the match.
  • Deposit Wallet orders (type 3) through the legacy v2 clients. Many reports since May 2026 (py-clob-client-v2 #64, #70, #71, #75, #77, #90; clob-client-v2 #73, #103). Developers report that switching to the unified SDK resolved it.

Fix. Create or derive the API key and place orders from one consistently configured client. In the unified SDK, createSecureClient / AsyncSecureClient.create derives or creates the CLOB credentials, resolves the account wallet and picks the signing flow, so they cannot drift apart. With a session key, the session key creates its own credentials (see below).

# pip install polymarket-client      (polymarket-client 0.14.0)
import os
from polymarket import AsyncSecureClient

client = await AsyncSecureClient.create(
    private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
    wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
)
credentials = client.credentials   # store these; pass them back to resume the same key

order_version_mismatch

What it means. The order was built for a different exchange version than the one the CLOB expects. Since the 28 April 2026 upgrade, Polymarket says V1 SDKs and V1-signed orders are no longer supported: the order struct dropped nonce, feeRateBps and taker, added timestamp (milliseconds), metadata and builder, and the Exchange EIP-712 domain version moved from "1" to "2" (the ClobAuth domain stays "1").

Fix. Remove py-clob-client or @polymarket/clob-client and install the unified SDK (pip install polymarket-client or npm install @polymarket/client viem). If you sign orders by hand, follow the current order typed data in the docs' Place Orders page. Orders resting before the upgrade were wiped and must be placed again.

Unauthorized/Invalid api key, Invalid L1 Request headers, Could not create api key

  • Unauthorized/Invalid api key (401): the L2 key is missing, expired or wrong on an authenticated endpoint. Send all of POLY_ADDRESS, POLY_API_KEY, POLY_PASSPHRASE, POLY_SIGNATURE and POLY_TIMESTAMP.
  • Invalid L1 Request headers (401): the EIP-712 ClobAuth signature used to create or derive a key is malformed or does not match POLY_ADDRESS. The L1 message is signed by the signing key (domain ClobAuthDomain, version "1", chain 137) with a fresh Unix timestamp in seconds.
  • Could not create api key / Could not derive api key! (400): creation or derivation failed. The docs say to derive the credentials when they already exist for that signer and nonce (nonce 0 unless you manage several credential sets), so switch between create and derive. Developers have also reported Cloudflare 403 blocks on key creation (py-clob-client-v2 #41).

Reading market data needs no key at all. Credentials are only for orders, cancels and account data.

Price breaks minimum tick size rule

Full string: order {id} is invalid. Price ({price}) breaks minimum tick size rule: {tick}. Your price is not a multiple of the market's tick size. Read tick_size from GET /book or GET /tick-size and round to it. Tick sizes can change (World Cup markets moved to 0.0025 in July 2026), so listen for the tick_size_change event if you cache it.

Size lower than the minimum

Full string: order {id} is invalid. Size ({size}) lower than the minimum: {min}. The book returns min_order_size (5 shares in the docs' example). Raise the size above it.

FOK and FAK messages

  • order couldn't be fully filled. FOK orders are fully filled or killed.: a Fill-or-Kill order could not fill completely against resting orders, so nothing filled. Size to the visible depth, adjust the price, or use FAK.
  • no orders found to match with FAK order. FAK orders are partially filled or killed if no match is found.: a Fill-and-Kill order found nothing at your price.
  • invalid post-only order: order crosses book: a post-only order would have matched at once. Move the price so it rests.

Background: FOK, FAK and GTC orders.

Trading is currently cancel-only, post-only mode, Trading is currently disabled, 425

  • Trading is currently disabled. Check polymarket.com for updates (503): the exchange is paused; no orders or cancels are accepted.
  • Trading is currently cancel-only... (503): cancels work, new orders do not.
  • post-only mode: only post-only orders and cancels are allowed (503): the response carries retry_after_seconds and a Retry-After header. Send post-only orders or wait.
  • HTTP 425 Too Early: the matching engine is restarting. Retry with exponential backoff; the docs' Rust example rebuilds and re-signs the order before each retry.

address in closed only mode, address banned

'{address}' address in closed only mode and '{address}' address banned are listed by Polymarket without further detail. Polymarket also restricts order placement by location, with some regions limited to closing positions. Check the requesting IP with GET https://polymarket.com/api/geoblock (fields blocked, country, region) and contact Polymarket support about the address itself.

Too Many Requests (429)

You passed a rate limit. Most limits are per IP and Polymarket throttles (delays or queues) requests over the limit; order and cancel requests also have per-signer limits. Back off exponentially and keep a client-side limiter. Current numbers are in the docs' Rate Limits page.

"Order failed" with no clear message

When an order "just fails", check these in order:

  1. The errorMsg in the response (or error for non-200 replies). Batch posts return per-order errors inside a 200 response.
  2. order timed out (500): the order never reached the book, usually during bursts from one account. It can be resubmitted safely.
  3. the market is not yet ready to process new orders: the market is not open for orders yet.
  4. invalid expiration: GTD expiration must be at least 3 minutes ahead, and orders expire one minute before the time you set.
  5. The client, wallet type and approvals described above.

Certificate error (SSL: CERTIFICATE_VERIFY_FAILED)

Polymarket's docs do not cover this one, so these are general TLS checks, not Polymarket guidance. A certificate error when calling clob.polymarket.com usually comes from your side: a wrong system clock, an outdated CA bundle in your Python or Node environment (update certifi or the OS certificates), or a corporate proxy or antivirus that intercepts TLS. Fix the trust store rather than turning off verification: a bot that skips certificate checks sends its signed requests to whoever answers.

The Deposit Wallet contracts: factory, execute(Batch), authorizeSessionSigner

Developers searching for function authorizeSessionSigner or function execute(Batch are usually reading the Deposit Wallet source. Here is what the verified code does.

Addresses (Polygon, chain 137), verified 25 October 2026
  • Deposit Wallet Factory: 0x00000000000Fb5C9ADea0298D729A0CB3823Cc07. Listed on Polymarket's Contracts page (docs.polymarket.com/resources/contracts) and used as the Relayer to address in the docs. On chain it is an ERC-1967 proxy whose implementation is 0x528cc05efac2b0d255e423272187efd41248abd7.
  • Deposit Wallet Beacon: 0x7A18EDfe055488A3128f01F563e5B479D92ffc3a (Contracts page). Its implementation() returned 0xf7f27c29e60fe6325bef8da7f93250353d2e3294, the current DepositWallet code for beacon wallets (deployed after 29 June 2026).
  • Legacy implementation: the factory's LEGACY_IMPL() returned 0x58ca52ebe0dadfdf531cde7062e76746de4db1eb, the DepositWallet code behind the earlier UUPS wallets.
The three implementation addresses come from our own reads of the contracts on Polygon (block 96160295). All three have source verified as an exact match on Sourcify, written by Polymarket (Solidity 0.8.34, BUSL-1.1 license). We did not find this wallet source in Polymarket's public GitHub repositories on that date.

execute(Batch) and onlyFactory

function execute(Batch calldata _batch, bytes calldata _signature) external onlyFactory

modifier onlyFactory() {
    require(msg.sender == factory(), OnlyFactory());
    _;
}

execute runs a batch of calls (target, value, data) from the wallet. onlyFactory means only the factory contract may call it; anyone else gets the OnlyFactory() revert. The factory in turn exposes proxy(Batch[], bytes[]), which only addresses with the factory's operator role may call. In the docs, signed batches are sent to Polymarket's Relayer with the factory as the to address, so wallet actions are gasless and you never call execute yourself.

Inside execute the wallet checks, in order: the batch is not empty, wallet is this wallet, nonce equals its next nonce (InvalidNonce), the deadline has not passed (Expired), and the EIP-712 signature (domain DepositWallet, version "1") comes from the owner or a still-valid session signer (InvalidSignature). It then runs the calls in order; if any call fails, the whole batch reverts. A batch signed by a session signer may not call the wallet itself or the beacon.

authorizeSessionSigner

function authorizeSessionSigner(address _sessionSigner, uint256 _validUntil) external onlySelf

This stores an expiry time for a session signer. onlySelf means the wallet must call it on itself, so the only way in is an owner-signed batch whose call targets the wallet's own address, run through the factory. It rejects the zero address and a validUntil that is not in the future. revokeSessionSigner(address) sets the expiry back to zero. Because session-signed batches cannot call the wallet, a session signer cannot add other signers or change the owner.

Session keys and API keys are different things

  • A session key is an ordinary key pair that the Deposit Wallet owner authorizes on chain to trade for the wallet. Per the docs it lasts 180 days (the Relayer rejects other values; revoke to end it early), can be scoped to CLOB, COMBOSRFQ or ALL, and cannot withdraw funds. The scopes are not in the wallet contract we read; they are recorded when you authorize through the Relayer. Authorizing one needs a Builder API key, which during the beta Polymarket's builder team has to enable.
  • An API key (L2 credentials: key, secret, passphrase) authenticates HTTP requests to the CLOB. The session key creates its own API key by signing the ClobAuth message, and its orders still name the Deposit Wallet as maker and signer with signature type 3.
  • A session key only sees its own orders, trades and notifications. Revoking it cancels its open orders.
# polymarket-client 0.14.0: owner authorizes, session key trades
from polymarket import AsyncSecureClient, BuilderApiKey

owner = await AsyncSecureClient.create(
    private_key=os.environ["POLYMARKET_PRIVATE_KEY"],
    wallet=os.environ["POLYMARKET_DEPOSIT_WALLET"],
    api_key=BuilderApiKey(
        key=os.environ["POLYMARKET_BUILDER_API_KEY"],
        secret=os.environ["POLYMARKET_BUILDER_SECRET"],
        passphrase=os.environ["POLYMARKET_BUILDER_PASSPHRASE"],
    ),
)
await owner.authorize_session_key(address=session_key_address)   # 180 days

session = await AsyncSecureClient.create(
    private_key=os.environ["POLYMARKET_SESSION_PRIVATE_KEY"],
    wallet=os.environ["POLYMARKET_DEPOSIT_WALLET"],
)
await session.place_limit_order(asset_id=asset_id, side="BUY", price="0.52", size="10")

The owner can also pause the wallet and, after the factory's timelock (it read 3,600 seconds, one hour, on 25 October 2026), recover assets or opt out of beacon upgrades. The docs warn that an opted-out wallet gets no future fixes.

All errors at a glance

Error stringUsual causeFix
not enough balance / allowanceMissing pUSD or shares, missing approval, stale CLOB cache, wrong funder, shares reserved by open ordersRefresh with CONDITIONAL + token_id (sells) or COLLATERAL (buys); set approvals; correct signature_type and funder
maker address not allowed, please use the deposit wallet flowMaker is an EOA, proxy or Safe on an account that must trade through a Deposit WalletSignature type 3 with the Deposit Wallet as funder; unified SDK
the order signer address has to be the address of the API KEYAPI key and order signed for different addressesCreate the key and sign orders from one client setup
the order owner has to be the owner of the API KEYOrder maker differs from the API key's addressSame as above; check funder
order_version_mismatchV1 client or V1 order struct after 28 April 2026Unified SDK; current order typed data
Unauthorized/Invalid api keyL2 credentials missing or wrongCreate or derive credentials; send all five headers
Invalid L1 Request headersBad ClobAuth signature or headersSign ClobAuth with the signing key, fresh timestamp
Could not create api key / Could not derive api key!Key exists or cannot be derivedDerive instead of create (or the reverse), same nonce
Invalid signature_typeUnaccepted value on balance-allowanceUse the wallet's type (3 for Deposit Wallets)
Price ({price}) breaks minimum tick size rulePrice not on the tick gridRound to tick_size; watch tick_size_change
Size ({size}) lower than the minimumBelow min_order_sizeIncrease size
FOK orders are fully filled or killedNot enough depth for a full fillSmaller size, other price, or FAK
invalid post-only order: order crosses bookPost-only order would matchPrice it to rest
post-only mode / cancel-only / Trading is currently disabledExchange mode or pauseWait for Retry-After; cancels still work in the first two
425 Too EarlyMatching engine restartBackoff, re-sign, retry
order timed outBurst of orders from one accountResubmit; spread out submissions
address in closed only modeAddress limited to closing positionsCheck geoblock; contact support
429 Too Many RequestsRate limitExponential backoff, client-side limiter
OnlyFactory() revertCalled DepositWallet.execute directlySubmit the signed batch through the Relayer
InvalidNonce() / Expired() revertStale wallet nonce or past deadlineFetch a fresh WALLET nonce, set a future deadline
Sources checked on 25 October 2026 (named, not linked): Polymarket docs pages Error Codes, Wallets and Authentication, Session Keys, Contracts, Order Lifecycle, Place Orders, Rate Limits, Geographic Restrictions, Migrate from Legacy SDKs to Unified SDKs, and the Predictions and SDK changelogs (all under docs.polymarket.com); the official repositories github.com/Polymarket/py-clob-client-v2, github.com/Polymarket/clob-client-v2, github.com/Polymarket/py-sdk and github.com/Polymarket/ts-sdk, and the issue threads cited above; package versions on PyPI and npm; the Deposit Wallet source verified on Sourcify; and direct reads of the factory and beacon on Polygon.

Next: Authentication and wallets · Which SDK to use · CLOB API reference · The pUSD migration · API quickstart.