Skip to main content
Polymarket’s Relayer Client enables gasless transactions for your users. Instead of requiring users to hold POL for gas, Polymarket’s infrastructure pays all transaction fees. This creates a seamless experience where users only need pUSD to trade.

How It Works

The relayer acts as a transaction sponsor:
  1. Your app creates a transaction
  2. The user signs it with their private key
  3. Your app sends it to Polymarket’s relayer
  4. The relayer submits it onchain and pays the gas fee
  5. The transaction executes from the user’s wallet

What Is Covered

Polymarket pays gas for all operations routed through the relayer:
OperationDescription
Wallet deploymentDeploy Safe or Proxy wallets for new users
Token approvalsApprove contracts to spend pUSD or outcome tokens
CTF operationsSplit, merge, and redeem positions
TransfersMove tokens between addresses

Authentication

The relayer uses Relayer API Keys. You can create one from Settings > API Keys on the Polymarket website.
Already have a builder signing key? Your existing HMAC-based builder API key keeps working with the Relayer — no need to rotate or reissue. Only order-signing moved to the native builderCode field in CLOB V2. See Migrating to CLOB V2 for context.
Include these headers with your requests:
HeaderDescription
RELAYER_API_KEYYour Relayer API key
RELAYER_API_KEY_ADDRESSThe address that owns the key
If you want to use the Relayer API Key directly without the SDK, see the Relayer API Reference.

Prerequisites

Before using the relayer, you need:
RequirementSource
Relayer API KeySettings > API Keys
User’s private key or signerYour wallet integration
pUSD balanceFor trading (not for gas)

Installation

npm install @polymarket/builder-relayer-client

Client Setup

Initialize the relayer client with your Relayer API Key:
import { createWalletClient, http, Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { polygon } from "viem/chains";
import { RelayClient } from "@polymarket/builder-relayer-client";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as Hex);
const wallet = createWalletClient({
  account,
  chain: polygon,
  transport: http(process.env.RPC_URL),
});

const client = new RelayClient({
  host: "https://api.copilot.markets/relayer/",
  chain: 137,
  signer: wallet,
  relayerApiKey: process.env.RELAYER_API_KEY!,
  relayerApiKeyAddress: process.env.RELAYER_API_KEY_ADDRESS!,
});
Never expose your Relayer API Key in client-side code. Use environment variables or a secrets manager.

Wallet Types

Choose a wallet type when initializing the client:
TypeDeploymentBest For
SafeCall deploy() before first transactionMost builder integrations
ProxyAuto-deploys on first transactionMagic Link users
import { RelayClient, RelayerTxType } from "@polymarket/builder-relayer-client";

const client = new RelayClient({
  host: "https://api.copilot.markets/relayer/",
  chain: 137,
  signer: wallet,
  relayerApiKey: process.env.RELAYER_API_KEY!,
  relayerApiKeyAddress: process.env.RELAYER_API_KEY_ADDRESS!,
  txType: RelayerTxType.SAFE,
});

// Deploy before first transaction
const response = await client.deploy();
const result = await response.wait();
console.log("Safe Address:", result?.proxyAddress);

Executing Transactions

Use the execute method to send transactions through the relayer:
interface Transaction {
  to: string; // Target contract address
  data: string; // Encoded function call
  value: string; // POL to send (usually "0")
}

const response = await client.execute(transactions, "Description");
const result = await response.wait();

Token Approval

Approve contracts to spend tokens:
import { encodeFunctionData, maxUint256 } from "viem";

const pUSD = "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB";
const CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";

const approveTx = {
  to: pUSD,
  data: encodeFunctionData({
    abi: [
      {
        name: "approve",
        type: "function",
        inputs: [
          { name: "spender", type: "address" },
          { name: "amount", type: "uint256" },
        ],
        outputs: [{ type: "bool" }],
      },
    ],
    functionName: "approve",
    args: [CTF, maxUint256],
  }),
  value: "0",
};

const response = await client.execute([approveTx], "Approve pUSD for CTF");
await response.wait();

Redeem Positions

Exchange winning tokens for pUSD after market resolution:
import { encodeFunctionData } from "viem";

const redeemTx = {
  to: CTF_ADDRESS,
  data: encodeFunctionData({
    abi: [
      {
        name: "redeemPositions",
        type: "function",
        inputs: [
          { name: "collateralToken", type: "address" },
          { name: "parentCollectionId", type: "bytes32" },
          { name: "conditionId", type: "bytes32" },
          { name: "indexSets", type: "uint256[]" },
        ],
        outputs: [],
      },
    ],
    functionName: "redeemPositions",
    args: [collateralToken, parentCollectionId, conditionId, indexSets],
  }),
  value: "0",
};

const response = await client.execute([redeemTx], "Redeem positions");
await response.wait();

Batch Transactions

Execute multiple operations atomically in a single call:
const approveTx = {
  to: pUSD,
  data: encodeFunctionData({
    abi: erc20Abi,
    functionName: "approve",
    args: [CTF, maxUint256],
  }),
  value: "0",
};

const transferTx = {
  to: pUSD,
  data: encodeFunctionData({
    abi: erc20Abi,
    functionName: "transfer",
    args: [recipientAddress, parseUnits("50", 6)],
  }),
  value: "0",
};

// Both execute atomically
const response = await client.execute(
  [approveTx, transferTx],
  "Approve and transfer",
);
await response.wait();
Batching reduces latency and ensures all transactions succeed or fail together.

Transaction States

Track transaction progress through these states:
StateTerminalDescription
STATE_NEWNoTransaction received by relayer
STATE_EXECUTEDNoSubmitted onchain
STATE_MINEDNoIncluded in a block
STATE_CONFIRMEDYesFinalized successfully
STATE_FAILEDYesFailed permanently
STATE_INVALIDYesRejected as invalid

Contract Addresses

See Contracts for all Polymarket smart contract addresses on Polygon.

Resources

Next Steps

Negative Risk Markets

Learn about capital-efficient trading for multi-outcome events.

Positions & Tokens

Understand token operations like split, merge, and redeem.