Skip to main content

Overview

This guide demonstrates how to create basic limit orders using the CLOB Client SDK. You’ll learn how to place buy and sell orders with different time-in-force options.

Prerequisites

Before creating orders, ensure you have:
  • Initialized a ClobClient instance
  • Created or derived API credentials
  • USDC balance and approved allowances (for buy orders)
  • Token shares (for sell orders)
  • A valid token ID from the Gamma Markets API
Use createOrDeriveApiKey() to avoid creating duplicate API keys. See the Managing API Keys guide for details.

Basic Setup

First, initialize the CLOB client with your credentials:
import { ClobClient, Side, OrderType } from "@polymarket/clob-client";
import { ethers } from "ethers";

const host = "https://clob.polymarket.com";
const chainId = 137; // Polygon mainnet

// Initialize wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);

// Create or derive API credentials
const creds = await new ClobClient(host, chainId, wallet).createOrDeriveApiKey();

// Initialize client
const clobClient = new ClobClient(
  host,
  chainId,
  wallet,
  creds,
  1 // signatureType: 0 for browser wallets, 1 for email/Magic
);

Creating a Simple Limit Order

The most basic order creation involves specifying a token ID, price, side, and size:
const YES_TOKEN = "71321045679252212594626385532706912750332728571942532289631379312455583992563";

// Create a buy order for 100 shares at $0.50 each
const buyOrder = await clobClient.createOrder({
  tokenID: YES_TOKEN,
  price: 0.50,
  side: Side.BUY,
  size: 100,
});

console.log("Created order:", buyOrder);

// Post the order to the exchange
const result = await clobClient.postOrder(buyOrder, OrderType.GTC);
console.log("Order posted:", result);
{
  "success": true,
  "orderID": "0x1234567890abcdef...",
  "status": "LIVE",
  "matchedAmount": "0",
  "remainingAmount": "100"
}

Single-Step Order Creation

For convenience, use createAndPostOrder() to create and post in one step:
const YES_TOKEN = "71321045679252212594626385532706912750332728571942532289631379312455583992563";

const result = await clobClient.createAndPostOrder(
  {
    tokenID: YES_TOKEN,
    price: 0.50,
    side: Side.BUY,
    size: 100,
  },
  { tickSize: "0.01", negRisk: false },
  OrderType.GTC
);

console.log("Order created and posted:", result);
The tickSize must match the market’s tick size. Common values are "0.1", "0.01", "0.001", or "0.0001". Check the market details to determine the correct tick size.

Order Types

GTC (Good-Til-Canceled)

Orders remain active until filled or manually canceled:
const order = await clobClient.createAndPostOrder(
  {
    tokenID: YES_TOKEN,
    price: 0.50,
    side: Side.BUY,
    size: 100,
  },
  { tickSize: "0.01", negRisk: false },
  OrderType.GTC
);

GTD (Good-Til-Date)

Orders expire at a specific timestamp:
// Set expiration to 1 hour from now
// Add 10 seconds buffer to avoid immediate cancellation
const oneHour = Math.floor((Date.now() + 60 * 60 * 1000 + 10 * 1000) / 1000);

const order = await clobClient.createOrder({
  tokenID: YES_TOKEN,
  price: 0.50,
  side: Side.BUY,
  size: 100,
  expiration: oneHour,
});

const result = await clobClient.postOrder(order, OrderType.GTD);
console.log("GTD order posted:", result);
The CLOB has a 10-second security threshold. Always add at least 10 seconds to your expiration time to prevent immediate cancellation.

Post-Only Orders

Post-only orders are guaranteed not to match immediately. They’re only supported for GTC and GTD orders:
const order = await clobClient.createOrder({
  tokenID: YES_TOKEN,
  price: 0.50,
  side: Side.BUY,
  size: 100,
});

// Post-only is the 4th parameter (postOnly = true)
const result = await clobClient.postOrder(
  order,
  OrderType.GTC,
  false, // deferExec
  true   // postOnly
);
console.log("Post-only order:", result);
Post-only orders will be rejected if they would immediately match with existing orders. This is useful for market makers who want to ensure they’re providing liquidity.

Batch Order Creation

Create and post multiple orders simultaneously:
import { PostOrdersArgs } from "@polymarket/clob-client";

const YES_TOKEN = "71321045679252212594626385532706912750332728571942532289631379312455583992563";

// Create multiple orders
const orders: PostOrdersArgs[] = [
  {
    order: await clobClient.createOrder({
      tokenID: YES_TOKEN,
      price: 0.40,
      side: Side.BUY,
      size: 100,
    }),
    orderType: OrderType.GTC,
  },
  {
    order: await clobClient.createOrder({
      tokenID: YES_TOKEN,
      price: 0.45,
      side: Side.BUY,
      size: 100,
    }),
    orderType: OrderType.GTC,
  },
  {
    order: await clobClient.createOrder({
      tokenID: YES_TOKEN,
      price: 0.55,
      side: Side.SELL,
      size: 100,
    }),
    orderType: OrderType.GTC,
  },
  {
    order: await clobClient.createOrder({
      tokenID: YES_TOKEN,
      price: 0.60,
      side: Side.SELL,
      size: 100,
    }),
    orderType: OrderType.GTC,
  },
];

// Post all orders at once
const results = await clobClient.postOrders(orders);
console.log("Batch order results:", results);
[
  {
    "success": true,
    "orderID": "0xabc...",
    "status": "LIVE"
  },
  {
    "success": true,
    "orderID": "0xdef...",
    "status": "LIVE"
  },
  {
    "success": true,
    "orderID": "0xghi...",
    "status": "LIVE"
  },
  {
    "success": true,
    "orderID": "0xjkl...",
    "status": "LIVE"
  }
]

Complete Example

Here’s a full working example with error handling:
import { ClobClient, Side, OrderType } from "@polymarket/clob-client";
import { ethers } from "ethers";
import { config as dotenvConfig } from "dotenv";

dotenvConfig();

async function main() {
  const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!);
  const chainId = 137; // Polygon mainnet
  const host = "https://clob.polymarket.com";

  console.log(`Address: ${await wallet.getAddress()}`);

  // Initialize client with API credentials
  const creds = {
    key: process.env.CLOB_API_KEY!,
    secret: process.env.CLOB_SECRET!,
    passphrase: process.env.CLOB_PASS_PHRASE!,
  };

  const clobClient = new ClobClient(host, chainId, wallet, creds);

  const YES_TOKEN = "71321045679252212594626385532706912750332728571942532289631379312455583992563";

  try {
    // Create and post a buy order
    const result = await clobClient.createAndPostOrder(
      {
        tokenID: YES_TOKEN,
        price: 0.50,
        side: Side.BUY,
        size: 100,
      },
      { tickSize: "0.01", negRisk: false },
      OrderType.GTC,
      false, // deferExec
      false  // postOnly
    );

    console.log("✓ Order created successfully:", result);
  } catch (error) {
    console.error("✗ Failed to create order:", error);
  }
}

main();

Next Steps

Market Orders

Execute immediate trades at market prices

Order Management

Learn about canceling and managing orders

RFQ Trading

Request quotes for large orders

API Reference

View detailed ClobClient documentation

Build docs developers (and LLMs) love