Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt

Use this file to discover all available pages before exploring further.

The unified TypeScript SDK gives you a consistent surface across Polymarket discovery, market data, trading, account data, and realtime streams.
The TypeScript SDK is currently in beta. We are keeping it in this beta phase while we address issues and harden the SDK before transitioning to a more stable release.

Quickstart

1

Install the Package

Install the SDK from your package manager.
pnpm add @polymarket/client@beta
2

Create a Public Client

Create an instance of the PublicClient.
import { createPublicClient } from "@polymarket/client";

const client = createPublicClient();
3

Fetch Markets

Fetch a page of markets to discover active trading opportunities.
const markets = client.listMarkets({
  closed: false,
  pageSize: 5,
});

const firstPage = await markets.firstPage();

for (const market of firstPage.items) {
  // market: Market
}

SDK Patterns

The SDK normalizes data across API seams and uses consistent patterns for pagination and typed error handling across public and authenticated workflows.

Typed Primitives

Common primitives such as IDs, decimal values, date/time strings, and EVM addresses are represented with explicit SDK types so integrations can avoid treating every value as a plain string.
type Market = {
  id: MarketId;
  conditionId: ConditionId | null;
  state: {
    startDate?: IsoDateTimeString | null;
    endDate?: IsoDateTimeString | null;
  };
  outcomes: {
    yes: {
      tokenId: TokenId | null;
      price: DecimalString | null;
    };
  };
  resolution: {
    resolvedBy: EvmAddress | null;
  };
  // …
};

Market and Event Data

Market and event responses use normalized field names and TypeScript shapes instead of service-specific response formats.
type Market = {
  id: MarketId;
  slug?: string | null;
  conditionId: ConditionId | null;
  question?: string | null;
  description?: string | null;
  category?: string | null;
  image?: string | null;
  icon?: string | null;
  state: MarketState;
  outcomes: MarketOutcomes;
  metrics: MarketMetrics;
  prices: MarketPrices;
  trading: MarketTrading;
  resolution: MarketResolution;
  rewards: MarketRewards;
  sports: MarketSportsMetadata;
  tags: MarketTag[];
  // …
};

Pagination

List methods return a consistent paginator interface across paginated endpoints. Use for await to iterate through pages.
const markets = client.listMarkets({
  closed: false,
  pageSize: 10,
});

for await (const page of markets) {
  // page.items: Market[]
}
You can also fetch the first page directly and resume later from a cursor.
const firstPage = await markets.firstPage();
// firstPage.items: Market[]

for await (const page of markets.from(firstPage.nextCursor)) {
  // page.items: Market[]
}

Error Handling

Each public action exposes a matching error guard. Use it to handle expected SDK errors and rethrow anything unexpected.
Error guards make exhaustive checks easier and help surface newly added SDK error cases during upgrades.
import { ListMarketsError } from "@polymarket/client";

try {
  const markets = client.listMarkets({
    closed: false,
    pageSize: 10,
  });

  const firstPage = await markets.firstPage();
  // firstPage.items: Market[]
} catch (error) {
  if (!ListMarketsError.isError(error)) {
    throw error;
  }

  switch (error.name) {
    case "RateLimitError":
      // Retry later.
      break;
    case "UserInputError":
      // Fix the request parameters.
      break;
    default:
    // …
  }
}

Market Data

Use market data methods to fetch market and event details, order books, current prices, historical prices, and batch quotes.
const market = await client.fetchMarket({
  url: "https://polymarket.com/market/eth-flipped-in-2026",
});

const market = await client.fetchMarket({
  slug: "eth-flipped-in-2026",
});

const market = await client.fetchMarket({
  id: "12345",
});
Then fetch related tags, order books, prices, and history.
const marketTags = await client.fetchMarketTags({
  id: market.id,
});

const eventTags = await client.fetchEventTags({
  id: event.id,
});

Discovery

Use discovery methods to browse events, markets, teams, tags, comments, sports metadata, and search results. The examples below show a few common entry points.
const events = client.listEvents({
  pageSize: 10,
});

for await (const page of events) {
  // page.items: Event[]
}

Realtime Streams

Subscribe through one SDK interface even when events are served by different websocket surfaces. The SDK routes each subscription spec to the right stream and merges the results into one stream.
const stream = await client.subscribe([
  {
    topic: "market",
    tokenIds: [market.outcomes.yes.tokenId!],
  },
  {
    topic: "prices.crypto.binance",
    symbols: ["btcusdt"],
  },
]);

for await (const event of stream) {
  // event:
  //   | MarketBookEvent
  //   | MarketPriceChangeEvent
  //   | MarketLastTradePriceEvent
  //   | MarketTickSizeChangeEvent
  //   | CryptoPricesBinanceEvent

  if (shouldStopStreaming()) {
    await stream.close();
  }
}

Authenticated Client

