Skip to main content

Query Model and Templates

This page defines the core EQL query object and copy/paste starters you can use before activation.

For the full trigger reference (conditions, indicators, operators, timeframes, and exact TA args schema), see Triggers, Signal, and TA Args Contract.

Intent Routing (Strict)

Choose source by intent before writing conditions:

IntentRequired sourceMinimum required fields
Account-anchored post intent (@user posts ...)source: "tweet"args.username (no @), args.text, args.minConfidence (baseline 80)
World event intent (ETF approval, exploit, sanctions, etc.)source: "news"args.text, args.minConfidence (baseline 80)
Fuzzy world-state predicate not naturally post/event matchingsource: "llm"method: "athena_condition", args.query, args.period (>= 1h)
Prediction-market move/lifecycle on a named open Kalshi marketsource: "kalshi"method (e.g. yes_price, status, result), args.ticker (open market), operator/value per the Kalshi method allowlists
Prediction-market price/trade on a Polymarket outcome tokensource: "polymarket"method (price, bid, ask, size, side), args.ticker (outcome-token asset_id), operator/value per the Polymarket method allowlists
Perp funding-rate intent (overheated funding, funding flips negative)source: "funding"method (prefer annualized_rate), args.ticker as SYMBOL:EXCHANGE (e.g. BTC:BINANCE) — see Funding
Liquidation-flow intent (cascade, long/short flush)source: "liquidation"method (e.g. total_usd_5m, total_pct_oi_1h), args.ticker as SYMBOL:EXCHANGE — see Liquidation
Market-wide sentiment intent (fear/greed regime)source: "fear_greed"method (value or classification), empty args: {} — see Fear & Greed
Real-world catalyst moving an equity/index/commodity (rate decision, CPI, earnings, OPEC)the catalyst's own source (kalshi / polymarket / news / price), with a HIP-3 symbol in the actionPick the catalyst source, then bridge to the asset class it moves — see Catalyst Triggers

When the prompt is account-anchored, do not route to news or llm first. Start with tweet.

Required API Sequence

For lifecycle operations in API key mode: validate -> create -> cancel (if active/recurring) -> delete (if terminal).

Trade actions (market_order, limit_order) must preflight GET /v2/auto/exchanges before create.

Inner Query Object (EQL)

The object below is the value of query. It is not the full HTTP request body by itself.

{
"conditions": { "AND": ["..."] },
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "..." }
}
],
"expiresIn": "24h"
}

repeat is an optional sibling of expiresIn. By default a plan is one-shot (fires once, then terminal); add repeat to make it re-fire on its own conditions — see Repeat (repeat).

HTTP Request Wrapper (Required)

When calling API endpoints, wrap the inner EQL object under a top-level query key.

Create request shape:

{
"query": {
"conditions": { "AND": ["..."] },
"actions": [{ "stepId": "step_1", "type": "notify", "params": { "message": "..." } }],
"expiresIn": "24h"
},
"title": "Optional title",
"description": "Optional description"
}

Validate request shape:

{
"query": {
"conditions": { "AND": ["..."] },
"actions": [{ "stepId": "step_1", "type": "notify", "params": { "message": "..." } }],
"expiresIn": "24h"
}
}

