Prediction Markets
Prediction-market conditions let an Auto query trigger on activity inside a prediction market. Two providers are supported:
- Kalshi (
source: "kalshi") — trigger on live trade prints (executed YES/NO price, trade flow, block trades) and market lifecycle (status, settlement result, settlement value), addressed by a full Kalshi market ticker. - Polymarket (
source: "polymarket") — trigger on live outcome-token activity (last price, best bid/ask, last-trade size and aggressor side), addressed by an outcome-tokenasset_id. Polymarket exposes price/quote/trade methods only — there are no market-lifecycle methods.
Use a prediction-market condition when the trigger maps to a concrete data point on a market you can name (a Kalshi ticker or a Polymarket outcome-token id):
- Prefer a prediction-market source over
llmwhen the trigger is a supported method (price level, trade flow, status, or settlement). It evaluates on real trade/market events, not a scheduled natural-language guess. - Prefer it over
price/tawhen you care about the implied probability of an event resolving, not the spot price of a crypto asset. - Reach for
llmonly when the question is fuzzy and no prediction market expresses it.
Both sources use the full EQL condition form and obey the standard limits: they
can be combined with other sources inside AND/OR groups, up to depth 3 and
10 leaf conditions. See Triggers.
Kalshi
Exposed as EQL source: "kalshi". Kalshi conditions trigger on Kalshi
prediction-market activity: live trade prints (executed YES/NO price, trade
flow, block trades) and market lifecycle (status, settlement result, settlement
value).
Open Markets Only
At create time, Auto validates args.ticker against the catalog of open
(tradeable) Kalshi markets. A ticker that is closed, determined,
settled, or finalized is not in that catalog, and create/validate fails
with EQL_INVALID_ARG_VALUE — the market "was not found or is not open".
Resolve a real, currently-open ticker before encoding the query. Do not
invent or guess tickers. The full market ticker looks like
KXBTC-26APR0803-T77799.99 (series + event + strike).
Note that lifecycle conditions are still useful on a market you are already
watching. A plan created while a market is active can trigger as that same
market moves to settled (via status) or resolves (result,
settlement_value) within the plan's expiresIn window.
Condition Shape
Kalshi conditions use the full EQL condition form. args contains exactly one
field, ticker — the full Kalshi market ticker.
{
"source": "kalshi",
"method": "yes_price",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "crosses_below",
"value": 0.4
}
Standard EQL limits apply: a kalshi condition can be combined with other
sources inside AND/OR groups, up to depth 3 and 10 leaf conditions. See
Triggers.
Trade-Backed Methods
These read from live Kalshi trade prints. Each evaluates on the latest executed trade for the ticker.
| Method | Returns | Description |
|---|---|---|
yes_price | number in [0, 1] | Executed YES price in dollars — the live implied probability of the market resolving YES. |
no_price | number in [0, 1] | Executed NO price in dollars (implied probability of NO). |
trade_size | number ≥ 0 | Number of contracts on that print. |
taker_outcome_side | enum "yes" / "no" | Which outcome the aggressor (taker) positioned for. |
taker_book_side | enum "bid" / "ask" | Same aggressor expressed in book terms: "bid" = YES-side pressure, "ask" = NO-side pressure. |
is_block_trade | boolean | true when the print is a large negotiated off-book block trade. |
yes_price and no_price are the core signals; they are the market's live
read on how likely the event is. taker_outcome_side / taker_book_side /
is_block_trade let you filter for who is trading and how, not just the
price.
Market-Backed Methods
These read from Kalshi market lifecycle updates rather than individual trades.
| Method | Returns | Description |
|---|---|---|
status | enum "active" / "closed" / "determined" / "settled" / "finalized" | Market lifecycle state. "active" is the only tradeable state. |
result | enum "yes" / "no" | Settlement outcome. Empty until the market resolves. |
settlement_value | number ≥ 0 | Final settlement value in dollars; populated on settlement. |
The lifecycle generally flows active → closed → determined → settled → finalized. A condition on status == "settled" (or result == "yes") is how
you trigger downstream work the moment a market you've been watching resolves.
Operators by Method
Operators are restricted per method:
| Method(s) | Allowed operators |
|---|---|
yes_price, no_price | > · < · >= · <= · == · != · crosses_above · crosses_below |
trade_size, settlement_value | > · < · >= · <= · == · != |
taker_outcome_side, taker_book_side, status, result, is_block_trade | == · != |
Notes:
- Only the price methods (
yes_price,no_price) support the transition operatorscrosses_above/crosses_below. They evaluate a probability crossing a threshold, which is usually what you want for an alert. - Enum and boolean methods are equality-only (
==/!=). trade_sizeandsettlement_valueare numeric levels but have no cross operators.
Value Types and Enums
value must be a literal that matches the method's type — Kalshi conditions
do not support dynamic (field-vs-field) values.
| Method | value type | Allowed values |
|---|---|---|
yes_price, no_price | number | 0–1 (dollar price / implied probability) |
trade_size | number | ≥ 0 (contracts) |
settlement_value | number | ≥ 0 (dollars) |
taker_outcome_side | string enum | "yes", "no" |
taker_book_side | string enum | "bid", "ask" |
status | string enum | "active", "closed", "determined", "settled", "finalized" |
result | string enum | "yes", "no" |
is_block_trade | boolean | JSON true / false (not the strings "true"/"false") |
Example Automations
All examples are shown in the flattened title / description +
conditions / actions / expiresIn shape. For HTTP calls, wrap
conditions / actions / expiresIn under a top-level query key — see
HTTP Request Wrapper.
1) Probability threshold crossing
Alert when the market's YES probability falls through 40% — useful for catching a thesis breaking down on a market you hold a view on.
{
"title": "BTC < $77,799.99 — YES drops below 40%",
"description": "Fire when the Kalshi market's implied YES probability crosses down through 40%, signalling the market no longer expects this outcome.",
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "yes_price",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "crosses_below",
"value": 0.4
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Kalshi YES probability dropped below 40%" }
}
],
"expiresIn": "24h"
}
2) Aggressive flow into a near-certain market
Combine a price filter with the taker side to catch aggressive YES buying into a market that is already pricing the outcome as near-certain — a "smart money is still piling in" signal.
{
"title": "Aggressive YES flow into a 90%+ market",
"description": "Fire when YES is already above 90% AND the aggressor is buying YES, indicating continued conviction buying near resolution.",
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "yes_price",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": ">",
"value": 0.9
},
{
"source": "kalshi",
"method": "taker_outcome_side",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "==",
"value": "yes"
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Aggressive YES flow into a 90%+ Kalshi market" }
}
],
"expiresIn": "24h"
}
3) Block-trade watcher
Surface large negotiated block trades — a signal that a sizeable participant is taking a position.
{
"title": "Large block trade on Kalshi market",
"description": "Fire on off-book block trades larger than 500 contracts to flag institutional-size positioning.",
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "is_block_trade",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "==",
"value": true
},
{
"source": "kalshi",
"method": "trade_size",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": ">",
"value": 500
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "48h"
}
4) Settlement recap (lifecycle + LLM)
Trigger the moment a market you are watching settles YES, then run an LLM action to write a short resolution recap and notify.
{
"title": "Kalshi market resolved YES — recap",
"description": "When the market settles with a YES result, generate a concise recap of what happened and why.",
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "result",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "==",
"value": "yes"
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "llm",
"params": {
"action": "chat",
"message": "This Kalshi market just resolved YES. Write a concise recap explaining what resolved and what to watch next.",
"callback": {
"action": {
"type": "notify",
"params": { "message": "{{llm_output.analysisText}}" }
}
}
}
}
],
"expiresIn": "48h"
}
5) Builder Chat prompt
You can let Builder Chat assemble the query. Give it the open ticker and the prediction-market signal you want:
Build an Auto query:
- title + description: short summary and the thesis behind this watch
- source: kalshi
- ticker: KXBTC-26APR0803-T77799.99 (already confirmed open)
- trigger when the YES implied probability crosses above 60%
- action: webhook to https://your-runner.example/auto/events
- one-time trigger, expires in 48h
If the ticker is not open or anything is unsupported, say so and return the closest supported query.
Validation Notes
| Error signal | What it means | Next action |
|---|---|---|
EQL_INVALID_ARG_VALUE on args.ticker | Ticker is not a currently-open Kalshi market (closed/settled/unknown). | Resolve a currently-open full ticker and re-validate. Don't guess tickers. |
Invalid enum value | A status/result/taker_* value outside its enum set. | Use an exact enum value from Value Types and Enums. |
| Unsupported operator | An operator not in the method's allowlist (e.g. crosses_above on trade_size, or > on status). | Pick an allowed operator from Operators by Method. |
is_block_trade type error | value passed as a string instead of a JSON boolean. | Use JSON true / false, not "true" / "false". |
Unknown method | Method not in the supported set. | Use a supported method. |
Polymarket
Exposed as EQL source: "polymarket". Polymarket conditions trigger on live
outcome-token activity from Polymarket's prediction markets: last traded price,
best bid/ask, and the size and aggressor side of the most recent trade. Unlike
Kalshi, Polymarket exposes price and trade methods only — there are no
market-lifecycle (status / result) methods.
Outcome-Token Tickers
For Polymarket, args.ticker is the outcome token asset_id — the long
numeric id of a single outcome (for example the YES token), not the
top-level Polymarket market id. The market id is shared by both sides of a binary
market and is not the routing key Auto uses.
At create time, Auto validates the token against Polymarket's live markets. An unknown or inactive token is rejected — the market "was not found or is not active". Resolve a real, currently-active outcome-token id before encoding the query; do not invent or guess ids.
Polymarket Condition Shape
args contains exactly one field, ticker — the outcome-token asset_id.
{
"source": "polymarket",
"method": "price",
"args": { "ticker": "115556263888245616435851357148058235707004733438163639091106356867234218207169" },
"operator": "crosses_below",
"value": 0.4
}
Standard EQL limits apply: a polymarket condition can be combined with other
sources inside AND/OR groups, up to depth 3 and 10 leaf conditions.
Polymarket Methods
Each method takes a single ticker arg (the outcome-token asset_id) and reads
from the live outcome-token price / quote / trade feed.
| Method | Returns | Description |
|---|---|---|
price | number in [0, 1] | Last traded probability / price for the outcome token. |
bid | number in [0, 1] | Best bid for the outcome token (when present on the event). |
ask | number in [0, 1] | Best ask for the outcome token (when present on the event). |
size | number ≥ 0 | Size of the last-trade update (when present on the event). |
side | enum "BUY" / "SELL" | Aggressor side of the last trade, in uppercase. |
The feed mixes several event subtypes (price_change, best_bid_ask,
last_trade_price, book), and not every field updates on every event — for
example best_bid_ask updates bid/ask only, while last_trade_price updates
price/size/side only. Design a condition around the specific field you need
rather than assuming all fields move together on each update.
Polymarket Operators
Operators are restricted per method:
| Method(s) | Allowed operators |
|---|---|
price, bid, ask | > · < · >= · <= · == · != · crosses_above · crosses_below |
size | > · < · >= · <= · == · != |
side | == · != |
Only the price/quote methods (price, bid, ask) support the transition
operators crosses_above / crosses_below. size is a numeric level with no
cross operators, and side is equality-only.
Polymarket Value Types
value must be a literal that matches the method's type. Polymarket
conditions do not support dynamic (field-vs-field) values — because the feed
mixes event subtypes and fields do not co-occur on every event, dynamic
Polymarket targets are rejected at validation.
| Method | value type | Allowed values |
|---|---|---|
price, bid, ask | number | 0–1 (probability / price) |
size | number | ≥ 0 |
side | string enum | "BUY", "SELL" (uppercase) |
Polymarket Examples
All examples are shown in the flattened title / description +
conditions / actions / expiresIn shape. For HTTP calls, wrap
conditions / actions / expiresIn under a top-level query key — see
HTTP Request Wrapper.
1) Outcome price threshold crossing
Alert when a single outcome token's implied probability falls through 40%.
{
"title": "Polymarket outcome drops below 40%",
"description": "Fire when the outcome token's last traded price crosses down through 0.40, signalling the market no longer expects this outcome.",
"conditions": {
"AND": [
{
"source": "polymarket",
"method": "price",
"args": { "ticker": "115556263888245616435851357148058235707004733438163639091106356867234218207169" },
"operator": "crosses_below",
"value": 0.4
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Polymarket outcome dropped below 40%" }
}
],
"expiresIn": "24h"
}
2) Aggressive buy flow (side + size filter)
Catch a large BUY-side print on an outcome token — aggressive positioning into that outcome.
{
"title": "Large BUY-side Polymarket print",
"description": "Fire when the last trade on the outcome token is a BUY of more than 100 in size, flagging aggressive positioning.",
"conditions": {
"AND": [
{
"source": "polymarket",
"method": "side",
"args": { "ticker": "115556263888245616435851357148058235707004733438163639091106356867234218207169" },
"operator": "==",
"value": "BUY"
},
{
"source": "polymarket",
"method": "size",
"args": { "ticker": "115556263888245616435851357148058235707004733438163639091106356867234218207169" },
"operator": ">",
"value": 100
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Large BUY-side Polymarket print observed" }
}
],
"expiresIn": "24h"
}
3) Cross-outcome signal (AND across two tokens)
Require two outcome tokens to satisfy their thresholds jointly — for example one outcome above 60% while another is below 30%.
{
"title": "Cross-outcome Polymarket signal",
"description": "Fire when outcome A trades above 0.60 AND outcome B trades below 0.30, confirming a joint move across two related outcomes.",
"conditions": {
"AND": [
{
"source": "polymarket",
"method": "price",
"args": { "ticker": "ASSET_ID_A" },
"operator": ">",
"value": 0.6
},
{
"source": "polymarket",
"method": "price",
"args": { "ticker": "ASSET_ID_B" },
"operator": "<",
"value": 0.3
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Cross-outcome Polymarket signal hit" }
}
],
"expiresIn": "24h"
}
Polymarket Validation Notes
| Error signal | What it means | Next action |
|---|---|---|
| Ticker not found / not active | args.ticker is not a live Polymarket outcome token (unknown or inactive). | Resolve a currently-active outcome-token asset_id and re-validate. Don't guess ids. |
| Unsupported operator | An operator not in the method's allowlist (e.g. crosses_above on size, or > on side). | Pick an allowed operator from Polymarket Operators. |
Invalid side value | A side value other than "BUY" / "SELL", or the wrong case. | Use uppercase "BUY" or "SELL". |
Dynamic value on polymarket | A field-vs-field dynamic value was used. | Use a literal value; dynamic comparisons aren't supported for Polymarket in v1. |
Unknown method | Method not in the supported set (price, bid, ask, size, side). | Use a supported method. |
See the general iteration guidance in Validation Errors → Next Action: reshape and re-validate in a loop rather than abandoning the query.
Pair a prediction market with the asset it moves
A prediction market tells you when the world changed. It doesn't have to be the end of the plan — it can be the trigger for a position in the asset that catalyst moves.
A rate decision reprices on Kalshi in seconds. The assets it moves — the S&P, gold,
the dollar, mega-cap tech — all trade as HIP-3 perps on Hyperliquid, 24/7, even
when the cash equity market is closed. So a Kalshi condition can fire a
market_order on xyz:SP500 at 3am on a Sunday.
{
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "yes_price",
"args": { "ticker": "<an open Kalshi Fed-decision market ticker>" },
"operator": "crosses_above",
"value": 0.6
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "market_order",
"params": { "exchange": "hyperliquid", "symbol": "xyz:SP500", "side": "buy", "amount": "250" }
}
]
}
This is the single highest-leverage pattern in Auto. It has its own page: Catalyst Triggers — how to pick the cheapest catalyst source, how to bridge a catalyst to the asset classes it moves, and five worked setups.
Related Docs
- Catalyst Triggers — pair these markets with equity/commodity perps
- Triggers (Conditions + Indicators)
- Query Model and Templates
- Symbols — HIP-3 asset classes
- Capabilities
- Signal Triggers
- Create Query