Create a secure client when you need wallet-scoped reads or trading.

Wallet Integrations

The SDK is intended to support a variety of wallet libraries. At launch, we support Viem, Privy, and Ethers v5. We will expand support for more libraries based on demand.
1

Install the Packages

Install the SDK and Viem wallet tools.
pnpm add @polymarket/client@beta viem
2

Create the Secure Client

Use the private-key helper, or adapt an existing viem wallet client.
import { createSecureClient } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";

const secureClient = await createSecureClient({
  wallet: "YOUR_POLYMARKET_WALLET_ADDRESS",
  signer: privateKey(process.env.PRIVATE_KEY),
});

Trading Setup

Before placing orders, configure API key authentication if you need gasless wallet setup, then make sure the authenticated wallet has the required trading approvals.
1

Configure API Key Authentication

Configure an API key when the SDK needs to set up gasless wallet operations.
import { createSecureClient, relayerApiKey } from "@polymarket/client";

let secureClient = await createSecureClient({
  wallet: "YOUR_POLYMARKET_WALLET_ADDRESS",
  signer,
  apiKey: relayerApiKey({
    key: process.env.RELAYER_API_KEY!,
    address: process.env.RELAYER_API_KEY_ADDRESS!,
  }),
});
Builder API keys are supported for backwards compatibility with builders that still use them for gasless workflows. They are not used for order attribution. Use builderCode on orders for attribution.
2

Check Gasless Readiness

Check whether the authenticated wallet is already ready for gasless transactions.
const isGaslessReady = await secureClient.isGaslessReady();
3

Set Up Gasless Wallet

If needed, set up the gasless wallet and continue with the returned secure client.
if (!isGaslessReady) {
  secureClient = await secureClient.setupGaslessWallet();
}
4

Set Up Trading Approvals

Set up the approvals required for trading and wait for the setup transaction to complete.
const handle = await secureClient.setupTradingApprovals();
await handle.wait();

Trading

Use a secure client to create, sign, and submit orders. Limit orders specify the price and size you want to trade. Market orders execute against resting liquidity immediately. Order placement returns a discriminated response. Check response.ok before reading order details.

Place Orders

import { OrderSide } from "@polymarket/client";

const response = await secureClient.placeLimitOrder({
  tokenId: market.outcomes.yes.tokenId!,
  side: OrderSide.BUY,
  price: 0.52,
  size: 10,
});

if (response.ok) {
  // response.orderId: string
} else {
  // response.code: OrderResponseErrorCode
  // response.message: string
}

Create, Then Post

Create signed orders separately when you want to review, store, or batch them before submitting.
import { OrderSide } from "@polymarket/client";

const order = await secureClient.createLimitOrder({
  tokenId: market.outcomes.yes.tokenId!,
  side: OrderSide.BUY,
  price: 0.52,
  size: 10,
});

const response = await secureClient.postOrder(order);

if (response.ok) {
  // response.orderId: string
} else {
  // response.code: OrderResponseErrorCode
  // response.message: string
}

Position Lifecycle

Use position lifecycle methods to split collateral into outcome tokens, merge complete sets back into collateral, or redeem resolved positions. These examples assume the secure client is configured with API key authentication as shown in Trading Setup.
const handle = await secureClient.splitPosition({
  conditionId: market.conditionId!,
  amount: 1n,
});

const outcome = await handle.wait();

// outcome.transactionHash: TxHash

Wallet Operations

Use wallet operation methods for direct token movements from the authenticated wallet. These examples assume the secure client is configured with API key authentication as shown in Trading Setup.
const handle = await secureClient.transferErc20({
  amount: 1n,
  recipientAddress: "RECIPIENT_ADDRESS",
  tokenAddress: secureClient.environment.collateralToken,
});

const outcome = await handle.wait();

// outcome.transactionHash: TxHash

Order Management

Manage open orders for the authenticated wallet after placement. These examples assume orderId comes from an accepted order response.
const order = await secureClient.fetchOrder({
  orderId,
});

// order: OpenOrder

Rewards and Scoring

Use rewards methods to inspect active reward programs and scoring methods to check whether orders are eligible for scoring.
const rewards = client.listCurrentRewards();

for await (const page of rewards) {
  // page.items: CurrentReward[]
}

Account Data

Secure clients can read account-scoped data for the authenticated wallet.
const positions = secureClient.listPositions({
  market: [market.id], // Or market.conditionId
  pageSize: 10,
});

for await (const page of positions) {
  // page.items: Position[]
}

Authentication Sessions

Secure clients expose the API credentials created for the authenticated session. Store them securely if you want to reuse the session later without requiring a new authentication signature while the credentials remain valid.
const secureClient = await createSecureClient({
  wallet: "YOUR_POLYMARKET_WALLET_ADDRESS",
  signer,
});

await storage.set("polymarketCredentials", secureClient.credentials);