@codifydoo/polymarket-apidata-client
v1.0.2
Published
TypeScript client library for Polymarket Data API (positions, trades, user activity, market statistics)
Maintainers
Readme
Polymarket Data API Client
A production-ready TypeScript client library for the Polymarket Data API (positions, trades, user activity, market statistics, and builder metrics).
Features
- 🚀 Full API Coverage - All endpoints across Health, Core, Misc, and Builders domains
- 🔒 Type Safety - Strict TypeScript types with no
any - ✅ Runtime Validation - Zod schemas for request/response validation
- 🔄 Retry Logic - Exponential backoff with jitter for resilience
- ⚡ Rate Limiting - Token bucket implementation for polite API usage
- 📖 Comprehensive Docs - JSDoc comments and runnable examples
Installation
npm install @codifydoo/polymarket-apidata-clientOr with pnpm:
pnpm add @codifydoo/polymarket-apidata-clientQuick Start
import { PolymarketDataClient } from '@codifydoo/polymarket-apidata-client';
const client = new PolymarketDataClient({
baseURL: 'https://data-api.polymarket.com',
timeoutMs: 10_000,
retries: 2,
rateLimit: { burst: 30, ratePerSec: 18 },
userAgent: 'my-app/1.0.0',
});
// Health check
const health = await client.health.check();
console.log('API Status:', health.data);
// Get positions for a user
const positions = await client.core.getPositions({
user: '0x56687bf447db6ffa42ffe2204a05edaa20f55839',
limit: 10,
});
// Get trades
const trades = await client.core.getTrades({
user: '0x56687bf447db6ffa42ffe2204a05edaa20f55839',
});
// Get open interest
const openInterest = await client.misc.getOpenInterest({
market: ['0xdd22472e552920b8438158ea7238bfadfa4f736aa4cee91a6b86c39ead110917'],
});Configuration
Client Options
interface PolymarketDataClientConfig {
baseURL?: string; // Default: 'https://data-api.polymarket.com'
timeoutMs?: number; // Default: 10_000
retries?: number; // Default: 2
rateLimit?: {
// Default: { burst: 30, ratePerSec: 18 }
// Based on Data API limits: 200 requests / 10s = 20 req/s
// Using conservative 18 req/s (180/10s) with burst allowance
burst: number;
ratePerSec: number;
};
userAgent?: string; // Default: 'polymarket-apidata-client/1.0.0'
}Examples
Basic Usage
const client = new PolymarketDataClient();Custom Configuration
const client = new PolymarketDataClient({
baseURL: 'https://data-api.polymarket.com',
timeoutMs: 15_000,
retries: 3,
rateLimit: { burst: 40, ratePerSec: 20 }, // Maximum: 200 requests / 10s
userAgent: 'my-trading-bot/1.0.0',
});API Reference
Health
client.health.check()
Check the health status of the Data API.
Returns: Promise<HealthCheckResponse>
const health = await client.health.check();
// { data: 'OK' }Core
client.core.getPositions(params)
Get current positions for a user.
Parameters:
params.user- User address (required, 0x-prefixed, 40 hex chars)params.market?- Comma-separated list of condition IDsparams.eventId?- Comma-separated list of event IDsparams.limit?- Number of positions to return (default: 100, max: 500)params.offset?- Number of positions to skip (default: 0)params.sortBy?- Sort field (default: 'TOKENS')params.sortDirection?- Sort direction (default: 'DESC')
Returns: Promise<Position[]>
const positions = await client.core.getPositions({
user: '0x56687bf447db6ffa42ffe2204a05edaa20f55839',
limit: 10,
});client.core.getTrades(params)
Get trades for a user or markets.
Parameters:
params.user?- User addressparams.market?- Comma-separated list of condition IDsparams.limit?- Number of trades to returnparams.offset?- Number of trades to skip
Returns: Promise<Trade[]>
const trades = await client.core.getTrades({
user: '0x56687bf447db6ffa42ffe2204a05edaa20f55839',
});client.core.getUserActivity(params)
Get user activity.
Parameters:
params.user- User address (required)params.limit?- Number of activities to returnparams.offset?- Number of activities to skip
Returns: Promise<UserActivity[]>
client.core.getTopHolders(params)
Get top holders for markets.
Parameters:
params.market- Array of condition IDs (required)params.limit?- Number of holders to return
Returns: Promise<TopHolder[]>
client.core.getTotalValue(params)
Get total value of a user's positions.
Parameters:
params.user- User address (required)
Returns: Promise<TotalValue>
client.core.getClosedPositions(params)
Get closed positions for a user.
Parameters:
params.user- User address (required)params.market?- Array of condition IDsparams.eventId?- Array of event IDsparams.limit?- Number of positions to returnparams.offset?- Number of positions to skip
Returns: Promise<ClosedPosition[]>
Misc
client.misc.getTotalMarketsTraded(params)
Get total markets a user has traded.
Parameters:
params.user- User address (required)
Returns: Promise<TotalMarketsTraded>
client.misc.getOpenInterest(params)
Get open interest for markets.
Parameters:
params.market- Array of condition IDs (required)
Returns: Promise<OpenInterest[]>
client.misc.getLiveVolume(params)
Get live volume for an event.
Parameters:
params.eventId- Event ID (required)
Returns: Promise<LiveVolume>
Builders
client.builders.getAggregatedLeaderboard(params?)
Get aggregated builder leaderboard.
Parameters:
params.limit?- Number of entries to returnparams.offset?- Number of entries to skipparams.period?- Time period (e.g., 'daily', 'weekly', 'all-time')
Returns: Promise<BuilderLeaderboardEntry[]>
client.builders.getDailyVolumeSeries(params?)
Get daily builder volume time series.
Parameters:
params.builder?- Builder addressparams.startDate?- Start date (ISO date string)params.endDate?- End date (ISO date string)params.limit?- Number of entries to returnparams.offset?- Number of entries to skip
Returns: Promise<DailyVolumeSeries[]>
Error Handling
The client provides comprehensive error handling:
try {
const positions = await client.core.getPositions({
user: '0x56687bf447db6ffa42ffe2204a05edaa20f55839',
});
} catch (error) {
if (error instanceof Error) {
console.error('API Error:', error.message);
}
}Common Error Scenarios
Network Errors
try {
const result = await client.core.getPositions({ user: '0x...' });
} catch (error) {
// Network errors are automatically retried with exponential backoff
console.error('Request failed after retries:', error.message);
}Validation Errors
try {
const result = await client.core.getPositions({ user: 'invalid-address' });
} catch (error) {
// Zod validation error
console.error('Validation error:', error.message);
}Rate Limiting
// The client automatically handles rate limiting
// Requests are queued and executed at the configured rate
const promises = Array(100)
.fill(null)
.map(() => client.core.getPositions({ user: '0x...' }));
await Promise.all(promises); // Will be rate-limited automaticallyRate Limiting
The client implements a token bucket rate limiter. Default limits are based on Polymarket Data API rate limits:
- General endpoints: 200 requests / 10s (default: 18 req/s = 180/10s, conservative)
- /trades endpoint: 75 requests / 10s (7.5 req/s)
- Health check: 10 requests / 10s (1 req/s)
const client = new PolymarketDataClient({
rateLimit: {
burst: 30, // Allow up to 30 requests immediately
ratePerSec: 18, // Then limit to 18 requests per second (180/10s, under 200/10s limit)
},
});
// These requests will be rate-limited automatically
const promises = Array(200)
.fill(null)
.map(() => client.core.getPositions({ user: '0x...' }));
await Promise.all(promises);Best Practices
1. Error Handling
Always wrap API calls in try-catch blocks:
try {
const result = await client.core.getPositions({ user: '0x...' });
// Process result
} catch (error) {
// Handle error appropriately
console.error('Failed to fetch positions:', error.message);
}2. Pagination
Use pagination to avoid loading too much data at once:
async function getAllPositions(user: string) {
const allPositions = [];
let offset = 0;
const limit = 100;
while (true) {
const positions = await client.core.getPositions({
user,
limit,
offset,
});
allPositions.push(...positions);
if (positions.length < limit) break;
offset += limit;
}
return allPositions;
}3. Rate Limiting
Configure appropriate rate limits for your use case:
const client = new PolymarketDataClient({
rateLimit: {
burst: 10, // Conservative burst
ratePerSec: 10, // Conservative rate (100/10s, well under 200/10s limit)
},
});4. Type Safety
Use TypeScript strict mode and leverage the provided types:
import { Position, GetPositionsParams } from '@codifydoo/polymarket-apidata-client';
async function processPositions(params: GetPositionsParams): Promise<Position[]> {
const positions = await client.core.getPositions(params);
return positions;
}Troubleshooting
Common Issues
1. Network Timeouts
const client = new PolymarketDataClient({
timeoutMs: 30_000, // Increase timeout for slow connections
});2. Rate Limiting
const client = new PolymarketDataClient({
rateLimit: {
burst: 1, // Reduce burst
ratePerSec: 1, // Reduce rate
},
});3. Validation Errors
Check the error message for specific validation issues:
try {
await client.core.getPositions({ user: 'invalid-address' });
} catch (error) {
console.error('Validation error:', error.message);
// Look for specific field validation errors
}Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
