Polymarket’s CLOB API uses a layered authentication system that trips up almost every developer on first attempt. The errors are cryptic, the wallet architecture is unusual, and getting even one parameter wrong means silent 401s or misleading error messages.

This guide is the definitive reference for Polymarket API authentication. Whether you’re staring at INVALID_SIGNATURE for the tenth time or trying to figure out why your funder address keeps getting rejected, everything you need to debug is here.

Last verified against Polymarket’s API: March 2026.


TL;DR

Most Polymarket auth errors come from three things: using the wrong signatureType for your wallet, passing your signing address instead of your proxy wallet as the funder, or working with stale credentials after a nonce collision. This guide covers every POLY_* header, all three wallet types and when to use each, a complete error reference table, and a step-by-step debugging checklist that will resolve the vast majority of authentication failures.


The Five POLY_* Headers

Every authenticated (L2) endpoint on the Polymarket CLOB API requires exactly five custom headers. If any one is missing or incorrect, the request fails.

HeaderContainsExample
POLY_ADDRESSYour Polygon signer address (the wallet that signs requests)0x1a2B3c4D5e6F7a8B9c0D1e2F3a4B5c6D7e8F9a0b
POLY_SIGNATUREHMAC-SHA256 signature of the request body and timestampa1b2c3d4e5f6... (hex-encoded)
POLY_TIMESTAMPCurrent UNIX timestamp in seconds1741564800
POLY_API_KEYYour derived API key (the apiKey value from credential derivation)a1b2c3d4-e5f6-7890-abcd-ef1234567890
POLY_PASSPHRASEYour derived API passphrase (the passphrase value from credential derivation)randomPassphraseString

These headers are only required for L2 endpoints — authenticated operations like placing orders, canceling orders, and managing positions. Public endpoints (market data, order books, prices) do not require authentication.

The POLY_SIGNATURE is computed as an HMAC-SHA256 of the request timestamp, method, path, and body using your API secret as the key. The SDK clients handle this computation automatically, so you typically only need to worry about it if you are making raw HTTP requests.


Signature Types Explained

The signatureType parameter tells the API how your wallet is structured and how to verify your signatures. Using the wrong type is the single most common cause of INVALID_SIGNATURE errors.

ValueNameWallet TypeNotes
0EOAMetaMask, hardware wallets, standard Ethereum walletsSigns directly with private key. Requires POL for gas.
1POLY_PROXYMagic Link / email login walletsCustom proxy wallet for Magic Link users only.
2GNOSIS_SAFEGnosis Safe multisig proxy walletMost common type. Used by the majority of Polymarket accounts.

Type 0 — EOA (MetaMask, Hardware Wallets)

EOA (Externally Owned Account) is a standard Ethereum wallet where your private key directly controls the address. When you sign a message or transaction, the signature comes from the key itself with no proxy layer in between.

With type 0, your signing address and your funder address are the same address. You do not need to pass a separate funder parameter because there is no proxy wallet — the wallet that signs is the wallet that holds your funds.

EOA wallets require POL (the Polygon native token) for gas fees. If you are building a bot with a type 0 wallet, make sure the wallet is funded with both USDC (for trading) and POL (for transaction gas).

POLY_PROXY is a custom proxy wallet type used exclusively by users who signed up for Polymarket via Magic Link (email-based login). These users have a proxy wallet that was created during the Magic Link onboarding flow.

If you logged into Polymarket using an email address rather than connecting a browser wallet, you are a type 1 user. To use the API, you need to export your private key from Magic Link and import it into your bot or script. The signing key and the proxy wallet address are separate — your private key signs requests, but your funds live at the proxy address.

Type 2 — GNOSIS_SAFE (Most Common)

GNOSIS_SAFE is the most common wallet type for Polymarket users. When you connect a wallet (such as MetaMask) to Polymarket.com for the first time, the platform automatically deploys a Gnosis Safe proxy contract that becomes your trading wallet.

With type 2, there are two distinct addresses:

  • Signing key address — the private key you export from your wallet (MetaMask, etc.)
  • Proxy/funder address — the Gnosis Safe contract address that holds your USDC funds

Your private key authorizes transactions, but the proxy contract is the entity that actually holds and moves funds on the exchange. This separation is why the funder parameter exists and why getting it wrong causes Invalid Funder Address errors.


Funder Address

The funder is the proxy wallet address that holds your trading funds on Polymarket. It is the address displayed on your Polymarket profile at polymarket.com/settings.

When Is It Required?

  • Type 0 (EOA): Not required. Your signing address is your funder address.
  • Type 1 (POLY_PROXY): Required. Your Magic Link signing key is different from the proxy address that holds funds.
  • Type 2 (GNOSIS_SAFE): Required. Your MetaMask signing key is different from the Gnosis Safe proxy address that holds funds.

