GuidesCookbook
Alert on scored trades
The smart-money feed is a scored-trade feed. It ranks trades that have already happened; it is informational and is not a recommendation, and treating a score as a signal to copy is a misreading of what it measures.
Trader Intelligence is the reference. This page builds a watcher.
curl -s "$PREDICTEFY_API_URL/v1/traders/smart-money?minScore=80&window=day&limit=100" \ -H "Authorization: Bearer pk_live_YOUR_KEY"Every parameter is optional:
| Parameter | Values |
|---|---|
venue | One Trader Intelligence venue |
minScore | 0–100 |
market | Exact market id |
wallet | Exact venue-scoped wallet |
category | bot, whale, smart, fresh, fish |
window | day, week, month, all (default all) |
limit | 1–100 |
cursor | Opaque (ts, tradeId) keyset cursor |
Rows add tradeScore, tradeFactors, scoreVersion, walletScoreAtTrade and
categoryAtTrade to the normal trader-trade fields. Under score version t1 the factors are
walletScore, size, entry and timing.
Watch without re-alerting
Section titled “Watch without re-alerting”The feed is newest-first. Its cursor walks backward to rows older than the last row on the
current page; it is not a forward watcher checkpoint. Start every poll without a cursor, then use
the top-level nextCursor only to walk older pages until you reach the newest trade saved from the
previous poll.
let initialized = false;let newestSeen = null;
function tradeKey(trade) { return `${trade.venue}:${trade.ts}:${trade.tradeId}`;}
async function poll() { let cursor = null; let newestInPoll = null; let reachedPrevious = false; const fresh = [];
do { const url = new URL('/v1/traders/smart-money', BASE); url.searchParams.set('minScore', '80'); url.searchParams.set('window', 'day'); url.searchParams.set('limit', '100'); if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.PREDICTEFY_API_KEY}` }, }); const body = await res.json();
if (!body.success) { // TRADERS_UNSUPPORTED is a 400 and is not retryable — it is an answer. if (!body.error.retryable) throw new Error(`${body.error.code}: ${body.error.message}`); return; }
if (newestInPoll === null && body.data[0]) newestInPoll = tradeKey(body.data[0]); for (const trade of body.data) { if (tradeKey(trade) === newestSeen) { reachedPrevious = true; break; } fresh.push(trade); } cursor = reachedPrevious ? null : (body.nextCursor ?? null); } while (initialized && cursor);
// The first poll establishes a baseline instead of alerting the existing feed. if (!initialized) { initialized = true; newestSeen = newestInPoll; return; }
for (const trade of fresh.reverse()) alert(trade); if (newestInPoll !== null) newestSeen = newestInPoll;}Persist newestSeen across process restarts and keep the filter set unchanged. Reusing a backward
cursor on the next poll skips trades that arrived after that cursor was minted; restarting from the
newest page and stopping at the saved trade avoids both misses and duplicate alerts.
Reading the score honestly
Section titled “Reading the score honestly”window=allmeans all collected feed data. No historical backfill is included — the feed starts when collection started, so an empty early window is a collection boundary, not a quiet market.walletScoreAtTradeandcategoryAtTradeare the values as they were at the time of the trade, not the wallet’s current standing. Rendering a current score next to a historical trade attributes information to the trader that they did not have.scoreVersionmatters. Factors differ between versions, so scores are not comparable across them. Store the version with anything you persist.- A listed capability is not a claim that rows exist. Scored-trade coverage requires activity from that venue; a supported venue can legitimately return nothing.
The errors are answers
Section titled “The errors are answers”| Response | Meaning |
|---|---|
400 TRADERS_UNSUPPORTED | That venue does not support that verb. Not retryable. |
404 TRADER_NOT_FOUND | Unknown wallet. |
404 on any /v1/traders/* | Trader Intelligence is unavailable. |
TRADERS_UNSUPPORTED names the verb and the venue — for example, market holders being
unsupported on a given venue. Do not fall back to another venue’s data to fill the gap; the
honest render is that this venue does not expose it. See
Capability-honest data.
Through an agent instead
Section titled “Through an agent instead”The same surface is available as MCP tools — get_smart_money, get_market_traders,
get_market_holders, get_leaderboard, get_wallet_profile — each capped at 100 rows, with
get_wallet_profile under a 50 KB response budget. See MCP server.
Related
Section titled “Related”- Trader Intelligence — every route, parameter and venue capability
- MCP server — the same data as agent tools
- Capability-honest data — why an unsupported verb is an answer