Guides / API Guide
A working Node/TypeScript client for the ProbSights API: find a market, pull its orderbook history, and page to the end correctly.
const BASE = "https://api.probsights.com/v1";
async function get(path, params = {}) {
const qs = new URLSearchParams(
Object.entries(params).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]),
);
const res = await fetch(`${BASE}${path}?${qs}`, {
headers: { Authorization: `Bearer ${process.env.PROBSIGHTS_API_KEY}` },
});
if (!res.ok) {
// Errors are { message, status } — surface the message, not the status code.
const body = await res.json().catch(() => ({}));
throw new Error(body.message ?? `Request failed (${res.status})`);
}
return res.json();
}
Keep the key server-side. In a browser bundle it is readable by anyone who loads the page.
// "q" or "series_id" is required; omitting both is a 400.
const markets = await get("/search/markets", {
q: "bitcoin", status: "active", sort_by: "volume", limit: 5,
});
const marketId = markets[0].market_id;
// Date.parse gives MILLISECONDS; the API wants seconds.
const unix = (iso) => Math.floor(Date.parse(iso) / 1000);
async function* orderbookHistory(venue, marketId, startIso, endIso, granularity = "1m") {
const params = {
market_id: marketId,
start_time: unix(startIso),
end_time: unix(endIso),
granularity,
limit: 1000,
};
for (;;) {
const res = await get(`/historical/${venue}/orderbook`, params);
yield* res.snapshots;
if (!res.pagination?.has_more) return;
// Follow the cursor rather than advancing start_time, which would drop or
// duplicate rows sharing a timestamp.
params.pagination_key = res.pagination.pagination_key;
}
}
const snapshots = [];
for await (const s of orderbookHistory(
"polymarket", marketId, "2025-01-20T00:00:00Z", "2025-01-21T00:00:00Z",
)) {
snapshots.push(s);
}
console.log(snapshots.length, snapshots[0]?.mid, snapshots[0]?.spread);
const { trades } = await get("/historical/polymarket/trades", {
market_id: marketId,
start_time: unix("2025-01-20T00:00:00Z"),
end_time: unix("2025-01-21T00:00:00Z"),
limit: 1000,
});
Kalshi is the same shape — swap polymarket for kalshi; its
snapshots expose yes_bids/no_bids instead of
bids/asks.
Data from Kalshi and Polymarket. Search live API docs Pricing