Allowed action types:

  • API key mode (/v2/auto/*): webhook, notify, telegram_bot, llm, market_order, limit_order
  • x402 mode (/x402/v2/auto/*): webhook, notify, telegram_bot, llm

Action params shape (key fields):

typeRequired paramsOptional params
notifymessage (1–1000 chars)
webhookurl (https only, allowlisted host)signingSecret (write-only), allNotifications (default false)
telegram_botbotToken, chatIdallNotifications (default false)
market_order / limit_orderexchange (see Supported Venues), symbol, side, and exactly one of size / amount / positionSizePercent (+ price for limit)reduceOnly, leverage, tp, sl
llmaction (chat / summary / macro / accountAnalysis / tokenDiscovery / tokenAnalysis), callback.actionspeed (fast / expert), per-action extras

telegram_bot does not take a message field — the body is auto-composed from query title + description + trigger context. Use notify (in-app push) when you want to specify the message text yourself. allNotifications: true on webhook / telegram_bot opts the destination into lifecycle notifications (failed / expired / run-failed) in addition to trigger fires.

For signed webhook delivery, set webhook.params.signingSecret; do not reuse your API key, request HMAC secret, or x402 agent secret. LLM callback webhook actions accept the same webhook params at query creation time, but resolved callback responses expose only public callback fields, not url or signingSecret. See Notifications.

Trade-action prerequisite in API key mode:

  • market_order and limit_order require an active connected exchange. The required params.exchange selects the venue — hyperliquid, gmx, binance, or pacifica — and a matching active connection must exist for that venue. Optional params are not supported uniformly across venues: see Supported Venues.
  • Without an exchange connection, trade actions fail at execution time when the trigger fires.
  • x402 does not support order execution actions.

Execution setup details: Trading Execution (API Key mode).

title and description are surfaced back inside delivered notifications (Telegram, webhook, notify). When a user suddenly receives an alert — often hours or days after setting it up — these fields are what let them recognize what fired and why they asked for it.

Without them, recipients get a condition summary with no context on the original intent, which hurts trust and slows follow-up.

Guidance:

  • title: short, human-readable summary of the trigger. Example: "BTC RSI oversold on 1h".
  • description: 1–2 sentences describing the thesis or intent. Example: "Mean-reversion entry: if BTC 1h RSI dips under 30 during US session, consider scaling in.".
  • Write them as if the recipient has forgotten they set this up — because they often have.

Expiry (expiresIn)

Allowed values: 1h, 2h, 4h, 8h, 12h, 24h, 48h (2d), 72h (3d), 120h (5d), 168h (7d), 240h (10d), 336h (14d), 504h (21d), 720h (30d).

Prefer 24h3d (or shorter). Only use longer durations (10d to 30d) for slow-rolling structural thesis plans, options expiries, or multi-week event tracking.

Shorter expiries are much better for four reasons:

  • Signal freshness. Crypto/market conditions change fast. A trigger set 7 days ago was based on a thesis that may no longer hold — narratives, sentiment, and fundamentals shift within hours, not weeks. Shorter windows force a re-evaluation: "do I still believe this setup?"
  • Technical Indicator Decay. Over-extended indicators lose predictive value. For example, a 14-period RSI trigger or MACD crossover setup on short-to-medium timeframes (e.g. 5m, 1h) typically resolves within 24 to 72 hours; leaving them active for 2 weeks or a month increases the risk of triggering on stale or unrelated chart wicks.
  • Noise and alert fatigue. The longer a condition sits open, the higher the chance it triggers on a random wick, a one-off news spike, or an unrelated move — not the signal you cared about. Short expiries keep the notification feed tied to current intent, not a graveyard of forgotten conditions.
  • Intent decay. If a setup hasn't played out in a few days, the original trade idea is usually invalidated anyway. A 7-day alert firing on day 6 rarely reflects what the trader would act on today. Most actionable setups resolve within 24–72 hours.

Duration Selection Guide

Choose expiresIn based on the expected lifespan of the signal that triggered the setup:

  • 1h - 4h (Scalp & Momentum): High-frequency setups, immediate reaction plays, or micro-news triggers. Ideal for fast technical indicators (RSI, MACD) on tight timeframes (1m, 5m, 15m) that lose all relevance within hours.
  • 8h - 24h (Intraday & Swing): Standard intraday setups, overnight hold-conditions, or immediate FOMC/CPI macroeconomic reaction triggers. Resolves within a single trading day.
  • 48h - 72h (Multi-Day Breakouts): Weekend hold strategies, support/resistance breakout retests, or mid-week event triggers.
  • 120h - 168h (Standard Weekly): Weekly close momentum trends, intermediate funding rate sweeps, or macro consolidation watches.

When to Choose Longer Expiries (10d - 30d Max Limit)

While shorter durations are preferred to minimize noise and protect capital, certain structured automations specifically require longer runways. The following guide dictates when to use these extended periods:

  • 10 Days (240h): Speculative Event Window / Narrative Front-Running. Tailored for major catalyst events such as token unlocks, network hard forks, or key conferences (e.g. Consensus, Devcon) which experience a standard 10-day momentum accumulation cycle before peak volatility.
  • 14 Days (336h): Bi-weekly and options-rebalancing setups. Appropriate for front-running bi-weekly options expirations, monitoring payroll liquidity allocations, or tracking bi-weekly macroeconomic cycles (such as CPI-to-FOMC central bank policy sprints).
  • 21 Days (504h): Multi-Week Swing & Options Expiry. Perfect for monthly options-hedging plays or monthly funding rate sweeps. Designed to enter positioning as market makers re-hedge delta exposure in the 2 to 3 weeks leading up to monthly options expiration dates.
  • 30 Days (720h - Absolute Maximum Ceiling): Monthly copy-trading or portfolio-tracking. Reserved strictly for long-term automated plays like 13F institutional filing copiers (matching portfolio filings from large funds), monthly fund rebalancing, or monthly candle close trend-following. Never use for short-term technical indicators or scalps.

Repeat (repeat)

By default a plan is one-shot: it fires once and moves to a terminal state. The optional top-level repeat object keeps a plan active and makes it re-fire on its own conditions — the right tool for "notify me every time BTC dips below 60k" without a fixed cron cadence.

{
"conditions": { "AND": ["..."] },
"actions": ["..."],
"expiresIn": "168h",
"repeat": { "cooldown": "1h", "maxTriggers": 10 }
}

Both fields are mandatory when repeat is present:

FieldTypeMeaning
cooldownstringMinimum time between fires. "0" disables the rate limit.
maxTriggersnumberLifetime cap on fires (11000); reaching it makes the plan terminal.
  • cooldown allowed values (its own set — sub-hour is permitted, unlike the cron/llm 1h minimum): 1m, 5m, 15m, 30m, 1h, 2h, 4h, 8h, 12h, 24h, 1d, 7d, plus "0". Use "0" for "fire on every distinct event" (e.g. every matching tweet).
  • maxTriggers counts how many times the plan fires over its lifetime (distinct from the number of action steps). Sanity-check cooldown × maxTriggers against expiresIn — if there isn't enough runway, the plan expires before reaching the cap.
  • Single reset rule. A repeat plan re-fires only once its triggering signal has cleared. Level conditions (price / ta / llm-boolean) disarm on fire and re-arm when the whole condition tree next evaluates false; event conditions (tweet.semantic / news.semantic) consume the matched mention and re-fire on the next distinct mention.
caution
repeat on trade actions places a new order every fire

repeat composes with every action type, including market_order and limit_order. On an order action, each fire places a new order — Auto does not net, reconcile, or cancel what earlier fires opened. Three fires means three positions.

  • Sizing resolves per fire. positionSizePercent is recomputed against the then-current account value (so it compounds), and tp / sl / leverage are attached to each order independently.
  • cooldown and maxTriggers are your position-count controls. They are not just a notification rate-limit here — they are the only thing bounding how much size the plan can put on. Choose them deliberately.
  • Avoid cooldown: "0" on order actions. It is accepted, but the cooldown is a recurring plan's only replay guard: with "0", a redelivered trigger can place a second order. Any non-zero cooldown closes that window.
  • A failed fire does not stop the plan. You are notified (order_failed / athena_query_run_failed), the plan stays live for its next trigger, and the failed fire still consumes one of your maxTriggers.
note
Still rejected: repeat + recurring cron

repeat cannot be combined with a recurring cron condition (cron.every / cron.schedule) — both provide recurrence, so combining them is rejected at validation as EQL_INVALID_REPEAT. For a fixed-cadence recurring plan, use the cron condition on its own; for a condition-driven recurring plan, use repeat.

Avoiding Over-Triggering

repeat re-fires on the plan's own condition, so the main risk is a condition that keeps flipping true — a metric flapping around its threshold, or a chatty account — firing far more often than you intended. Two knobs control this, and you should treat them as your rate-limit and your safety net:

  • cooldown is a rate-limit floor. No matter how often the condition re-arms, the plan will not fire again until cooldown has elapsed since the last fire. This is your primary defense against spam. "0" removes the floor entirely — reserve it for genuinely discrete events (e.g. "every distinct tweet"), never for level/metric conditions.
  • maxTriggers is a hard circuit breaker. Even if the condition is mis-tuned, the plan goes terminal after this many fires. Always set it conservatively so a runaway condition self-limits instead of alerting for the full expiresIn window.

Why a metric over-triggers: a level condition like price < 60000 fires, disarms, then re-arms the instant price pops back above 60k — so a price oscillating around the threshold produces a fire on every dip (the reset rule edge-gates it, so it won't fire on every evaluation cycle, but it will fire on every re-crossing). A short or zero cooldown turns that into a flood.

Safer patterns:

  • Prefer transition operators. Use crosses_below / crosses_above rather than < / > so the plan reacts to the crossing edge, not to the value simply sitting past the threshold.
  • Give the threshold room. Set it a meaningful distance from the current value so normal noise doesn't repeatedly trip it.
  • Match cooldown to the signal's cadence. For a 1h-timeframe metric, a sub-hour cooldown just re-alerts on the same move — align cooldown with the timeframe you actually care about.
  • Start conservative, then loosen. Begin with a longer cooldown and a low maxTriggers; widen only if you find you're missing real events.

Safe defaults to start from, then tune to your use case:

Condition typecooldownmaxTriggersNotes
Price / TA level (price, ta)1h4h (≥ your timeframe)310Prefer crosses_* operators; avoid "0" here.
LLM predicate (llm.athena_condition)≥ period (min 1h)35The LLM already re-checks on period — don't re-alert faster than it re-evaluates.
Event — single / quiet account (tweet)015m1020Each distinct post is a discrete event; "0" is fine unless the account is chatty.
Event — noisy account / broad news15m1h1020A small cooldown collapses a burst of mentions into one alert.
Liquidation cascade (liquidation)1h+510Windows decay to zero, so the plan re-arms per cascade; the cooldown stops one long cascade re-alerting.
Trade / order action (market_order, limit_order)Non-zero, 1h+25These are positions, not alertsmaxTriggers is the number of orders the plan may place. Never "0".

Always sanity-check cooldown × maxTriggers against expiresIn: with cooldown: "1h" and maxTriggers: 10 the plan has roughly ten hours of firing runway, so a much longer expiresIn mainly buys patience through quiet periods — it does not raise the fire cap. When in doubt, start with a longer cooldown and a low maxTriggers; you can always create a looser follow-up plan.

If /auto Doesn't Fit: Substitution Ladder

Before concluding your use case is out of scope, walk this ladder. Most intents resolve at rung 1 or 2.

  1. Rephrase through Builder Chat with a substitution instruction. Append "If anything is unsupported, return the closest supported query and list substitutions" to your chat prompt. Builder Chat will map your intent onto supported primitives rather than failing silently.
  2. Iterate on Validate Query. Validate Query returns structured errors (see Validation Errors → Next Action). Loop: validate → reshape → re-validate. Do not jump to "this isn't possible" after one rejection.
  3. Split into multiple queries joined by your runner. If a single condition tree can't express the logic (depth 3 / 10-leaf limits, or AND across incompatible sources), create 2+ queries and have your Agent Runner correlate their events.
  4. Use source: "llm" for fuzzy predicates. If the condition isn't a clean numeric rule, phrase it as a natural-language predicate evaluated by athena_condition. This covers narrative/sentiment/context questions that don't map to TA indicators.
  5. Pre-compute in your own service, use Auto as control plane. Only rung 5. If you have genuinely proprietary selection or signal logic, compute it yourself and feed the result into an Auto query — keep monitoring, lifecycle, and delivery inside Auto. See For Advanced Strategies.

Do not build your own monitoring/evaluation/trigger stack before walking rungs 1–4.

Anti-example: "I need to alert when BTC breaks a descending trendline"

A first instinct is "Auto doesn't compute trendlines, so I'll build this externally." Walk the ladder:

  • Rung 1: Rephrase as a supported proxy — "alert when BTC price crosses above its 4h upper Bollinger Band AND 1h RSI > 55". That's a supported query.
  • Rung 4: If the proxy isn't acceptable, use source: "llm" with a scheduled natural-language predicate — "has BTC broken its recent descending trendline on the 4h chart?".
  • Rung 5: Only if both fail: compute trendline-break externally, then feed a boolean into an Auto cron + llm query as the condition trigger.

Quick Action Snippets (for Builder Chat)

Use these snippets inside your POST /v2/auto/chat prompt so the generated query includes delivery wiring.

Webhook

Action requirements:
- action type: webhook
- deliver trigger payload to https://your-runner.example/auto/events
- keep payload concise and machine-readable

Telegram Bot

Action requirements:
- action type: telegram_bot
- params: botToken + chatId for my Telegram bot/chat
- include severity label in the query title/description so it lands in the auto-composed alert: info, warn, or high

LLM

Action requirements:
- action type: llm
- return one decision: long, short, or no-trade
- include 3 bullet rationale points and confidence score
- I will fetch full output via sessions APIs

Canonical Template: Daily Suggest + Trade (amount: "10")

Use this template for requests like: "suggest a BTC trade every 24h and execute with amount 10."

Required order:

  1. GET /v2/auto/exchanges (confirm hyperliquid active)
  2. POST /v2/auto/queries/validate
  3. POST /v2/auto/queries
{
"title": "Daily BTC suggest + trade 10",
"description": "Every 24h, generate a BTC suggestion and execute a 10-unit market order policy.",
"conditions": {
"AND": [
{
"source": "cron",
"method": "every",
"args": { "period": "24h" },
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "llm",
"params": {
"objective": "Return one concise BTC trade suggestion (buy, sell, or no-trade) with confidence and rationale."
}
},
{
"stepId": "step_2",
"type": "market_order",
"params": {
"exchange": "hyperliquid",
"symbol": "BTC",
"side": "buy",
"amount": "10"
}
}
],
"expiresIn": "3d"
}

For HTTP calls, wrap conditions, actions, and expiresIn under top-level query.

Copy/Paste Query Templates

Use these as starting points with Validate Query before create.

Note:

  • Templates below are shown in a flattened shape for readability (title/description + conditions/actions/expiresIn).
  • For HTTP calls, convert them to API payload shape by moving conditions, actions, and expiresIn under top-level query.
  • action.params keys can vary by integration setup. Treat these as starter templates and adjust for your environment.

Signal Authoring Quality Rubric (X/Twitter Post + Event)

For Signal conditions (tweet.semantic, news.semantic), write args.text as a short factual claim.

Weak phrasing (bad)Actionable phrasing (good)
Bearish vibesOpens a short position on oil
Something bullishAnnounces a new stake in TSLA
Bullish on a coinPosts that they're bullish on $HYPE and $SOL
Market crashMajor DeFi protocol suffers a $200M exploit
War conflictUS imposes new sanctions on Russia
Big newsSEC approves a spot ETH ETF

Confidence guidance (minConfidence):

  • Baseline default: 80
  • Raise to 85-90 when you want fewer false positives
  • Lower to 70-75 when recall is more important than precision

1) Breakout Alert (Webhook)

{
"title": "BTC breakout above 100k",
"description": "Notify runner when BTC spot trades above the 100k round-number level.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"operator": ">",
"value": 100000
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": {
"url": "https://your-runner.example/auto/events",
"signingSecret": "your-webhook-signing-secret"
}
}
],
"expiresIn": "24h"
}

2) Downside Guardrail (Telegram)

{
"title": "ETH downside guardrail (< 2500)",
"description": "Risk-off alert: flag if ETH breaks below 2500 so I can review exposure.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "ETH" },
"operator": "<",
"value": 2500
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "telegram_bot",
"params": { "botToken": "<TELEGRAM_BOT_TOKEN>", "chatId": "<TELEGRAM_CHAT_ID>" }
}
],
"expiresIn": "24h"
}

The notification body for telegram_bot is auto-composed from title + description + trigger context — there is no message param.

3) Runner Handoff (Webhook + Notify)

{
"title": "SOL breakout handoff to runner",
"description": "When SOL trades above 220, hand off to the agent runner and log a notify event.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "SOL" },
"operator": ">",
"value": 220
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
},
{
"stepId": "step_2",
"type": "notify",
"params": { "message": "SOL trigger fired; runner notified" }
}
],
"expiresIn": "24h"
}

4) Triggered LLM Analysis

{
"title": "BTC > 100k — LLM next-action review",
"description": "On BTC breakout, run an LLM pass to decide the next trading action under current conditions.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"operator": ">",
"value": 100000
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "llm",
"params": { "objective": "Analyze trigger context and return next action" }
}
],
"expiresIn": "24h"
}

5) Multi-Symbol Confirmation

{
"title": "BTC + ETH joint breakout",
"description": "Confirm majors are moving together: BTC above 100k AND ETH above 3500 before acting.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"operator": ">",
"value": 100000
},
{
"source": "price",
"method": "current",
"args": { "symbol": "ETH" },
"operator": ">",
"value": 3500
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "BTC and ETH confirmation trigger fired" }
}
],
"expiresIn": "24h"
}

6) Dynamic Comparison (Price crosses Bollinger Band)

Compare one live metric against another — no precomputation required.

{
"title": "ETH breakout above 4h upper BBand",
"description": "Dynamic comparison: fire when ETH price crosses above its own 4h upper Bollinger Band.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "ETH" },
"operator": "crosses_above",
"value": {
"source": "ta",
"method": "bbands_upper",
"args": { "symbol": "ETH", "timeframe": "4h" }
}
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "48h"
}

7) Scheduled Check (cron)

Fire on a fixed schedule, no market condition required — useful for periodic LLM summaries or recurring portfolio sweeps.

{
"title": "Every 4h: portfolio sweep",
"description": "Recurring check every 4h to run a portfolio-context LLM pass.",
"conditions": {
"AND": [
{
"source": "cron",
"method": "every",
"args": { "period": "4h" },
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "llm",
"params": { "objective": "Summarize BTC/ETH/SOL context and flag any risk shifts" }
}
],
"expiresIn": "3d"
}

For a calendar / wall-clock schedule (e.g. weekdays at 09:00 New York time) use method: "schedule" with a 5-field cron expression and an IANA timezone. The minute field must be a single fixed value (1h-minimum cadence), and there is no period arg — see Cron Source.

{
"title": "Weekday 9am NY: market open recap",
"description": "Every weekday at 09:00 America/New_York, run an LLM recap of what moved overnight while US cash markets were shut.",
"conditions": {
"AND": [
{
"source": "cron",
"method": "schedule",
"args": { "expression": "0 9 * * 1-5", "timezone": "America/New_York" },
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "llm",
"params": { "objective": "Recap the overnight session for xyz:SP500, xyz:NVDA and xyz:GOLD, and flag any risk shifts ahead of the US open" }
}
],
"expiresIn": "7d"
}

This one is worth dwelling on: the equity and commodity perps (xyz:SP500, xyz:GOLD) kept trading all night while the cash market was closed, so there is a real overnight session to recap. See Catalyst Triggers.

cron.schedule is available on the direct EQL/API path today; Builder Chat does not yet reliably generate it, so author calendar schedules directly and confirm with Validate Query.

8) LLM-Evaluated Condition (athena_condition)

Use when the predicate is fuzzy or narrative-driven and can't be expressed as a numeric rule.

{
"title": "Narrative shift watcher",
"description": "Fire when the dominant narrative around AI tokens materially shifts based on news + X context.",
"conditions": {
"AND": [
{
"source": "llm",
"method": "athena_condition",
"args": {
"query": "Has the dominant narrative around AI-sector tokens shifted materially in the last 6 hours based on news and X sentiment?",
"period": "1h"
},
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "telegram_bot",
"params": { "botToken": "<TELEGRAM_BOT_TOKEN>", "chatId": "<TELEGRAM_CHAT_ID>" }
}
],
"expiresIn": "2d"
}

9) Signal Trigger: X/Twitter Post

Trigger when a specific monitored account posts something matching your description.

{
"title": "Binance Alpha listing post watcher",
"description": "Fire when cz_binance posts that Binance Alpha is listing a new token so I can review follow-through.",
"conditions": {
"AND": [
{
"source": "tweet",
"method": "semantic",
"args": {
"username": "cz_binance",
"text": "Binance Alpha is listing a new token",
"minConfidence": 80
},
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "24h"
}

10) Signal Trigger: Event

Trigger when an event-style mention matches the semantic description.

{
"title": "ETH ETF approval event watcher",
"description": "Fire when event feeds indicate a spot ETH ETF approval so I can kick off a post-event playbook.",
"conditions": {
"AND": [
{
"source": "news",
"method": "semantic",
"args": {
"text": "SEC approves a spot ETH ETF",
"minConfidence": 80
},
"operator": "==",
"value": true
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "Event trigger fired: spot ETH ETF approval signal" }
}
],
"expiresIn": "24h"
}

11) Prediction Market (Kalshi)

Trigger on a Kalshi market's implied probability. args.ticker must be a currently-open market — see Prediction Markets for the full method/operator reference and the open-markets-only rule.

{
"title": "Kalshi YES crosses 60%",
"description": "Fire when the market's implied YES probability crosses up through 60%, signalling the market now expects this outcome.",
"conditions": {
"AND": [
{
"source": "kalshi",
"method": "yes_price",
"args": { "ticker": "KXBTC-26APR0803-T77799.99" },
"operator": "crosses_above",
"value": 0.6
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "48h"
}

12) Prediction Market (Polymarket)

Trigger on a Polymarket outcome token's implied probability. args.ticker is the outcome-token asset_id (a long numeric id), not the market id — see Prediction Markets → Polymarket for the full method/operator reference.

{
"title": "Polymarket outcome crosses 60%",
"description": "Fire when the outcome token's last traded price crosses up through 0.60, signalling the market now expects this outcome.",
"conditions": {
"AND": [
{
"source": "polymarket",
"method": "price",
"args": { "ticker": "115556263888245616435851357148058235707004733438163639091106356867234218207169" },
"operator": "crosses_above",
"value": 0.6
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "48h"
}

13) Recurring Trigger (repeat)

Re-fire on the plan's own condition instead of a fixed cron cadence — here, notify every time BTC crosses down through 60k, rate-limited to once per hour and capped at 10 fires. Note the safer-pattern choices: crosses_below (reacts to the crossing edge, not a value sitting below the line) plus a 1h cooldown and a low maxTriggers ceiling. See Repeat and Avoiding Over-Triggering.

{
"title": "Notify when BTC crosses below 60k",
"description": "Recurring risk alert: fire each time BTC price crosses down through 60000, no more than once per hour, up to 10 times.",
"conditions": {
"AND": [
{
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"operator": "crosses_below",
"value": 60000
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "BTC dipped below 60k again" }
}
],
"expiresIn": "7d",
"repeat": { "cooldown": "1h", "maxTriggers": 10 }
}

14) Funding Flip (funding)

Fire when Binance BTC funding turns negative — shorts start paying longs. Note the composite SYMBOL:EXCHANGE ticker and the venue-comparable annualized_rate method. See Funding and Liquidations.

{
"title": "BTC funding flips negative",
"description": "Shorts are now paying longs on Binance BTC — a crowded-short signal worth reviewing.",
"conditions": {
"AND": [
{
"source": "funding",
"method": "annualized_rate",
"args": { "ticker": "BTC:BINANCE" },
"operator": "crosses_below",
"value": 0
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "notify",
"params": { "message": "BTC funding on Binance flipped negative" }
}
],
"expiresIn": "7d"
}

15) Liquidation Cascade (liquidation + repeat)

Fire each time ETH liquidations cross $500k in a 5-minute window. Liquidation windows decay back to zero once a cascade subsides, which re-arms the condition — so with repeat this fires once per cascade.

{
"title": "ETH liquidation cascade (5m > $500k)",
"description": "Alert on each distinct ETH liquidation cascade on Bybit, capped at 10 alerts.",
"conditions": {
"AND": [
{
"source": "liquidation",
"method": "total_usd_5m",
"args": { "ticker": "ETH:BYBIT" },
"operator": "crosses_above",
"value": 500000
}
]
},
"actions": [
{
"stepId": "step_1",
"type": "webhook",
"params": { "url": "https://your-runner.example/auto/events" }
}
],
"expiresIn": "7d",
"repeat": { "cooldown": "1h", "maxTriggers": 10 }
}

16) Catalyst → Equity/Index Trade (HIP-3)

The prediction-market-to-perp bridge: when a rate decision reprices, take a position in the S&P perp — including overnight and at weekends, when cash equities are closed. xyz:SP500 is a HIP-3 market on Hyperliquid; see Catalyst Triggers.

{
"title": "Fed cut odds → long S&P",
"description": "When the market prices a cut as more likely than not, go long the S&P perp.",
"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"
}
}
],
"expiresIn": "168h",
"repeat": { "cooldown": "4h", "maxTriggers": 3 }
}

Poll Response Shape

GET /v2/auto/queries/{queryId} returns:

  • queryId (UUID)
  • status
  • credits (number, optional)
  • latestEvaluation — latest current-state snapshot
  • executions — action execution records, each with a UUID id

Note: All query and execution identifiers are UUIDs (e.g., a12d20ff-6cb2-433e-afed-cc2e6a0380b6), not prefixed strings like q_123 or exec_123.

Latest Evaluation

latestEvaluation is null until a query has evaluated at least once. Once present, it includes:

  • evaluatedAt
  • conditionStates[]
  • wouldTriggerNow
  • matchingConditions
  • totalConditions

Use conditionStates[].currentValue for the latest observed value and conditionStates[].targetValue / conditionStates[].operator for the current comparison.

{
"evaluatedAt": "2026-04-01T12:00:00.000Z",
"conditionStates": [
{
"index": 0,
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"currentValue": 97250.5,
"targetValue": 100000,
"operator": "<",
"isMet": true,
"lastUpdated": "2026-04-01T12:00:00.000Z"
}
],
"wouldTriggerNow": true,
"matchingConditions": 1,
"totalConditions": 1
}

Auto Trigger Context

Execution records include Auto Trigger Context when the query has fired. This is the stable public representation of why the query fired:

  • triggerTime
  • conditionsMet
  • trigger.type
  • trigger.time
  • trigger.matchedConditions[]

Use trigger.matchedConditions[].match.observedValue for the value observed at trigger time. The trigger threshold is trigger.matchedConditions[].condition.value.

{
"id": "a12d20ff-6cb2-433e-afed-cc2e6a0380b6",
"queryId": "76e2e824-fc47-4d60-99b1-c227fbd2d3f5",
"type": "notification",
"status": "success",
"details": { "notification": { "channel": "webhook" } },
"triggerTime": "2026-04-01T12:00:00.000Z",
"conditionsMet": 1,
"trigger": {
"type": "price",
"time": "2026-04-01T12:00:00.000Z",
"matchedConditions": [
{
"condition": {
"source": "price",
"method": "current",
"args": { "symbol": "BTC" },
"operator": "<",
"value": 100000
},
"match": { "observedValue": 97250.5 }
}
]
},
"createdAt": "2026-04-01T12:00:01.000Z"
}

Auto Trigger Context is also included in outbound delivery payloads and script trigger context. Raw stored trigger payloads are not part of the public API.

Common Agent Flows

Poll-Based LLM Flow

1. POST /v2/auto/queries                               -> create query with action.type = "llm"
2. GET /v2/auto/queries/{queryId} -> poll until execution with sessionId appears
3. GET /v2/auto/queries/{queryId}/sessions/{sessionId} -> fetch full analysis

Webhook-Based LLM Flow

1. POST /v2/auto/queries                               -> create with action.type = "llm" + callback webhook
2. Wait for webhook -> receive session reference / output
3. Optional GET session fetch -> /v2/auto/queries/{queryId}/sessions/{sessionId}