Skip to content
Get an API key

@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.

Terminal window
npm install @predictefy/sdk
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 venues
await client.polymarket.fetchOHLCV({ outcomeId: '123', resolution: '1h', limit: 500 });
await client.fetchDiscrepancies({ live: true }); // indicative price discrepancies
await 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
});

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 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.

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.');
}
}

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);
}

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.