@predictions/sdk
v1.0.0
Published
Official SDK for the Synthesis prediction markets API
Maintainers
Readme
Synthesis SDK
Official JavaScript/TypeScript SDK for the Synthesis prediction markets API. Works in both Node.js and the browser.
Installation
npm install @predictions/sdkQuick Start
import Synthesis from '@predictions/sdk';
const client = new Synthesis();
// Get trending markets
const markets = await client.markets.get({ sort: 'volume', limit: 10 });
console.log(markets.data);
// Get a specific Polymarket event by slug
const market = await client.polymarket.getBySlug('will-bitcoin-reach-100k');
console.log(market.data);Configuration
// No auth needed for public data (markets, prices, news, etc.)
const client = new Synthesis();
// Project app (creates/manages headless user accounts)
const client = new Synthesis({
projectApiKey: 'sk_...', // Project secret key
});
// After creating a session for a user, set it for user-scoped calls
const session = await client.projects.createSession('account_id');
client.setSessionToken(session.data.session_id);
// Now wallet/order calls are scoped to that user
await client.wallets.get();
// Clear when done
client.clearSessionToken();All config options:
const client = new Synthesis({
baseUrl: 'https://synthesis.trade', // API base URL (default)
projectApiKey: 'sk_...', // Project secret key for project-level operations
sessionToken: 'sess_...', // Session token for user-scoped requests
timeout: 30000, // Request timeout in ms (default: 30s)
});Error Handling
All methods return ApiResponse<T>:
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
}const result = await client.markets.get();
if (!result.success) {
console.error(result.error);
return;
}
console.log(result.data);Markets
Aggregate market data across all venues.
// Get markets with filters
client.markets.get({
venue: 'polymarket', // 'polymarket' | 'kalshi' | 'all'
sort: 'volume', // 'volume' | 'liquidity' | etc.
order: 'DESC',
limit: 20,
offset: 0,
live: true,
})
// Search markets by query
client.markets.search('bitcoin')
// Batch price data
client.markets.sparklines(['token_id_1', 'token_id_2'])
client.markets.prices(['token_id_1', 'token_id_2'])
client.markets.orderbooks(['token_id_1'])
client.markets.historicalOrderbooks({ token_id: '...', interval: '1h' })
// Venue statistics
client.markets.statistics()
// Related and similar markets
client.markets.related('event-slug')
client.markets.similar({ market_id: '...', limit: 10 })
client.markets.similarPairs({ limit: 20, min_similarity: 0.8 })
// Personalized recommendations (requires session)
client.markets.recommendations({ limit: 25 })Polymarket
Polymarket-specific endpoints.
// List and lookup
client.polymarket.get({ sort: 'volume', limit: 20 })
client.polymarket.getBySlug('will-bitcoin-reach-100k')
client.polymarket.getById('0xcondition_id')
// Market data
client.polymarket.priceHistory('token_id', { interval: '1h', fidelity: 60 })
client.polymarket.statistics('token_id')
client.polymarket.trades('0xcondition_id')
// Users and leaderboard
client.polymarket.user('0xaddress')
client.polymarket.leaderboard()Note: For prices and orderbooks, use the batch endpoints on
client.markets.prices()andclient.markets.orderbooks(). Holder data is available via the data WebSocket.
Kalshi
Kalshi-specific endpoints.
// List and lookup
client.kalshi.get({ sort: 'volume', limit: 20 })
client.kalshi.getEvent('KXBTC-25')
client.kalshi.getBySlug('bitcoin-price-march')
client.kalshi.getById('KXBTC-25-T100000')
// Market data
client.kalshi.trades('KXBTC-25-T100000')
client.kalshi.holders('KXBTC-25-T100000')
client.kalshi.statistics('KXBTC-25-T100000')
client.kalshi.priceHistory('KXBTC', 'KXBTC-25-T100000')
client.kalshi.candlesticks('KXBTC', 'KXBTC-25-T100000', { interval: '1h' })
// Leaderboard and users
client.kalshi.leaderboard()
client.kalshi.user('username')Wallets
Wallet management, trading, deposits, and withdrawals. Requires a session token.
// List, create, and manage wallets
client.wallets.get()
client.wallets.reorder(['wallet_a', 'wallet_b'])
client.wallets.create('POL')
client.wallets.create('SOL')
client.wallets.update('wallet_id', { name: 'Primary', autoredeem: true })
client.wallets.delete('wallet_id')
client.wallets.export('POL', 'wallet_id', 'base64-public-key')
// Generic (cross-venue) data
client.wallets.depositAddress('POL', 'wallet_id', 'EVM')
client.wallets.balance('wallet_id')
client.wallets.positions('wallet_id')
client.wallets.orders('wallet_id')
client.wallets.transfers('wallet_id')
client.wallets.pnl('wallet_id')Polygon (Polymarket)
// Wallets and balance
client.wallets.pol.wallets()
client.wallets.pol.balance('wallet_id')
client.wallets.pol.depositAddress('wallet_id', 'EVM')
// Portfolio
client.wallets.pol.positions('wallet_id')
client.wallets.pol.orders('wallet_id')
client.wallets.pol.activeOrders('wallet_id')
client.wallets.pol.activeMarketOrders('wallet_id', '0xcondition_id')
client.wallets.pol.transfers('wallet_id')
client.wallets.pol.trades('wallet_id')
client.wallets.pol.pnl('wallet_id')
// Trading
client.wallets.pol.quote('wallet_id', { token_id: '0x...', side: 'BUY', amount: 100 })
client.wallets.pol.createOrder('wallet_id', {
token_id: '0x...', side: 'BUY', type: 'MARKET', amount: 50, units: 'USDC',
})
client.wallets.pol.createOrder('wallet_id', {
token_id: '0x...', side: 'BUY', type: 'LIMIT', price: 0.65, amount: 100,
})
client.wallets.pol.getOrder('wallet_id', 'order_id')
client.wallets.pol.updateOrder('wallet_id', 'order_id', { type: 'LIMIT', price: '0.70' })
client.wallets.pol.cancelOrder('wallet_id', 'order_id')
client.wallets.pol.cancelAllOrders('wallet_id')
// Copytrades
client.wallets.pol.getCopytrades('wallet_id')
client.wallets.pol.createCopytrade('wallet_id', { target: '0x...', mode: 'COPY', settings: {} })
client.wallets.pol.updateCopytrade('wallet_id', 'copytrade_id', { settings: {} })
client.wallets.pol.deleteCopytrade('wallet_id', 'copytrade_id')
client.wallets.pol.pauseCopytrade('wallet_id', 'copytrade_id')
client.wallets.pol.unpauseCopytrade('wallet_id', 'copytrade_id')
client.wallets.pol.getCopytradeOrders('wallet_id', 'copytrade_id')
// Mint, merge, redeem, withdraw, swap
client.wallets.pol.mint('wallet_id', { condition_id: '0x...', amount: 100 })
client.wallets.pol.merge('wallet_id', { condition_id: '0x...', amount: 100 })
client.wallets.pol.redeem('wallet_id', '0xcondition_id')
client.wallets.pol.withdraw('wallet_id', { token: 'USDC', amount: 100, address: '0x...', chain: 'POLYGON' })
client.wallets.pol.swap('wallet_id', { from: 'USDC', to: 'USDT', amount: 100 })Solana (Kalshi)
// Wallets, KYC, and balance
client.wallets.sol.wallets()
client.wallets.sol.kyc('wallet_id')
client.wallets.sol.createKyc('wallet_id')
client.wallets.sol.balance('wallet_id')
client.wallets.sol.depositAddress('wallet_id', 'SOL')
// Portfolio
client.wallets.sol.positions('wallet_id')
client.wallets.sol.orders('wallet_id')
client.wallets.sol.transfers('wallet_id')
client.wallets.sol.pnl('wallet_id')
// Trading
client.wallets.sol.quote('wallet_id', { token_id: '...', side: 'BUY', amount: 100 })
client.wallets.sol.createOrder('wallet_id', { token_id: '...', side: 'BUY', type: 'MARKET', amount: 100 })
client.wallets.sol.redeem('wallet_id', 'token_id')
client.wallets.sol.withdraw('wallet_id', { token: 'USDC', amount: 100, address: '...', chain: 'SOLANA' })Account
Manage the authenticated user's account.
// Session
client.account.session()
client.account.expireSession()
// API keys
client.account.getApiKeys()
client.account.createApiKey('my-key')
client.account.deleteApiKey('pk_...')
// Interests (for recommendations)
client.account.getInterests()
client.account.updateInterests(['crypto', 'politics', 'sports'])Projects
Manage headless accounts for your project. Requires a project API key.
// API keys
client.projects.createApiKey({ name: 'production' })
// Settings
client.projects.updateSettings({ domain: 'myapp.com' })
// Account management
client.projects.getAccounts({ limit: 50 })
client.projects.createAccount({ user_id: 'ext_123' })
client.projects.getAccount('account_id')
client.projects.updateAccountMetadata('account_id', { plan: 'pro' })
// Session management
client.projects.createSession('account_id')
client.projects.refreshSession('account_id', 'session_id')
client.projects.expireSession('account_id', 'session_id')
client.projects.expireAllSessions('account_id')
// Account API keys
client.projects.getAccountApiKeys('account_id')
client.projects.createAccountApiKey('account_id', 'key-name')
client.projects.deleteAccountApiKey('account_id', 'pk_...')News
client.news.get({ limit: 10 })
client.news.forEvent('event_id')
client.news.forMarket('market_id')Sports
client.sports.categories()
client.sports.games({ sport: 'basketball', league: 'NBA' })
client.sports.game('basketball', 'NBA', 'game_123')
client.sports.markets()
client.sports.news()WebSockets
Real-time data feeds. Works in both browser and Node.js. Supports automatic reconnection with exponential backoff and subscription replay on reconnect.
const ws = client.ws({ reconnect: true, reconnectInterval: 1000 });Orderbook
const ws = client.ws();
ws.onMessage((msg) => {
console.log('Orderbook update:', msg);
});
ws.orderbook();
ws.subscribe({ type: 'subscribe', markets: ['token_id_1', 'token_id_2'] });Trades
const ws = client.ws();
ws.onMessage((msg) => {
console.log('Trade:', msg);
});
ws.trades();
ws.subscribe({
type: 'subscribe',
venue: 'polymarket',
markets: ['token_id_1'],
offset: 0,
});Balance
const ws = client.ws();
ws.onMessage((msg) => {
console.log('Balance update:', msg);
});
ws.balance();
ws.subscribe({
type: 'subscribe',
wallets: [{ address: '0x...' }],
});Data (Holders)
const ws = client.ws();
ws.onMessage((msg) => {
console.log('Holder data:', msg);
});
ws.data();
ws.subscribe({
type: 'subscribe',
data_type: 'holder_counts',
params: { condition_ids: ['0x...'] },
});Lifecycle
const ws = client.ws();
// Multiple handlers supported
ws.onOpen(() => console.log('Connected'));
ws.onError((err) => console.error(err));
ws.onClose((code, reason) => console.log('Closed:', code));
// Remove specific handlers
const handler = (msg) => console.log(msg);
ws.onMessage(handler);
ws.offMessage(handler);
// Check connection state
console.log(ws.connected);
// Clean up
ws.clearSubscriptions();
ws.close();CLI
The CLI is a separate package:
npm install -g synthesis-cli
synthesis setupSee synthesis-cli for full CLI documentation.
TypeScript
All types are exported:
import Synthesis, {
SynthesisWebSocket,
MarketWithEvent,
Market,
MarketEvent,
Wallet,
WalletBalance,
Order,
Position,
PositionWithContext,
Transfer,
PnlPoint,
CopyTrade,
TxResult,
Trade,
Holder,
Orderbook,
CreateOrderParams,
WithdrawParams,
DepositAddress,
WebSocketMessage,
ApiResponse,
} from '@predictions/sdk';Agent / LLM Quickstart
This SDK is designed for programmatic use by AI agents and LLMs. A machine-readable tool schema is available at tools.json for use with OpenAI function calling, Anthropic tool use, LangChain, or any agent framework.
End-to-end: search → quote → trade
import Synthesis from '@predictions/sdk';
const client = new Synthesis({ projectApiKey: 'sk_...' });
// 1. Create a session for a user
const account = await client.projects.createAccount({ user_id: 'agent_1' });
const session = await client.projects.createSession(account.data.account_id);
client.setSessionToken(session.data.session_id);
// 2. Create a wallet
const wallet = await client.wallets.create('POL');
const walletId = wallet.data.wallet_id;
// 3. Search for a market
const results = await client.markets.search('bitcoin');
const market = results.data[0];
const tokenId = market.markets[0].left_token_id; // YES side
// 4. Get a quote
const quote = await client.wallets.pol.quote(walletId, {
token_id: tokenId, side: 'BUY', amount: 10
});
console.log(`Quote: ${quote.data.expected_shares} shares @ $${quote.data.avg_price}`);
// 5. Place the order
const order = await client.wallets.pol.createOrder(walletId, {
token_id: tokenId, side: 'BUY', type: 'MARKET', amount: 10
});
console.log(`Order ${order.data.order_id} placed`);
// 6. Check positions
const positions = await client.wallets.positions(walletId);
for (const p of positions.data) {
console.log(`${p.position.outcome}: ${p.position.shares} shares, PnL: $${p.position.amount_pnl}`);
}Key concepts for agents
- token_id is the universal identifier — use it for prices, orderbooks, quotes, and orders
- condition_id groups YES/NO tokens into one market (Polymarket)
- market_id is the Kalshi equivalent
- Every response has
{ success: boolean, data?, error? }— always checksuccessfirst - Positions return full context:
{ position, event, market }so agents can reason about what they hold tools.jsonin the repo root has every SDK method as a callable tool with parameter schemas
Cross-venue arbitrage
const pairs = await client.markets.similarPairs({ min_similarity: 0.8 });
for (const pair of pairs.data) {
const pmPrice = pair.polymarket.market.left_price;
const kaPrice = pair.kalshi.market.left_price;
const spread = Math.abs(pmPrice - kaPrice);
if (spread > 0.05) {
console.log(`Arb opportunity: ${pair.polymarket.event.title}`);
console.log(` Polymarket: ${pmPrice} | Kalshi: ${kaPrice} | Spread: ${spread}`);
}
}Requirements
- Node.js >= 18.0.0 (or any modern browser)
License
MIT
