Webhook events
Every event Polywhaler can POST to your endpoint, what its data holds, and how to check that a delivery really came from us. Webhooks are part of the Quant plan; this page is open to everyone.
How delivery works#
Add an endpoint in the Developer portal (or with POST /v2/webhook-endpoints): an https URL on a public address, the event types it wants, and optional filters. Each event is then sent as one JSON POST.
- Answer with any
2xxwithin 10 seconds. Anything else, including a timeout, is retried after 30 seconds, 2 minutes, 10 minutes, 1 hour, 3 hours, 6 hours and 12 hours, with some jitter: 8 attempts over about a day. A429or503withRetry-Afteris honoured up to an hour. - Redirects are never followed, and a URL that resolves to a private, loopback or cloud-metadata address is refused; neither is retried.
- Every retry and every redelivery carries the same
webhook-id, so store the ids you have handled and skip repeats. Deliveries can arrive out of order. - An endpoint that keeps failing (at least 10 failures in a row spread over more than three days, with no success since) or that answers
410 Gonetwice an hour apart is disabled, and you get an email. Re-enable it in the portal and use Recover failed deliveries… to resend what it missed.
The event envelope#
Every body has the same envelope. data is the resource the type names, in the same shape the REST API returns it, so one parser serves both.
- idstring
The event id,
evt_…: the same on every endpoint the event went to. - type"trade.whale"
- apiVersion"v2"
- createdAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- testboolean
True on test sends (POST /v2/webhook-endpoints/{id}/test).
- dataTrade
One whale fill ($10k+ on Polymarket; Kalshi uses its own floors).
Three headers come with it:
webhook-id: the delivery id,msg_…. The same on every attempt.webhook-timestamp: when this attempt was signed, in Unix seconds.webhook-signature:v1,<base64>, space-separated. While a secret is being rotated there are two, one per live secret; accept the delivery if either matches.
Verifying signatures#
Deliveries are signed to the Standard Webhooks spec: an HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{raw body}, keyed with the bytes your whsec_ secret encodes in base64 after the prefix. Reject a timestamp more than 5 minutes from your clock, so a captured delivery cannot be replayed later. The standardwebhooks libraries for Node and Python do all of this; the hand-written versions below do the same with no dependency.
The secret is shown once, when the endpoint is created. Rotate secret issues a new one and keeps the old one signing beside it for 24 hours by default, so you can deploy the new secret without dropping a delivery.
Node.js#
Python#
Filters#
Filters narrow what an endpoint receives: every key must match (AND), and a list matches any of its values (OR). A filter only applies to the types listed beside it, and an endpoint may not set one that applies to none of its types (400 filter_not_applicable). Numbers must be JSON numbers.
Trades on these venues only.
- minAmounttrade.whaletrade.smart_moneytrade.followed_wallettrade.insider_flaggedtrade.vindicatedconsensus.detected
Trades (and consensus groups) of at least this many US dollars.
Trades in these market categories only.
- sidestrade.whaletrade.smart_moneytrade.followed_wallettrade.insider_flaggedtrade.vindicatedconsensus.detected
Taker side: BUY, SELL or both.
- minInsiderScoretrade.whaletrade.smart_moneytrade.followed_wallettrade.insider_flaggedtrade.vindicated
Trades whose insider score is at least this (unscored trades never match).
- maxRanktrade.smart_money
trade.smart_money: wallets ranked this high or better. Default 100.
- minScoretrade.smart_money
trade.smart_money: wallets whose Smart Money Score is at least this.
- walletstrade.whaletrade.smart_moneytrade.followed_wallettrade.insider_flaggedtrade.vindicatedwallet.rank_changedwallet.score_changed
These wallets only (trade.* and wallet.*).
- walletScopewallet.rank_changedwallet.score_changed
wallet.*: your watchlist, the top 100, or both (default both).
- minRankDeltawallet.rank_changed
wallet.rank_changed: moves of at least this many places (default 10). Entering or leaving the top 100 always counts.
- minScoreDeltawallet.score_changed
wallet.score_changed: changes of at least this many points (default 5).
- minConfidencecluster.detected
cluster.detected: detection confidence of at least this (0..1).
- minWhalesconsensus.detected
consensus.detected: at least this many of your wallets.
v1 endpoints#
Endpoints created before v2 keep working as they did until v1 is retired: the nine v1 event names, a pwsk_ secret, the X-Polywhaler-Signature: sha256=<hex> header (an HMAC of the body alone, with no timestamp), and 5 attempts. Each v2 event below names the v1 event it is also sent as, where there is one.
- Open the v1 endpoint in the portal and choose Upgrade to v2. That creates a v2 endpoint on the same URL with the v1 events mapped to their v2 types, the filters in v2 form and a new
whsec_secret, shown once. - Deploy the Standard Webhooks check with the new secret. Until you switch v1 off, each event arrives on both endpoints with the same event id (
X-Polywhaler-Event-Idon v1, the envelopeidon v2), so drop the duplicate by that id. - Disable or delete the v1 endpoint.
Note
Trade events#
trade.whale#
A whale fill
A new fill of $10,000 or more on Polymarket, or a Kalshi fill over its whale floor. data is the trade as GET /v2/trades/{id} returns it.
Filters:venuesminAmountcategoriessidesminInsiderScorewallets
Show the payloadHide the payload53 fields
- idstring
Trade id: the transaction hash on Polymarket,
kx_<tradeId>on Kalshi. Use with GET /v2/trades/{id}. - sideenum
Taker side of the fill.
One of
BUYSELL - outcomestring | null
The outcome bought or sold, e.g.
Yes. - outcomeIndexinteger | null
- priceProbabilitynumber
Fill price, which is the implied probability of
outcome. - sizeSharesnumber
Shares (Polymarket) or contracts (Kalshi) filled.
- amountUsdnumber
Notional of the fill: sizeShares × priceProbability.
- tradedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- marketobject
The market the trade was in.
- market.titlestring | null
The market's question.
- market.eventSlugstring | null
Polymarket event slug, or the Kalshi event ticker.
- market.marketSlugstring | null
Polymarket market slug, or the Kalshi market ticker.
- market.conditionIdstring | null
Polymarket condition id. Null on Kalshi.
- market.assetstring | null
Polymarket outcome token id. Null on Kalshi.
- market.tickerstring | null
Kalshi market ticker. Null on Polymarket.
- market.iconstring | null
- market.categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - market.tagsany[]
Polymarket event tags, as Polymarket returns them.
- market.endsAtstring (date-time) | null
Scheduled end of the market, when known.
- venue"polymarket" | "kalshi"
- transactionHashstring | null
An on-chain transaction hash, lowercase.
- walletstring | null
A Polygon wallet address, always lowercase.
- traderobject
Display identity of the wallet's Polymarket account.
- trader.namestring | null
Polymarket display name, when set.
- trader.pseudonymstring | null
Polymarket's generated pseudonym.
- trader.imagestring | null
Profile image URL.
- insiderobject | null
- insider.scorenumber | null
Insider-risk score, 0..100: above 40 is medium, above 70 high. Null when the trade has not been scored (only Polymarket buys are).
- insider.breakdownobject
The insider score's factors, in points. Each factor is capped, and together they add up to
score, which is capped at 100 (sports trades are capped lower, below the high band). - insider.breakdown.convictionnumber | null
A large position at long odds. Points, at most 35.
- insider.breakdown.priceImpactnumber | null
How far the trade moved the price. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.tradeSizenumber | null
The trade's size on its own. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.marketDominancenumber | null
The trade's size against the market's trading over the previous 24 hours. Points, at most 20.
- insider.breakdown.timingnumber | null
How close to the market's resolution the trade came, or a large early position on a distant event. Points, at most 10.
- insider.breakdown.walletAgenumber | null
How new the wallet was when it traded. Points, at most 15.
- insider.breakdown.contextnumber | null
How much the market's kind of event lends itself to inside knowledge. Points, at most 20.
- insider.detailsobject | null
The full scoring record (GET /v2/trades/{id} only). Its fields may grow; treat it as informational.
- smartMoneyobject | null
Present with include=smartMoney: null when the wallet is not on the board.
- smartMoney.rankinteger | null
The wallet's Smart Money rank (1 = best), null while provisional.
- smartMoney.scorenumber
The wallet's smoothed Smart Money Score.
- smartMoney.tierenum
Badge band: genius 80+ (methodology 4 also needs a minimum of realized edge in dollars), smart 60+, average 40+, naive below.
- smartMoney.styleenum | null
Trading style; null under methodology 3, which has none.
One of
long-shotbalancedfavoriteunknown - smartMoney.methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- resolutionobject | null
- resolution.statusenum
One of
winlosspendingcancelledinvalid - resolution.winningOutcomestring | null
- resolution.entryPricenumber | null
- resolution.exitPricenumber | null
- resolution.pnlUsdnumber | null
- resolution.roinumber | null
- resolution.resolvedAtstring (date-time) | null
- resolution.holdSecondsinteger | null
- resolution.vindicatedboolean
A high-insider-score trade that won.
trade.smart_money#
A fill by a top Smart Money wallet
A whale fill by a wallet ranked on the Smart Money board (by default the top 100; set maxRank). Polymarket only. data is the trade with the wallet's standing.
Filters:venuesminAmountcategoriessidesminInsiderScoremaxRankminScorewallets
Show the payloadHide the payload53 fields
- idstring
Trade id: the transaction hash on Polymarket,
kx_<tradeId>on Kalshi. Use with GET /v2/trades/{id}. - sideenum
Taker side of the fill.
One of
BUYSELL - outcomestring | null
The outcome bought or sold, e.g.
Yes. - outcomeIndexinteger | null
- priceProbabilitynumber
Fill price, which is the implied probability of
outcome. - sizeSharesnumber
Shares (Polymarket) or contracts (Kalshi) filled.
- amountUsdnumber
Notional of the fill: sizeShares × priceProbability.
- tradedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- marketobject
The market the trade was in.
- market.titlestring | null
The market's question.
- market.eventSlugstring | null
Polymarket event slug, or the Kalshi event ticker.
- market.marketSlugstring | null
Polymarket market slug, or the Kalshi market ticker.
- market.conditionIdstring | null
Polymarket condition id. Null on Kalshi.
- market.assetstring | null
Polymarket outcome token id. Null on Kalshi.
- market.tickerstring | null
Kalshi market ticker. Null on Polymarket.
- market.iconstring | null
- market.categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - market.tagsany[]
Polymarket event tags, as Polymarket returns them.
- market.endsAtstring (date-time) | null
Scheduled end of the market, when known.
- venue"polymarket"
- transactionHashstring
An on-chain transaction hash, lowercase.
- walletstring
A Polygon wallet address, always lowercase.
- traderobject
Display identity of the wallet's Polymarket account.
- trader.namestring | null
Polymarket display name, when set.
- trader.pseudonymstring | null
Polymarket's generated pseudonym.
- trader.imagestring | null
Profile image URL.
- insiderobject | null
- insider.scorenumber | null
Insider-risk score, 0..100: above 40 is medium, above 70 high. Null when the trade has not been scored (only Polymarket buys are).
- insider.breakdownobject
The insider score's factors, in points. Each factor is capped, and together they add up to
score, which is capped at 100 (sports trades are capped lower, below the high band). - insider.breakdown.convictionnumber | null
A large position at long odds. Points, at most 35.
- insider.breakdown.priceImpactnumber | null
How far the trade moved the price. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.tradeSizenumber | null
The trade's size on its own. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.marketDominancenumber | null
The trade's size against the market's trading over the previous 24 hours. Points, at most 20.
- insider.breakdown.timingnumber | null
How close to the market's resolution the trade came, or a large early position on a distant event. Points, at most 10.
- insider.breakdown.walletAgenumber | null
How new the wallet was when it traded. Points, at most 15.
- insider.breakdown.contextnumber | null
How much the market's kind of event lends itself to inside knowledge. Points, at most 20.
- insider.detailsobject | null
The full scoring record (GET /v2/trades/{id} only). Its fields may grow; treat it as informational.
- smartMoneyobject
The trading wallet's Smart Money standing at request time.
- smartMoney.rankinteger | null
The wallet's Smart Money rank (1 = best), null while provisional.
- smartMoney.scorenumber
The wallet's smoothed Smart Money Score.
- smartMoney.tierenum
Badge band: genius 80+ (methodology 4 also needs a minimum of realized edge in dollars), smart 60+, average 40+, naive below.
- smartMoney.styleenum | null
Trading style; null under methodology 3, which has none.
One of
long-shotbalancedfavoriteunknown - smartMoney.methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- resolutionobject | null
- resolution.statusenum
One of
winlosspendingcancelledinvalid - resolution.winningOutcomestring | null
- resolution.entryPricenumber | null
- resolution.exitPricenumber | null
- resolution.pnlUsdnumber | null
- resolution.roinumber | null
- resolution.resolvedAtstring (date-time) | null
- resolution.holdSecondsinteger | null
- resolution.vindicatedboolean
A high-insider-score trade that won.
trade.followed_wallet#
A fill by a wallet on your watchlist
A new fill by a wallet you follow. Sent only to your own endpoints.
Filters:minAmountcategoriessidesminInsiderScorewallets
Show the payloadHide the payload53 fields
- idstring
Trade id: the transaction hash on Polymarket,
kx_<tradeId>on Kalshi. Use with GET /v2/trades/{id}. - sideenum
Taker side of the fill.
One of
BUYSELL - outcomestring | null
The outcome bought or sold, e.g.
Yes. - outcomeIndexinteger | null
- priceProbabilitynumber
Fill price, which is the implied probability of
outcome. - sizeSharesnumber
Shares (Polymarket) or contracts (Kalshi) filled.
- amountUsdnumber
Notional of the fill: sizeShares × priceProbability.
- tradedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- marketobject
The market the trade was in.
- market.titlestring | null
The market's question.
- market.eventSlugstring | null
Polymarket event slug, or the Kalshi event ticker.
- market.marketSlugstring | null
Polymarket market slug, or the Kalshi market ticker.
- market.conditionIdstring | null
Polymarket condition id. Null on Kalshi.
- market.assetstring | null
Polymarket outcome token id. Null on Kalshi.
- market.tickerstring | null
Kalshi market ticker. Null on Polymarket.
- market.iconstring | null
- market.categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - market.tagsany[]
Polymarket event tags, as Polymarket returns them.
- market.endsAtstring (date-time) | null
Scheduled end of the market, when known.
- venue"polymarket" | "kalshi"
- transactionHashstring | null
An on-chain transaction hash, lowercase.
- walletstring | null
A Polygon wallet address, always lowercase.
- traderobject
Display identity of the wallet's Polymarket account.
- trader.namestring | null
Polymarket display name, when set.
- trader.pseudonymstring | null
Polymarket's generated pseudonym.
- trader.imagestring | null
Profile image URL.
- insiderobject | null
- insider.scorenumber | null
Insider-risk score, 0..100: above 40 is medium, above 70 high. Null when the trade has not been scored (only Polymarket buys are).
- insider.breakdownobject
The insider score's factors, in points. Each factor is capped, and together they add up to
score, which is capped at 100 (sports trades are capped lower, below the high band). - insider.breakdown.convictionnumber | null
A large position at long odds. Points, at most 35.
- insider.breakdown.priceImpactnumber | null
How far the trade moved the price. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.tradeSizenumber | null
The trade's size on its own. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.marketDominancenumber | null
The trade's size against the market's trading over the previous 24 hours. Points, at most 20.
- insider.breakdown.timingnumber | null
How close to the market's resolution the trade came, or a large early position on a distant event. Points, at most 10.
- insider.breakdown.walletAgenumber | null
How new the wallet was when it traded. Points, at most 15.
- insider.breakdown.contextnumber | null
How much the market's kind of event lends itself to inside knowledge. Points, at most 20.
- insider.detailsobject | null
The full scoring record (GET /v2/trades/{id} only). Its fields may grow; treat it as informational.
- smartMoneyobject | null
Present with include=smartMoney: null when the wallet is not on the board.
- smartMoney.rankinteger | null
The wallet's Smart Money rank (1 = best), null while provisional.
- smartMoney.scorenumber
The wallet's smoothed Smart Money Score.
- smartMoney.tierenum
Badge band: genius 80+ (methodology 4 also needs a minimum of realized edge in dollars), smart 60+, average 40+, naive below.
- smartMoney.styleenum | null
Trading style; null under methodology 3, which has none.
One of
long-shotbalancedfavoriteunknown - smartMoney.methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- resolutionobject | null
- resolution.statusenum
One of
winlosspendingcancelledinvalid - resolution.winningOutcomestring | null
- resolution.entryPricenumber | null
- resolution.exitPricenumber | null
- resolution.pnlUsdnumber | null
- resolution.roinumber | null
- resolution.resolvedAtstring (date-time) | null
- resolution.holdSecondsinteger | null
- resolution.vindicatedboolean
A high-insider-score trade that won.
trade.insider_flagged#
A fill with a high insider-risk score
A new Polymarket buy whose insider-risk score is 70 or more (only buys are scored). Badges and filters call a score high only above 70, so a fill at exactly 70 is sent here but reads as medium. (v1: trade.high_insider.)
Filters:minAmountcategoriessidesminInsiderScorewallets
Show the payloadHide the payload53 fields
- idstring
Trade id: the transaction hash on Polymarket,
kx_<tradeId>on Kalshi. Use with GET /v2/trades/{id}. - sideenum
Taker side of the fill.
One of
BUYSELL - outcomestring | null
The outcome bought or sold, e.g.
Yes. - outcomeIndexinteger | null
- priceProbabilitynumber
Fill price, which is the implied probability of
outcome. - sizeSharesnumber
Shares (Polymarket) or contracts (Kalshi) filled.
- amountUsdnumber
Notional of the fill: sizeShares × priceProbability.
- tradedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- marketobject
The market the trade was in.
- market.titlestring | null
The market's question.
- market.eventSlugstring | null
Polymarket event slug, or the Kalshi event ticker.
- market.marketSlugstring | null
Polymarket market slug, or the Kalshi market ticker.
- market.conditionIdstring | null
Polymarket condition id. Null on Kalshi.
- market.assetstring | null
Polymarket outcome token id. Null on Kalshi.
- market.tickerstring | null
Kalshi market ticker. Null on Polymarket.
- market.iconstring | null
- market.categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - market.tagsany[]
Polymarket event tags, as Polymarket returns them.
- market.endsAtstring (date-time) | null
Scheduled end of the market, when known.
- venue"polymarket" | "kalshi"
- transactionHashstring | null
An on-chain transaction hash, lowercase.
- walletstring | null
A Polygon wallet address, always lowercase.
- traderobject
Display identity of the wallet's Polymarket account.
- trader.namestring | null
Polymarket display name, when set.
- trader.pseudonymstring | null
Polymarket's generated pseudonym.
- trader.imagestring | null
Profile image URL.
- insiderobject | null
- insider.scorenumber | null
Insider-risk score, 0..100: above 40 is medium, above 70 high. Null when the trade has not been scored (only Polymarket buys are).
- insider.breakdownobject
The insider score's factors, in points. Each factor is capped, and together they add up to
score, which is capped at 100 (sports trades are capped lower, below the high band). - insider.breakdown.convictionnumber | null
A large position at long odds. Points, at most 35.
- insider.breakdown.priceImpactnumber | null
How far the trade moved the price. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.tradeSizenumber | null
The trade's size on its own. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.marketDominancenumber | null
The trade's size against the market's trading over the previous 24 hours. Points, at most 20.
- insider.breakdown.timingnumber | null
How close to the market's resolution the trade came, or a large early position on a distant event. Points, at most 10.
- insider.breakdown.walletAgenumber | null
How new the wallet was when it traded. Points, at most 15.
- insider.breakdown.contextnumber | null
How much the market's kind of event lends itself to inside knowledge. Points, at most 20.
- insider.detailsobject | null
The full scoring record (GET /v2/trades/{id} only). Its fields may grow; treat it as informational.
- smartMoneyobject | null
Present with include=smartMoney: null when the wallet is not on the board.
- smartMoney.rankinteger | null
The wallet's Smart Money rank (1 = best), null while provisional.
- smartMoney.scorenumber
The wallet's smoothed Smart Money Score.
- smartMoney.tierenum
Badge band: genius 80+ (methodology 4 also needs a minimum of realized edge in dollars), smart 60+, average 40+, naive below.
- smartMoney.styleenum | null
Trading style; null under methodology 3, which has none.
One of
long-shotbalancedfavoriteunknown - smartMoney.methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- resolutionobject | null
- resolution.statusenum
One of
winlosspendingcancelledinvalid - resolution.winningOutcomestring | null
- resolution.entryPricenumber | null
- resolution.exitPricenumber | null
- resolution.pnlUsdnumber | null
- resolution.roinumber | null
- resolution.resolvedAtstring (date-time) | null
- resolution.holdSecondsinteger | null
- resolution.vindicatedboolean
A high-insider-score trade that won.
trade.vindicated#
A flagged low-odds trade won
A high-insider-score fill bought at low odds whose market just resolved in its favour. data includes resolution.
Filters:minAmountcategoriessidesminInsiderScorewallets
Show the payloadHide the payload53 fields
- idstring
Trade id: the transaction hash on Polymarket,
kx_<tradeId>on Kalshi. Use with GET /v2/trades/{id}. - sideenum
Taker side of the fill.
One of
BUYSELL - outcomestring | null
The outcome bought or sold, e.g.
Yes. - outcomeIndexinteger | null
- priceProbabilitynumber
Fill price, which is the implied probability of
outcome. - sizeSharesnumber
Shares (Polymarket) or contracts (Kalshi) filled.
- amountUsdnumber
Notional of the fill: sizeShares × priceProbability.
- tradedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- marketobject
The market the trade was in.
- market.titlestring | null
The market's question.
- market.eventSlugstring | null
Polymarket event slug, or the Kalshi event ticker.
- market.marketSlugstring | null
Polymarket market slug, or the Kalshi market ticker.
- market.conditionIdstring | null
Polymarket condition id. Null on Kalshi.
- market.assetstring | null
Polymarket outcome token id. Null on Kalshi.
- market.tickerstring | null
Kalshi market ticker. Null on Polymarket.
- market.iconstring | null
- market.categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - market.tagsany[]
Polymarket event tags, as Polymarket returns them.
- market.endsAtstring (date-time) | null
Scheduled end of the market, when known.
- venue"polymarket" | "kalshi"
- transactionHashstring | null
An on-chain transaction hash, lowercase.
- walletstring | null
A Polygon wallet address, always lowercase.
- traderobject
Display identity of the wallet's Polymarket account.
- trader.namestring | null
Polymarket display name, when set.
- trader.pseudonymstring | null
Polymarket's generated pseudonym.
- trader.imagestring | null
Profile image URL.
- insiderobject | null
- insider.scorenumber | null
Insider-risk score, 0..100: above 40 is medium, above 70 high. Null when the trade has not been scored (only Polymarket buys are).
- insider.breakdownobject
The insider score's factors, in points. Each factor is capped, and together they add up to
score, which is capped at 100 (sports trades are capped lower, below the high band). - insider.breakdown.convictionnumber | null
A large position at long odds. Points, at most 35.
- insider.breakdown.priceImpactnumber | null
How far the trade moved the price. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.tradeSizenumber | null
The trade's size on its own. No longer scored: 0 on trades scored now, kept for older trades.
- insider.breakdown.marketDominancenumber | null
The trade's size against the market's trading over the previous 24 hours. Points, at most 20.
- insider.breakdown.timingnumber | null
How close to the market's resolution the trade came, or a large early position on a distant event. Points, at most 10.
- insider.breakdown.walletAgenumber | null
How new the wallet was when it traded. Points, at most 15.
- insider.breakdown.contextnumber | null
How much the market's kind of event lends itself to inside knowledge. Points, at most 20.
- insider.detailsobject | null
The full scoring record (GET /v2/trades/{id} only). Its fields may grow; treat it as informational.
- smartMoneyobject | null
Present with include=smartMoney: null when the wallet is not on the board.
- smartMoney.rankinteger | null
The wallet's Smart Money rank (1 = best), null while provisional.
- smartMoney.scorenumber
The wallet's smoothed Smart Money Score.
- smartMoney.tierenum
Badge band: genius 80+ (methodology 4 also needs a minimum of realized edge in dollars), smart 60+, average 40+, naive below.
- smartMoney.styleenum | null
Trading style; null under methodology 3, which has none.
One of
long-shotbalancedfavoriteunknown - smartMoney.methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- resolutionobject | null
- resolution.statusenum
One of
winlosspendingcancelledinvalid - resolution.winningOutcomestring | null
- resolution.entryPricenumber | null
- resolution.exitPricenumber | null
- resolution.pnlUsdnumber | null
- resolution.roinumber | null
- resolution.resolvedAtstring (date-time) | null
- resolution.holdSecondsinteger | null
- resolution.vindicatedboolean
A high-insider-score trade that won.
Wallet and leaderboard events#
wallet.rank_changed#
A wallet's Smart Money rank moved
From the daily board snapshot (about 04:10 UTC): a wallet in the top 100 (or on your watchlist) moved at least minRankDelta places, or entered or left the top 100. Not sent on a day the methodology changed.
Filters:walletswalletScopeminRankDelta
Show the payloadHide the payload14 fields
- walletstring
A Polygon wallet address, always lowercase.
- traderobject
The wallet's display name and image, when known.
- trader.namestring | null
- trader.imagestring | null
- snapshotDatestring (date)
The daily snapshot compared (UTC).
- previousSnapshotDatestring (date) | null
The snapshot it was compared with.
- methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- inTop100boolean
Ranked in the top 100 on snapshotDate.
- wasInTop100boolean
Ranked in the top 100 on previousSnapshotDate.
- rankinteger | null
Rank on snapshotDate; null when the wallet dropped off the board.
- previousRankinteger | null
- deltainteger | null
Places moved: positive is up (previousRank - rank).
- enteredTop100boolean
- exitedTop100boolean
wallet.score_changed#
A wallet's Smart Money Score changed
From the daily board snapshot: a wallet's score moved at least minScoreDelta points. Not sent on a day the methodology changed.
Filters:walletswalletScopeminScoreDelta
Show the payloadHide the payload14 fields
- walletstring
A Polygon wallet address, always lowercase.
- traderobject
The wallet's display name and image, when known.
- trader.namestring | null
- trader.imagestring | null
- snapshotDatestring (date)
The daily snapshot compared (UTC).
- previousSnapshotDatestring (date) | null
The snapshot it was compared with.
- methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- inTop100boolean
Ranked in the top 100 on snapshotDate.
- wasInTop100boolean
Ranked in the top 100 on previousSnapshotDate.
- scorenumber | null
- previousScorenumber | null
- deltanumber | null
score - previousScore.
- tierenum | null
One of
geniussmartaveragenaive - previousTierenum | null
One of
geniussmartaveragenaive
leaderboard.updated#
The daily Smart Money board
Once a day after the snapshot: the top 100, and the wallets that entered or left it. methodologyChanged is true on the day a new methodology took over.
Show the payloadHide the payload12 fields
- snapshotDatestring (date)
A UTC calendar day, YYYY-MM-DD.
- previousSnapshotDatestring (date) | null
- methodologyVersioninteger
The Smart Money Score methodology version that produced this score. GET /v2/methodology/{version} returns its specification.
- methodologyChangedboolean
True when the two snapshots were scored by different methodologies. Per-wallet change events are not sent that day.
- entriesobject[]
The top 100, best first.
- entries[].rankinteger
- entries[].previousRankinteger | null
- entries[].walletstring
A Polygon wallet address, always lowercase.
- entries[].namestring | null
- entries[].scorenumber | null
- enteredstring[]
Wallets in today's top 100 that were not in the previous one.
- exitedstring[]
Wallets in the previous top 100 that are not in today's.
Signal events#
cluster.detected#
Coordinated wallets detected
A new cluster of wallets trading in coordination. confidence is 0..1.
Filters:minConfidence
Show the payloadHide the payload12 fields
- clusterIdstring
- walletsstring[]
- sizeinteger
- detectionMethodenum
One of
timing_correlationoutcome_correlationfunding_sourcemulti_factor - confidencenumber
Detection confidence, 0..1.
- outcomeAlignmentnumber | null
Share of shared markets where the wallets chose the same outcome.
- coordinatedTradeCountinteger
- firstCoordinatedTradeAtstring (date-time) | null
- lastCoordinatedTradeAtstring (date-time) | null
- activeboolean
- flaggedForReviewboolean
- detectedAtstring (date-time) | null
consensus.detected#
Your wallets converged
Several wallets on your watchlist took the same position within the hour. Sent only to your own endpoints.
Filters:minAmountsidesminWhales
Show the payloadHide the payload18 fields
- positionKeystring
Stable id of the converged position.
- titlestring | null
- outcomestring | null
- outcomeIndexinteger | null
- eventSlugstring | null
- marketSlugstring | null
- iconstring | null
- categoryenum | null
One of
cryptopoliticseconomygeopoliticstechculturesciencesportsesportsothermarkets - sideenum
Taker side of the fill.
One of
BUYSELL - whaleCountinteger
- valueUsdnumber
Combined notional across the converging wallets.
- lastTradeAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- whalesobject[]
- whales[].walletstring
A Polygon wallet address, always lowercase.
- whales[].namestring | null
- whales[].imagestring | null
- whales[].valueUsdnumber
US dollars.
- whales[].lastTradeAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
black_swan.status_changed#
The Black Swan radar changed status
The radar moved between calm, ripples, storm and black_swan. (v1: black_swan.changed.)
Show the payloadHide the payload22 fields
- indexnumber
Geopolitical risk index, 0..100.
- statusenum
One of
calmripplesstormblack_swan - statusLabelstring
- statusDescriptionstring
- componentsobject
- components.probabilitynumber | null
- components.insidernumber | null
- components.resolvednumber | null
- highestRiskMarketobject | null
- highestRiskMarket.slugstring
- highestRiskMarket.titlestring
- highestRiskMarket.probabilitynumber
A rate on 0..1.
- highestRiskMarket.categorystring | null
- highestRiskMarket.aiScorenumber | null
- trackedMarketCountinteger
- insiderActivityobject | null
- insiderActivity.volumeUsdnumber
US dollars.
- insiderActivity.averageScorenumber | null
- insiderActivity.tradeCountinteger
- insiderActivity.yesBuyVolumeUsdnumber
US dollars.
- updatedAtstring (date-time) | null
- previousStatusenum | null
One of
calmripplesstormblack_swan
oracle.edition_published#
A new edition of The Oracle
The daily edition was published. (v1: oracle.published.)
Show the payloadHide the payload23 fields
- idstring
- datestring (date)
- volumeNumberinteger
- publishedAtstring (date-time) | null
- articlesobject[]
- articles[].eventSlugstring
- articles[].categorystring
- articles[].headlinestring
- articles[].ledestring
- articles[].bodystring
- articles[].predictedOutcomestring | null
- articles[].confidencenumber | null
- articles[].imageUrlstring | null
- articles[].resolvesAtstring (date-time) | null
- articles[].evidenceobject | null
- articles[].evidence.volumeUsdnumber | null
- articles[].evidence.tradeCountinteger | null
- articles[].evidence.buyVolumeUsdnumber | null
- articles[].evidence.sellVolumeUsdnumber | null
- articles[].evidence.avgInsiderScorenumber | null
- articles[].evidence.maxInsiderScorenumber | null
- articles[].evidence.dominantSideenum | null
One of
BUYSELL - articles[].evidence.avgProbabilitynumber | null
Forecast events#
btc_forecast.updated#
A new BTC forecast run
The hourly BTC price forecast was recomputed. data is the run as GET /v2/forecasts/btc returns it, with the modelVersion that produced it.
Show the payloadHide the payload50 fields
- runAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- spotUsdnumber
US dollars.
- spotSourcestring
- modelVersionstring
The model that produced the run, e.g.
btc-forecast/1.1.0. Methods change between versions, so segment backtests by it. The full specification and version history are in the Developer portal for Quant subscribers: polywhaler.com/developer/methodology#bitcoin-forecast. - marketCountinteger
- confidencenumber
Quality of the evidence behind the run, 0..1: the horizons' confidence combined, the better-evidenced ones counting more.
- horizonsobject[]
- horizons[].keyenum
One of
1w1m3m6m1y - horizons[].targetAtstring (date-time) | null
The instant the fit targets (now + tYears).
- horizons[].tYearsnumber
The time the horizon looks ahead, in years: the average time to expiry of its markets, the more influential ones counting more, or for a synthetic horizon its target of 7, 30, 91, 182 or 365 days.
- horizons[].medianUsdnumber
US dollars.
- horizons[].meanUsdnumber
US dollars.
- horizons[].ci50Usdany[]
- horizons[].ci80Usdany[]
- horizons[].ci95Usdany[]
- horizons[].scenariosUsdobject
The 10th, 50th and 90th percentiles.
- horizons[].scenariosUsd.bearnumber
US dollars.
- horizons[].scenariosUsd.basenumber
US dollars.
- horizons[].scenariosUsd.bullnumber
US dollars.
- horizons[].sigmaAnnualnumber
Annualized volatility of the horizon's price distribution, as a fraction (0.55 = 55%).
- horizons[].sigmaBorrowedboolean
The volatility came from the neighbouring horizons, because this horizon's own markets could not pin it down.
- horizons[].syntheticboolean
No market expires near this horizon; the fit is interpolated.
- horizons[].confidencenumber
Quality of the evidence behind this horizon's fit, 0..1. Not a directional view.
- horizons[].pointCountinteger
Strike observations in the fit.
- horizons[].clusterCountinteger
Distinct strike clusters among them.
- horizons[].rmsenumber
How far the markets' prices sit from the fitted forecast on average, in probability (0..1; lower is a closer fit).
- horizons[].effectiveSampleSizenumber
How many equally weighted markets the evidence is worth.
- horizons[].keyLevelsobject[]
- horizons[].keyLevels[].levelUsdnumber
US dollars.
- horizons[].keyLevels[].probabilityAbovenumber
A rate on 0..1.
- horizons[].densityobject[]
- horizons[].density[].priceUsdnumber
US dollars.
- horizons[].density[].densitynumber
- insightsobject[]
Plain-language bullets computed from the run (no LLM).
- insights[].typeenum
driver: one of the most influential markets in a horizon, and which way it pulls the forecast.divergence: Polymarket and Kalshi disagree at the same level and horizon.delta: the featured horizon's median and confidence against the run about 24 hours earlier.new_market: an influential market that was not in that run.inconsistency: strike pairs priced out of order, which count for less.lean: the featured horizon's implied chance that Bitcoin ends above spot, when the markets lean clearly one way.note: pipeline notes and the daily up-or-down market.skewappears only in runs stored before btc-forecast/1.1.0, which replaced it withlean. New types may be added: skip ones you do not know. - insights[].textstring
- insights[].refsstring[]
The market ids the bullet is about.
- flagsobject[]
- flags[].typeenum
monotonicity: a higher strike priced above a lower one on the same platform, event and expiry (both count for less).cross_platform: the platforms disagree clearly on the same strike and expiry (the shallower book counts for less). - flags[].detailstring
- flags[].marketIdsstring[]
- fanPathobject[]
- fanPath[].atstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- fanPath[].medianUsdnumber
US dollars.
- fanPath[].p025Usdnumber
US dollars.
- fanPath[].p10Usdnumber
US dollars.
- fanPath[].p25Usdnumber
US dollars.
- fanPath[].p75Usdnumber
US dollars.
- fanPath[].p90Usdnumber
US dollars.
- fanPath[].p975Usdnumber
US dollars.
Account events#
export.completed#
Your export finished
An export you requested is ready. Sent only to your own endpoints.
Show the payloadHide the payload13 fields
- idstring
- statusenum
One of
queuedprocessingcompletedfailed - formatenum
One of
csvjsonparquet - datasetenum
One of
tradesoutcomes - filtersobject
The filters the export ran with, camelCase.
- rowCountinteger | null
- fileSizeBytesinteger | null
- errorstring | null
Why a failed export failed.
- requestedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- startedAtstring (date-time) | null
- completedAtstring (date-time) | null
- expiresAtstring (date-time) | null
When the file is deleted. GET /v2/exports/{id}/download returns 410 after it.
- downloadUrlstring | null
Direct link to the file while the export is completed and not expired; null otherwise. Fetch it without your API key: it is on another host.
export.failed#
Your export failed
An export you requested failed. Sent only to your own endpoints. (v1 sent this as export.completed with status failed.)
Show the payloadHide the payload13 fields
- idstring
- statusenum
One of
queuedprocessingcompletedfailed - formatenum
One of
csvjsonparquet - datasetenum
One of
tradesoutcomes - filtersobject
The filters the export ran with, camelCase.
- rowCountinteger | null
- fileSizeBytesinteger | null
- errorstring | null
Why a failed export failed.
- requestedAtstring (date-time)
An instant, ISO-8601 in UTC with a Z suffix.
- startedAtstring (date-time) | null
- completedAtstring (date-time) | null
- expiresAtstring (date-time) | null
When the file is deleted. GET /v2/exports/{id}/download returns 410 after it.
- downloadUrlstring | null
Direct link to the file while the export is completed and not expired; null otherwise. Fetch it without your API key: it is on another host.