Official TypeScript SDK for the Polymarket US API.
npm install polymarket-usimport { PolymarketUS } from 'polymarket-us';
const client = new PolymarketUS();
// Get events with pagination
const events = await client.events.list({ limit: 10, offset: 0, active: true });
const nextPage = await client.events.list({ limit: 10, offset: 10, active: true });
// Get a specific event
const event = await client.events.retrieve(123);
const eventBySlug = await client.events.retrieveBySlug('super-bowl-2025');
// Get markets
const markets = await client.markets.list();
const market = await client.markets.retrieveBySlug('btc-100k');
// Get order book
const book = await client.markets.book('btc-100k');
// Get best bid/offer
const bbo = await client.markets.bbo('btc-100k');
// Search
const results = await client.search.query({ query: 'bitcoin' });
// Series and sports
const series = await client.series.list();
const sports = await client.sports.list();import { PolymarketUS } from 'polymarket-us';
const client = new PolymarketUS({
keyId: process.env.POLYMARKET_KEY_ID,
secretKey: process.env.POLYMARKET_SECRET_KEY,
});
// Create an order
const order = await client.orders.create({
marketSlug: 'btc-100k-2025',
intent: 'ORDER_INTENT_BUY_LONG',
type: 'ORDER_TYPE_LIMIT',
price: { value: '0.55', currency: 'USD' },
quantity: 100,
tif: 'TIME_IN_FORCE_GOOD_TILL_CANCEL',
});
// Get open orders
const openOrders = await client.orders.list();
// Cancel an order
await client.orders.cancel(order.id, { marketSlug: 'btc-100k-2025' });
// Cancel all orders
await client.orders.cancelAll();
// Get positions
const positions = await client.portfolio.positions();
// Get activity history
const activities = await client.portfolio.activities();
// Get account balances
const balances = await client.account.balances();Polymarket US uses Ed25519 signature authentication. Generate API keys at polymarket.us/developer.
The SDK automatically signs requests with your credentials:
const client = new PolymarketUS({
keyId: 'your-api-key-id', // UUID
secretKey: 'your-secret-key', // Base64-encoded Ed25519 private key
});import {
PolymarketUS,
AuthenticationError,
BadRequestError,
NotFoundError,
RateLimitError,
} from 'polymarket-us';
try {
await client.orders.create({ ... });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid credentials');
} else if (error instanceof BadRequestError) {
console.error('Invalid order parameters');
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded, retry later');
} else if (error instanceof NotFoundError) {
console.error('Resource not found');
}
}const client = new PolymarketUS({
keyId: 'your-key-id',
secretKey: 'your-secret-key',
timeout: 30000, // Request timeout in ms (default: 30000)
});subscribeOrders() subscribes to live order updates. Request a one-shot snapshot
of open orders separately with SUBSCRIPTION_TYPE_ORDER_SNAPSHOT and its own
request ID.
import { PolymarketUS, WebSocketError } from 'polymarket-us';
const client = new PolymarketUS({
keyId: process.env.POLYMARKET_KEY_ID,
secretKey: process.env.POLYMARKET_SECRET_KEY,
});
// Private WebSocket (orders, positions, balances, RFQs)
const privateWs = client.ws.private();
privateWs.on('orderSnapshot', (data) => {
console.log('Open orders:', data.orderSubscriptionSnapshot.orders);
});
privateWs.on('orderUpdate', (data) => {
console.log('Order execution:', data.orderSubscriptionUpdate.execution);
});
privateWs.on('positionUpdate', (data) => {
if ('positionSubscription' in data) {
const { beforePosition, afterPosition } = data.positionSubscription;
console.log('Position changed:', beforePosition, afterPosition);
}
});
privateWs.on('accountBalanceSnapshot', (data) => {
if ('accountBalancesSnapshot' in data) {
console.log('Balances:', data.accountBalancesSnapshot.balances);
}
});
privateWs.on('accountBalanceUpdate', (data) => {
if ('accountBalancesUpdate' in data) {
const change = data.accountBalancesUpdate.balanceChange;
console.log('Balance changed:', change.afterBalance?.buyingPower);
}
});
privateWs.on('error', (error) => {
console.error('WebSocket error:', error);
if (error instanceof WebSocketError) {
console.error(
'Subscription context:',
error.requestId,
error.subscriptionType,
);
}
});
privateWs.on('rfqEvent', (data) => {
const quote = data.rfqEvent.quoteCreated?.quote;
if (quote) console.log('Quote created:', quote.id, quote.buyPrice);
});
await privateWs.connect();
privateWs.subscribeOrders('order-sub-1');
privateWs.subscribe('order-snapshot-1', 'SUBSCRIPTION_TYPE_ORDER_SNAPSHOT');
privateWs.subscribePositions('pos-sub-1');
privateWs.subscribeAccountBalance('balance-sub-1');
privateWs.subscribeRFQ('rfq-sub-1');
// Markets WebSocket (order book, trades)
const marketsWs = client.ws.markets();
marketsWs.on('marketData', (data) => {
console.log('Order book:', data.marketData.bids, data.marketData.offers);
});
marketsWs.on('trade', (data) => {
console.log('Trade:', data.trade);
});
await marketsWs.connect();
marketsWs.subscribeMarketData('md-sub-1', ['btc-100k-2025']);
marketsWs.subscribeTrades('trade-sub-1', ['btc-100k-2025']);
// Unsubscribe and close
marketsWs.unsubscribe('md-sub-1');
marketsWs.close();Position and balance updates now reach positionUpdate and
accountBalanceUpdate. The SDK forwards each original message without renaming
its fields. Read positions from positionSubscription.beforePosition and
afterPosition, balances from accountBalancesSnapshot.balances, and balance
changes from accountBalancesUpdate.balanceChange.
Position quantities are available as exact decimal strings such as
netPositionDecimal, alongside cost/fee fields and comboLegDetails. Balance
reservation and display fields, such as displayedCash, are absent when the
gateway cannot determine them; a present 0 is distinct from an absent value.
These corrected declarations are a breaking type change in 2.0.0. The previous
positionSubscriptionUpdate, positionUpdate,
accountBalanceSubscriptionSnapshot, accountBalanceSubscriptionUpdate, and
accountBalanceUpdate aliases still dispatch unchanged; their types are exported
as LegacyPositionUpdate, LegacyAccountBalanceSnapshot, and
LegacyAccountBalanceUpdate. Narrow by the envelope key as above. Before/after
positions and balances, timestamps, position cost, cash value, and market
metadata can be null.
Position subscriptions deliver changes without an initial snapshot. Use
client.portfolio.positions() for current positions; the legacy
positionSnapshot callback remains available for older messages.
| Method | Description |
|---|---|
events.list(params?) |
List events with filtering |
events.retrieve(id) |
Get event by ID |
events.retrieveBySlug(slug) |
Get event by slug |
| Method | Description |
|---|---|
markets.list(params?) |
List markets with filtering |
markets.retrieve(id) |
Get market by ID |
markets.retrieveBySlug(slug) |
Get market by slug |
markets.book(slug) |
Get order book |
markets.bbo(slug) |
Get best bid/offer |
markets.settlement(slug) |
Get settlement price |
The corrected declarations match the existing API responses; runtime behavior is
unchanged. Read book and BBO fields through marketData:
const { marketData: book } = await client.markets.book('btc-100k');
const { marketData: bbo } = await client.markets.bbo('btc-100k');
console.log(book.bids, bbo.bestBid?.value);
const { slug, settlement } = await client.markets.settlement('btc-100k');
console.log(slug, settlement);Settlement uses slug and numeric settlement, replacing the old
marketSlug, settlementPrice, and settledAt declarations. Book stats and
transactTime, and BBO bestBid, bestAsk, and lastTradePx, can be null.
| Method | Description |
|---|---|
orders.create(params) |
Create a new order |
orders.list(params?) |
Get open orders |
orders.retrieve(orderId) |
Get order by ID |
orders.cancel(orderId, params) |
Cancel an order |
orders.modify(orderId, params) |
Modify an order |
orders.cancelAll(params?) |
Cancel all open orders |
orders.preview(params) |
Preview an order |
orders.closePosition(params) |
Close a position |
| Method | Description |
|---|---|
portfolio.positions(params?) |
Get trading positions |
portfolio.activities(params?) |
Get activity history |
Activity trades expose qtyDecimal as an exact decimal string alongside the
legacy qty field. Import PortfolioTrade for this type; Trade describes
market WebSocket trade messages.
| Method | Description |
|---|---|
account.balances() |
Get account balances |
| Method | Description |
|---|---|
series.list(params?) |
List series |
series.retrieve(id) |
Get series by ID |
| Method | Description |
|---|---|
sports.list() |
List sports |
sports.teams(params?) |
Get teams for provider |
| Method | Description |
|---|---|
search.query(params?) |
Search events (includes nested markets) |
| Method | Description |
|---|---|
ws.private() |
Create private WebSocket connection |
ws.markets() |
Create markets WebSocket connection |
Private WebSocket Events:
orderSnapshot- Initial orders snapshotorderUpdate- Order execution updatespositionSnapshot- Legacy snapshot event; the current gateway sends no position snapshotpositionUpdate- Position changesaccountBalanceSnapshot- Initial balanceaccountBalanceUpdate- Balance changesrfqEvent- RFQ and quote lifecycle eventsheartbeat- Connection keepaliveerror- Error eventsclose- Connection closed
Markets WebSocket Events:
marketData- Full order book updatesmarketDataLite- Lightweight price datatrade- Trade notificationsheartbeat- Connection keepaliveerror- Error eventsclose- Connection closed
- Node.js 18+
- For WebSocket support on Node.js < 22, install the
wspackage:
npm install wsMIT