Skip to main content
Beta - Use Only If NecessaryThese endpoints are in beta and still being tested. For most use cases, we strongly recommend using the SDK’s linkUser() method instead, which handles the complex signing logic automatically.Only use these direct endpoints if you have specific requirements like TEE/enclave environments, mobile on-device signing, or custom signing workflows where the SDK cannot be used.
Account linking creates Polymarket CLOB API credentials for a user’s wallet. This is a one-time setup required before placing orders. After linking, credentials should be stored in your database for subsequent order placement.

Overview

The linking flow has two steps for EOA wallets, and three steps for Safe wallets that need allowances:
  1. Prepare - Server generates an EIP-712 payload for the user to sign
  2. Complete - User signs the payload, server derives Polymarket credentials
  3. Set Allowances (Safe wallets only) - Sign and submit allowance transaction
Streamlined Flow for Fresh Safes: When a Safe is deployed during /link-complete, the response includes safeTxPayload and allowancesToSet. You can sign the messageHash directly and call /link-set-allowances - no need to call /link-set-allowances-prepare.

When to Use Direct Endpoints vs SDK


SDK Examples

The SDK handles the two-step flow automatically with a single linkUser() call.

EOA Wallet (Privy Embedded)

Safe Wallet (External Wallets)


Direct Endpoint Examples

Use the direct endpoints when you need control over the signing step, such as in TEE environments or mobile apps with on-device signing.

Endpoint URLs

Headers

All requests require:

Step 1: Prepare Session

POST /v1/polymarket/link-prepare Request the EIP-712 payload that the user needs to sign.
Request Parameters: Success Response:
Safe Wallet Response (includes safeInfo):
Safe Wallet Response with Auto-Deploy (includes safeDeployPayload): When walletType: "safe", autoDeploySafe: true, and the Safe is not yet deployed, the response includes an additional EIP-712 payload for deploying the Safe wallet:
When safeDeployPayload is present, you must sign both eip712Payload (for credentials) and safeDeployPayload (for Safe deployment), then include both signatures in the /link-complete request.

Step 2: Sign the EIP-712 Payload(s)

Sign the eip712Payload using your wallet. The exact method depends on your environment:
For Safe Wallets with Auto-Deploy: If safeDeployPayload was returned in the prepare response, you must also sign it to authorize Safe deployment:

Step 3: Complete Session

POST /v1/polymarket/link-complete Submit the signature to derive Polymarket credentials.
Request Parameters: Success Response:
Safe Wallet Response (includes safeAddress):
Safe Wallet Response with Deployment (when Safe was deployed): When deploymentSignature was provided and the Safe was deployed during this request:
Streamlined Flow: When safeTxPayload is present, you can sign safeTxPayload.messageHash directly using signMessage (eth_sign) and call /link-set-allowances without calling /link-set-allowances-prepare. This is possible because freshly deployed Safes have nonce=0.

Set Allowances (Safe Wallets Only)

For Safe wallets, USDC allowances must be set before trading. There are two ways to set allowances:
  1. Streamlined Flow (recommended for fresh Safes): When /link-complete returns safeTxPayload, sign the messageHash directly and call /link-set-allowances
  2. Standard Flow: Call /link-set-allowances-prepare to get the SafeTx payload, then sign and submit
Critical: Use signMessage, NOT signTypedData!The allowance signature uses a different signing method than the credential signature:
  • Credentials (link-complete): Use signTypedData / EIP-712
  • Allowances (link-set-allowances): Use signMessage / personal_sign / eth_sign
Using the wrong signing method will result in error code 2004: Invalid allowance signature.
The session is available for 30 minutes after /v1/polymarket/link-complete. If the session expires, you’ll need to restart the linking flow.

Streamlined Flow (Fresh Safes)

When the Safe was just deployed (nonce=0), /link-complete returns safeTxPayload with the messageHash to sign:

Standard Flow (Existing Safes)

For Safes that already exist (not freshly deployed), use /link-set-allowances-prepare to get the SafeTx payload.

Step 1: Prepare Allowances (Standard Flow)

POST /v1/polymarket/link-set-allowances-prepare Get the SafeTx payload that the user needs to sign.
Request Parameters: Success Response:
Response when allowances already set:
If allowancesToSet is empty, all allowances are already set. You can skip the signing and submission steps.

Step 2: Sign the SafeTx Hash

Sign the messageHash from the prepare response using eth_sign (personal sign). This is different from EIP-712 signing - you sign the hash directly as a message.
Use signMessage (eth_sign / personal_sign), NOT signTypedData. The server expects a signature created with the Ethereum message prefix.

Step 3: Submit Allowances

POST /v1/polymarket/link-set-allowances Submit the signature to execute the allowance transactions on-chain.
Request Parameters: Success Response:

Complete Direct Endpoint Example

Full example for TEE/mobile environments:

Safe Wallet with Auto-Deploy Example (Privy)

Full example for Safe wallets that need to be deployed using Privy managed wallets:

Health Check

GET /v1/polymarket/link-health Check the link service status.
Response:

Error Handling

Error Codes

Error Response Example

Handling Errors


Session Lifecycle

  • Incomplete sessions expire after 10 minutes
  • Completed sessions are kept for 30 minutes (for /v1/polymarket/link-set-allowances)
  • Each session can only be completed once via /v1/polymarket/link-complete
  • After successful /v1/polymarket/link-complete, the session remains available for /v1/polymarket/link-set-allowances
  • If a session expires, call /v1/polymarket/link-prepare again to start a new session

Security Considerations

  1. Store credentials securely - Encrypt apiSecret and apiPassphrase at rest
  2. Session IDs are single-use - Cannot replay /v1/polymarket/link-complete with same sessionId
  3. Signature verification - Server verifies the signature matches the wallet address
  4. No private keys transmitted - Only the signature is sent to the server

Next Steps

After linking, use the credentials to place orders:
Or call the placeOrder endpoint directly with the credentials.