How to Find It

  1. Log in to polymarket.com
  2. Navigate to Settings (polymarket.com/settings)
  3. The wallet address displayed on your profile page is your proxy/funder address

The Most Common Mistake

Developers frequently pass their MetaMask address (the signing key address) as the funder. This is incorrect for types 1 and 2. The funder must be the proxy wallet address — the one Polymarket displays on your profile — not the address of the private key you are signing with.

If you see Invalid Funder Address, this mismatch is almost certainly the cause.


Error Reference

ErrorCauseFix
INVALID_SIGNATUREWrong signatureType for your wallet type, incorrect private key, or malformed key stringVerify your signatureType matches your wallet (0 for EOA, 1 for Magic Link, 2 for Gnosis Safe). Confirm the private key is correct and includes the 0x prefix.
NONCE_ALREADY_USEDThe nonce provided was previously used to derive API credentials (replay protection)Re-derive your API credentials with a fresh nonce by calling create_or_derive_api_creds() again. Each derivation requires a unique nonce.
Invalid Funder AddressThe funder address does not match the proxy wallet registered to your signing keyUse the address displayed at polymarket.com/settings. Do not use your MetaMask/signing key address.
401 UnauthorizedAPI credentials are expired, revoked, or were never properly initializedRe-derive credentials using create_or_derive_api_creds() and re-initialize your client with the new apiKey, apiSecret, and passphrase.
Clock drift (intermittent 401)The POLY_TIMESTAMP header is too far from the server’s current timeSync your system clock. You can check the server’s time with GET /server-time on the CLOB API and compare.

Debugging Ambiguous Errors

Some errors are more ambiguous than they appear:

  • INVALID_SIGNATURE with a correct key — Almost always means the signatureType is wrong. Try type 2 first (it covers the majority of accounts).
  • Intermittent 401s that work on retry — Usually clock drift. Even a few seconds of timestamp skew can cause sporadic failures.
  • 401 immediately after credential derivation — The client was not re-initialized with the new credentials. Make sure you pass the derived apiKey, apiSecret, and passphrase back into the client constructor.

Deriving API Credentials

Before you can make authenticated requests, you must derive your API credentials. This is a one-time operation (per nonce) that produces an apiKey, apiSecret, and passphrase. These three values, along with your private key and funder address, are everything you need.

Python (py_clob_client)

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import ApiCreds

client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="YOUR_PRIVATE_KEY",
    signature_type=2,  # GNOSIS_SAFE for most users
    funder="YOUR_PROXY_WALLET_ADDRESS"
)

# Derive or create API credentials
creds = client.create_or_derive_api_creds()
print(f"API Key: {creds.api_key}")
print(f"Secret: {creds.api_secret}")
print(f"Passphrase: {creds.api_passphrase}")

# Re-initialize client with derived credentials
client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="YOUR_PRIVATE_KEY",
    signature_type=2,
    funder="YOUR_PROXY_WALLET_ADDRESS",
    creds=ApiCreds(
        api_key=creds.api_key,
        api_secret=creds.api_secret,
        api_passphrase=creds.api_passphrase
    )
)

Important: You must re-initialize the ClobClient with the derived credentials. The first client instance (without creds) can only derive credentials — it cannot make authenticated trading requests until the credentials are passed in.

TypeScript (@polymarket/clob-client)

import { ClobClient } from "@polymarket/clob-client";
import { ethers } from "ethers";

const wallet = new ethers.Wallet("YOUR_PRIVATE_KEY");

const client = new ClobClient(
  "https://clob.polymarket.com",
  137,
  wallet,
  undefined, // creds - will be derived
  2, // signatureType: GNOSIS_SAFE
  "YOUR_PROXY_WALLET_ADDRESS" // funder
);

// Derive API credentials
const creds = await client.createOrDeriveApiKey();
console.log("API Key:", creds.apiKey);
console.log("Secret:", creds.secret);
console.log("Passphrase:", creds.passphrase);

After deriving credentials in TypeScript, create a new ClobClient instance and pass the credentials object as the fourth constructor argument to make authenticated requests.

Storing Credentials

Once derived, you should store the apiKey, apiSecret, and passphrase securely (environment variables, a secrets manager, or an encrypted config file). You do not need to re-derive them on every run — only when they expire, are revoked, or you encounter persistent INVALID_SIGNATURE errors that re-derivation resolves.


Proxy Wallet Architecture

Understanding Polymarket’s proxy wallet system is essential for debugging authentication issues. Here is how the architecture works:

Automatic deployment. Proxy wallets are deployed automatically the first time a user logs into Polymarket.com. If you have never logged into the web interface, your proxy wallet does not exist yet, and API authentication will fail. You must log in at least once before using the API.

