TypeScript SDK
@predictefy/sdk is the official TypeScript client — one typed client across all
17 venues, including PredictStreet, plus the cross-venue router, matched clusters, and
indicative price discrepancies.
The package is ESM with bundled types and supports Node >=20.19 <21 || >=22.12 (Node
22.12+ recommended). Hosted reads and normalization stay server-side; signing and funding
remain client-side.
Install
Section titled “Install”npm install @predictefy/sdkQuickstart
Section titled “Quickstart”import Predictefy from '@predictefy/sdk';
const client = new Predictefy({ apiKey: process.env.PREDICTEFY_API_KEY });const markets = await client.polymarket.fetchMarkets({ limit: 5, query: 'fed' });console.log( markets.map((m) => m.title), markets.page?.total,);One normalized method family with familiar exchange-style names; each venue serves only the capabilities it supports:
await client.kalshi.fetchOrderBook({ outcomeId: 'KXFED-26MAR-T4.00' });await client.exchange('hyperliquid').fetchTrades('BTC-100K');await client.router.fetchMarkets({ query: 'election', status: 'active' }); // all venuesawait client.polymarket.fetchOHLCV({ outcomeId: '123', resolution: '1h', limit: 500 });await client.fetchDiscrepancies({ live: true }); // indicative price discrepanciesawait client.router.fetchArbitrage({ contracts: 100, executableOnly: true });Pass apiKey (or set the PREDICTEFY_API_KEY environment variable). The key is sent as
Authorization: Bearer <key>, is never logged, and is redacted from every error message.
const client = new Predictefy({ apiKey: 'pk_live_…', // falls back to PREDICTEFY_API_KEY baseUrl: process.env.PREDICTEFY_API_URL, // shown in your developer dashboard retryOn429: true, // default: GETs retried once on 429; POSTs are NEVER auto-retried});Execution
Section titled “Execution”Trading uses the separate, isolated execution origin and is always an explicit opt-in:
import { Predictefy, PREDICTEFY_EXEC_BASE_URL } from '@predictefy/sdk';
const client = new Predictefy({ apiKey: process.env.PREDICTEFY_API_KEY, execBaseUrl: PREDICTEFY_EXEC_BASE_URL,});
const openOrders = await client.exec.fetchOpenOrders({ venue: 'hyperliquid' });console.log(openOrders);Every API key includes the required trade scope by default; no separate approval is
required. execBaseUrl has no implicit default, so the reads API never becomes an execution
proxy. See Trading & execution for the non-custodial signing flow,
venue status, idempotency rules, spend caps, and limitations.
Trader Intelligence
Section titled “Trader Intelligence”Trader identity is capability-qualified by venue. Supported venues expose wallet-attributed tapes, holders, leaderboards, wallet profiles, and cross-venue smart-money signals:
const tape = await client.polymarket.fetchTraderTrades('market-id', { limit: 50 });const leaders = await client.hyperliquid.fetchLeaderboard({ by: 'score', limit: 50 });const profile = await client.hyperliquid.fetchWalletProfile('0x...');const signals = await client.fetchSmartMoney({ venue: 'hyperliquid', limit: 20 });Unsupported venue/verb combinations fail honestly; the SDK does not fabricate trader identity. Scored feed rows exist only where the venue source is producing activity.
Errors
Section titled “Errors”Every request is metered against your credit balance. Errors are typed — catch
PredictefyError (the base class) and switch on the class or .code. The server’s
code and message are always preserved on the thrown error.
| Error class | HTTP | Notes |
|---|---|---|
UnauthorizedError |
401 | Missing/unknown/revoked key. |
InsufficientCreditsError |
402 | .topUpHint provides the next balance step. |
ValidationError |
400 | Bad params. |
NotFoundError |
404 | Unknown venue/record. |
NotSupportedError |
400/501 | Honest capability gap (e.g. no public trades tape). |
RateLimitedError |
429 | GETs auto-retried once unless retryOn429: false. |
PlatformUnavailableError |
503 | Temporary outage — retry with backoff. |
NetworkError |
— | Transport failure / non-envelope body. |
Every account starts with 25,000 free credits, refilled monthly. Handle insufficient credits without retrying the request, then upgrade your plan or contact support if the balance looks wrong:
import { InsufficientCreditsError } from '@predictefy/sdk';
try { await client.polymarket.fetchMarkets();} catch (err) { if (err instanceof InsufficientCreditsError) { console.error('Insufficient credits. Check the balance shown in your dashboard.'); }}Pagination
Section titled “Pagination”List verbs return the data array with page / meta / nextCursor attached. Follow
cursors manually, or let the async iterator do it:
// Manual: cursor pagination freezes the catalog snapshot from page one.let page = await client.kalshi.fetchMarkets({ limit: 100 });while (page.nextCursor) page = await client.kalshi.fetchMarkets({ limit: 100, cursor: page.nextCursor });
// Iterator: walks every page for you (defaults snapshotTTL: 0 so the cursor// chain never expires mid-walk).for await (const market of client.kalshi.iterateMarkets({ status: 'active' })) { console.log(market.title);}Surface
Section titled “Surface”fetchMarkets · fetchMarket · fetchEvents · fetchEvent · fetchSeries ·
fetchOHLCV · fetchOrderBook · fetchOrderBooks · fetchTrades ·
getExecutionPrice · getExecutionPriceDetailed (per exchange; router serves the
list verbs, fetchEvent, and the stateless execution-price calculators) — plus
fetchClusters / fetchCluster / fetchDiscrepancies ({ live: true } for the live
overlay), router-only fetchArbitrage, venue-scoped Trader Intelligence, cross-venue
fetchSmartMoney / fetchTopTraders, execution/account clients, and billing.checkout.
Public billing checkout opens with the public plans.
All responses carry honest-data fields (asOf, provenance, capabilities);
cross-venue price gaps are labeled indicative price discrepancy.