The relationship chain:

Private Key  →  Signing Address  →  Proxy/Funder Address
(you hold)      (derived from key)   (deployed by Polymarket)

By wallet type:

  • EOA (type 0): Signing address = funder address. One address does everything. No proxy contract involved.
  • POLY_PROXY (type 1): Signing key is your exported Magic Link key. The proxy address is a separate contract deployed during Magic Link onboarding.
  • GNOSIS_SAFE (type 2): Signing key is your MetaMask/wallet private key. The proxy address is a Gnosis Safe contract deployed by Polymarket on your first login.

Key takeaway: For types 1 and 2, there is always a separation between the key that signs and the address that holds funds. The signing key authorizes actions; the proxy address is where USDC balances and positions actually live. When the API asks for a funder, it wants the proxy address — not your signing key address.

Finding your proxy address: Go to polymarket.com/settings. The address shown there is your proxy/funder address.


Debugging Checklist

When authentication fails, work through this checklist in order:

  1. Verify your wallet type and use the correct signatureType (0 for EOA, 1 for Magic Link, 2 for Gnosis Safe). If unsure, try type 2 first — it is the most common.
  2. For types 1 and 2, confirm your funder address matches polymarket.com/settings. Do not use your MetaMask address or signing key address as the funder.
  3. Check that your private key is correctly formatted with the 0x prefix. Some wallet exports omit the prefix, which causes silent failures.
  4. Verify your system clock is synced. Timestamp drift causes intermittent 401 errors that appear random. Compare your local time against GET /server-time on the CLOB API.
  5. Re-derive API credentials if you get persistent INVALID_SIGNATURE errors. Call create_or_derive_api_creds() and update your stored credentials.
  6. Ensure you have logged into polymarket.com at least once. The proxy wallet must be deployed before the API will accept your credentials. There is no way to deploy it programmatically.
  7. If using a new nonce, make sure it has not been used before. Nonce reuse triggers NONCE_ALREADY_USED. Each credential derivation consumes a unique nonce.

Polymarket US Authentication

Polymarket US uses a completely different authentication system than the Global API covered in this guide. The US platform uses Ed25519 signatures instead of the EIP-712/HMAC system described above. The header names, credential derivation flow, and signing process are all different.

If you are building for the US market or need to support both platforms, see the Polymarket US vs. Global API Guide for a complete comparison of the two authentication systems.


Frequently Asked Questions

What are the five POLY headers required for Polymarket API authentication?

The five L2 headers are: POLY_ADDRESS (your Polygon signer address), POLY_SIGNATURE (HMAC signature of the request), POLY_TIMESTAMP (current UNIX timestamp), POLY_API_KEY (your derived API key), and POLY_PASSPHRASE (your derived passphrase). All five are required for every authenticated trading endpoint on the CLOB API. Public endpoints like market data and order book queries do not require these headers.

What does INVALID_SIGNATURE mean in the Polymarket API?

INVALID_SIGNATURE means the API could not verify your request signature. The three most common causes are: using the wrong signatureType for your wallet (for example, passing type 0 when you should be using type 2), using an incorrect or improperly formatted private key, or having corrupted credentials that need to be re-derived. Start by verifying your signatureType — EOA wallets use type 0, Magic Link wallets use type 1, and Gnosis Safe proxy wallets (the most common) use type 2.

What is the funder address in Polymarket API?

The funder is the proxy wallet address that holds your trading funds. It is the wallet address displayed on your Polymarket.com profile at polymarket.com/settings. For proxy wallet types (1 and 2), the funder address is different from your signing key address. A common mistake is passing your MetaMask address as the funder — this will fail because the API expects the proxy wallet address, not the signing key address.

How do I fix NONCE_ALREADY_USED error on Polymarket?

NONCE_ALREADY_USED means the nonce you provided was previously used to create an API key. Nonces are consumed during credential derivation as a replay protection mechanism. To fix this, generate a new nonce and re-derive your API credentials by calling create_or_derive_api_creds() again. The SDK handles nonce generation automatically, so simply calling the derivation function again should resolve it.

What is the difference between signatureType 0, 1, and 2?

Type 0 (EOA) is for standard Ethereum wallets like MetaMask where your private key directly controls the address — the signing address and funder address are the same. Type 1 (POLY_PROXY) is for Magic Link email login users who have a custom proxy wallet created during the email-based onboarding flow. Type 2 (GNOSIS_SAFE) is for Gnosis Safe multisig proxy wallets and is the most common type — this is what gets deployed automatically when you connect a wallet to Polymarket.com for the first time.


See Also


This guide is maintained by AgentBets.ai. Found an error or API change we missed? Let us know on Twitter.

Not financial advice. Built for builders.