cron.schedule is available on the direct EQL/API path (Validate / Create).
Builder Chat does not yet reliably generate
cron.schedule — if you need a calendar/wall-clock schedule today, author the
condition directly and confirm it with Validate Query.
Triggers (Conditions + Indicators)
In Auto, a trigger is a condition tree that evaluates continuously. When the tree resolves to true, configured actions run.
Market Coverage
Auto monitors symbols across market-data venues — crypto perp markets (Hyperliquid, Binance), plus tokenised equities, indices, commodities, FX, and pre-IPO names listed as HIP-3 markets (xyz:NVDA, xyz:SP500, xyz:GOLD). Those trade 24/7, even when the underlying cash market is closed — see Catalyst Triggers. See Symbols for asset classes, examples, and how to verify a specific ticker.
price and ta conditions select their data venue via the required exchange arg (hyperliquid or binance). See Exchange Argument (price / ta).
The funding and liquidation sources read a wider set of venues (including Binance and Bybit) and select the venue differently — via a composite SYMBOL:EXCHANGE ticker rather than an exchange arg. See Funding and Liquidations.
The sec source is event-driven and selects the issuer by SEC CIK in
args.ticker, not by exchange ticker. See SEC Filings.
Trigger Shape
All triggers are expressed as conditions with a root boolean group:
{
"conditions": {
"AND": [
{
"source": "ta",
"method": "rsi",
"args": { "symbol": "BTC", "timeframe": "1h", "period": 14 },
"operator": "<",
"value": 30
}
]
}
}
Rules:
- Root group must be
ANDorOR. - Groups can be nested.
- Max condition tree depth:
3. - Max leaf conditions per query:
10.
Supported Condition Sources
Price Source (price)
| Method | Arguments | Returns | Description |
|---|---|---|---|
current | symbol, exchange | number | Current market price |
change | symbol, period, exchange | number | Percent price change over period |
high | symbol, period, exchange | number | Highest price in period |
low | symbol, period, exchange | number | Lowest price in period |
volume | symbol, period, exchange | number | Volume in USD over period |
exchange is required on all price methods — see Exchange Argument (price / ta).
TA Source (ta) - Indicator Methods
| Indicator method | Arguments | Returns | Description |
|---|---|---|---|
rsi | symbol, timeframe, period?, exchange | number | RSI (0-100), default period=14 |
macd_value | symbol, timeframe, exchange | number | MACD line value |
macd_signal | symbol, timeframe, exchange | number | MACD signal line |
macd_histogram | symbol, timeframe, exchange | number | MACD histogram |
bbands_upper | symbol, timeframe, period?, exchange | number | Upper Bollinger Band |
bbands_middle | symbol, timeframe, period?, exchange | number | Middle Bollinger Band |
bbands_lower | symbol, timeframe, period?, exchange | number | Lower Bollinger Band |
ema | symbol, timeframe, period, exchange | number | Exponential moving average |
sma | symbol, timeframe, period, exchange | number | Simple moving average |
atr | symbol, timeframe, period?, exchange | number | Average true range |
stoch_k | symbol, timeframe, exchange | number | Stochastic %K |
stoch_d | symbol, timeframe, exchange | number | Stochastic %D |
cci | symbol, timeframe, period?, exchange | number | Commodity Channel Index |
willr | symbol, timeframe, period?, exchange | number | Williams %R |
exchange is required on all ta methods — see Exchange Argument (price / ta).
Signal Source: X/Twitter Post (tweet)
In the builder catalog, this appears in the Signal category as X/Twitter Post.
| Method | Arguments | Returns | Description |
|---|---|---|---|
semantic | username, text, minConfidence | boolean | Matches posts from a specific X/Twitter account when semantic confidence meets threshold |
Notes:
usernameshould be passed without@(for examplecz_binance).usernamemust resolve to an active monitored account, otherwise validation/create fails.minConfidencemust be an integer from0to100.
Default condition shape:
{
"source": "tweet",
"args": {
"username": "cz_binance",
"text": "Binance Alpha is listing a new token",
"minConfidence": 80
}
}
Signal Source: Telegram Channel (telegram)
In the builder catalog, this appears in the Signal category as Telegram Channel.
| Method | Arguments | Returns | Description |
|---|---|---|---|
semantic | chatUsername and/or chatId, text, minConfidence | boolean | Matches messages from a monitored public Telegram channel when semantic confidence meets threshold |
Notes:
- Provide
chatUsername,chatId, or both on the full method form. Shorthand condition form requires exactly one identifier; if both are present on a full condition they must resolve to the same channel. - Prefer
chatUsernamewithout@ort.me/when you know the public channel username. - Use
chatIdonly when it came from tooling or an existing plan; it must be a signed 64-bit integer string. - The Telegram channel must resolve to a monitored public channel, otherwise validation/create fails.
minConfidencemust be an integer from0to100.
Default condition shape:
{
"source": "telegram",
"args": {
"chatUsername": "<monitored_public_channel_username>",
"text": "new Binance listing rumor",
"minConfidence": 80
}
}
Signal Source: Event (news)
In the builder catalog, this appears in the Signal category as Event.
| Method | Arguments | Returns | Description |
|---|---|---|---|
semantic | text, minConfidence | boolean | Matches event-like mentions from news-tagged sources when semantic confidence meets threshold |
Notes:
- Event matching is based on
news-tagged sources. minConfidencemust be an integer from0to100.
Default condition shape:
{
"source": "news",
"args": {
"text": "SEC approves a spot ETH ETF",
"minConfidence": 80
}
}
TA Args Contract
This is the exact args contract validated by Athena for TA methods.
Every method below also requires an exchange:string arg (hyperliquid or binance). It is listed under required args for each method — see Exchange Argument (price / ta).
| Method | Required args | Optional args | Notes |
|---|---|---|---|
rsi | symbol:string, timeframe:string, exchange:string | period:number (default 14) | period is optional. |
macd_value | symbol:string, timeframe:string, exchange:string | None | Uses MACD defaults internally. |
macd_signal | symbol:string, timeframe:string, exchange:string | None | Uses MACD defaults internally. |
macd_histogram | symbol:string, timeframe:string, exchange:string | None | Uses MACD defaults internally. |
bbands_upper | symbol:string, timeframe:string, exchange:string | period:number (default 20) | period is optional. |
bbands_middle | symbol:string, timeframe:string, exchange:string | period:number (default 20) | period is optional. |
bbands_lower | symbol:string, timeframe:string, exchange:string | period:number (default 20) | period is optional. |
ema | symbol:string, timeframe:string, period:number, exchange:string | None | period is required. |
sma | symbol:string, timeframe:string, period:number, exchange:string | None | period is required. |
atr | symbol:string, timeframe:string, exchange:string | period:number (default 14) | period is optional. |
stoch_k | symbol:string, timeframe:string, exchange:string | None | No period argument in EQL. |
stoch_d | symbol:string, timeframe:string, exchange:string | None | No period argument in EQL. |
cci | symbol:string, timeframe:string, exchange:string | period:number (default 20) | period is optional. |
willr | symbol:string, timeframe:string, exchange:string | period:number (default 14) | period is optional. |
Exchange Argument (price / ta)
Both price and ta conditions require an exchange arg that selects which venue's market data backs the condition.
| Property | Value |
|---|---|
| Arg name | exchange |
| Type | string |
| Required | Yes |
| Allowed values | hyperliquid, binance |
Use it to read the same indicator from a different venue — for example, evaluate RSI on binance rather than hyperliquid.
Per-venue notes:
binancereads its USD-M perp markets, and uses Binance's own base-symbol convention —1000PEPE, notkPEPE. Symbols are validated against Binance's live perp catalog at create time.
{
"source": "price",
"method": "low",
"args": { "symbol": "BTC", "period": "1h", "exchange": "binance" },
"operator": "<",
"value": 98000
}
{
"source": "ta",
"method": "rsi",
"args": { "symbol": "BTC", "timeframe": "1h", "period": 14, "exchange": "hyperliquid" },
"operator": "<",
"value": 30
}
Notes:
exchangeselects the data source of aprice/tacondition.- Use the exact lowercase enum values (
hyperliquidorbinance).
Validation Errors → Next Action
When Validate Query or Create rejects a query, the error is almost always a phrasing issue — not a capability gap. Iterate on Validate instead of abandoning the query.
| Error signal | What it means | Next action |
|---|---|---|
EQL_MISSING_ARG | A required arg is absent (e.g. period on ema/sma). | Check TA Args Contract, add the missing arg, re-validate. |
EQL_INVALID_ARG / type errors | Wrong type (e.g. "14" instead of 14) or unrecognized key (e.g. length vs period). | Use the exact key names and JSON numeric types from the contract table. |
Unknown method | Indicator name not supported. | Pick the nearest supported method from TA Source; ask Builder Chat to substitute. |
Unsupported timeframe / period | Value outside the enum. | Snap to the nearest allowed value — see Timeframe and Period Enums. |
Unsupported symbol / source | Asset not indexed or DEX pair unsupported. | Skip that symbol and report it; proceed with the supported subset (see capabilities prompt pack for the "skip unsupported" pattern). |
Unsupported exchange (EQL_INVALID_ARG_VALUE) | args.exchange is not a price/ta data venue. Only hyperliquid and binance are. The check runs on the enum before the symbol is looked up, so you get this rather than a symbol error even when the symbol is also wrong for the venue. | Use hyperliquid or binance — see Exchange Argument. Retired venues are not accepted; gmx was removed in 2.7.3. |
Retired exchange accepted by Save Draft, rejected on Convert (EQL_VALIDATION_ERROR) | POST /v2/auto/queries/drafts does not run venue validation, so a draft carrying an unsupported exchange saves cleanly. Convert Draft runs full create-time validation and wraps the same detail. | Don't treat a saved draft as validated. Run Validate Query before converting, or read the details array on the convert error and fix args.exchange. |
Unmonitored tweet username | tweet.semantic account is not in the monitored active account set. Rejected at both Validate and Create. | Replace with a monitored active handle and re-validate. |
| Unmonitored Telegram channel | telegram.semantic channel is not in the monitored public Telegram channel inventory. Rejected at both Validate and Create. | Use a monitored public channel username or a chatId returned from an existing plan/tooling, then re-validate. |
Invalid Telegram chatId | args.chatId is not a signed 64-bit integer string. | Use the exact string returned by tooling or an existing plan; do not coerce it to a JavaScript number. |
| Conflicting Telegram identifiers | A full telegram.semantic condition supplies both chatId and chatUsername, but they resolve to different channels. | Keep only one identifier, or use the matching pair returned by validation/create. |
kalshi ticker not open (EQL_INVALID_ARG_VALUE) | args.ticker is not a currently-open Kalshi market (closed/settled/unknown). | Use a currently-open full ticker — see Prediction Markets: Open Markets Only. Don't guess tickers. |
kalshi invalid enum / operator | Enum value outside its set, or operator not in the method's allowlist (e.g. crosses_above on trade_size). | Use the per-method allowlists in Prediction Markets → Kalshi. |
polymarket ticker not found / not active | args.ticker is not a live Polymarket outcome token (asset_id). | Use a currently-active outcome-token id — see Prediction Markets → Polymarket. Don't guess ids. |
polymarket invalid operator / dynamic value | Operator not in the method's allowlist, or a dynamic (field-vs-field) value was used. | Use the per-method allowlists in Polymarket Operators; use a literal value (dynamic values are unsupported for polymarket). |
sec invalid CIK | args.ticker is malformed or the CIK was not found in SEC submissions metadata. | Use the issuer CIK, not the stock ticker; see SEC Filings. |
sec invalid enum / operator | Enum value outside its set, or operator not in the method's allowlist. | Use equality for enum/boolean fields, level operators for document_count, and no dynamic values; see SEC Filings. |
Invalid minConfidence (tweet/telegram/news) | Confidence is non-integer or outside 0..100. | Use an integer between 0 and 100 (start with 80). |
| Depth / leaf-count exceeded | More than depth 3 or 10 leaves. | Split into two queries joined by your runner, or factor shared conditions out. |
cron / llm period too short | Below 1h minimum. | Raise to 1h or higher — see Scheduling Period. |
cron.schedule cadence too fast | Minute field isn't a single fixed value (e.g. */15 * * * *), or a sub-hour cadence. | Use a single fixed minute — see Cron Source allowed/not-allowed examples. |
EQL_INVALID_REPEAT | repeat was combined with a recurring cron condition (cron.every / cron.schedule). | Both provide recurrence — remove repeat (cron already recurs), or drop the cron condition. See Repeat. |
SYMBOL_CATALOG_UNAVAILABLE (HTTP 503) | The market catalog was temporarily unreachable, so the symbol could not be checked. Validation fails closed rather than letting an unverified symbol through. | Retry after the interval in the Retry-After header. This is transient — do not reshape the query. |
HIP-3 ticker on funding / liquidation (EQL_INVALID_ARG_VALUE, details.hip3: true) | Dex-prefixed HIP-3 symbols are not published by the funding/liquidation feeds, so the condition could never fire. | Use a plain base symbol (e.g. BTC:BINANCE). HIP-3 remains supported on price/ta — see HIP-3 symbols. |
| Unknown symbol in a composite ticker | The symbol is not listed on that venue's perp catalog (often a naming mismatch). | Check the venue's own base-symbol convention — 1000PEPE on Binance/Bybit vs KPEPE on Hyperliquid. |
| Dynamic value in action params | Dynamic values only allowed in condition value. | Move the dynamic reference into a condition; keep action params literal. |
General rule: if Validate returns an error, reshape and re-validate in a loop — do not create your own monitoring stack. See also If /auto doesn't fit.
Common TA Arg Errors
emaandsmarequireperiod;lengthis not a recognized alias.periodmust be a JSON number (for example14), not a string ("14").timeframeis required for all TA methods.
Invalid EMA example (length used, period missing):
{
"source": "ta",
"method": "ema",
"args": { "symbol": "BTC", "timeframe": "1h", "length": 20 },
"operator": ">",
"value": 100000
}
Expected validation failure:
EQL_MISSING_ARGforperiodon methodema
Valid EMA example:
{
"source": "ta",
"method": "ema",
"args": { "symbol": "BTC", "timeframe": "1h", "period": 20 },
"operator": ">",
"value": 100000
}
Cron Source (cron)
| Method | Arguments | Returns | Description |
|---|---|---|---|
once | period | boolean | True on first due evaluation at/after createdAt + period |
onceRemainTrue | period | boolean | True on first due evaluation and remains true afterward |
every | period | boolean | True at each period interval from query creation |
schedule | expression, timezone? | boolean | True whenever the 5-field cron expression matches in timezone |
once, onceRemainTrue, and every are interval methods measured from
query creation (see Scheduling Period).
schedule is a calendar/wall-clock method:
expressionis a classic 5-field cron string (minute hour day-of-month month day-of-week) — for example0 9 * * 1-5(weekdays at 09:00).timezoneis optional and defaults toUTC. When set it must be a valid IANA name (e.g.America/New_York,Europe/London,Asia/Singapore) so daylight-saving transitions are handled correctly. Fixed-offset strings like+02:00are not accepted.scheduleenforces the same 1h-minimum cadence as the other cron methods: the minute field must be a single fixed value (0–59). Wildcards, steps, lists, or ranges in the minute field (which fire multiple times per hour) are rejected. You choose which minute past the hour a run lands on.- Allowed:
7 * * * *(hourly at minute 7),0 9 * * 1-5(weekdays 09:00),30 8 * * *(daily 08:30). - Not allowed:
* * * * *(every minute),*/15 * * * *(every 15 min),0,30 * * * *(twice per hour).
- Allowed:
scheduletakes noperiodarg.
LLM Source (llm)
| Method | Arguments | Returns | Description |
|---|---|---|---|
athena_condition | query, period, speed? | boolean | LLM-evaluated condition |
Note:
cron,llm,tweet,telegram, andnewssupport shorthand forms and are expanded server-side.periodforcronandllmsources has a minimum of1h. See Scheduling Period (cron / llm) for the allowed set.- For clearer runtime semantics and easier debugging, prefer separate queries for event-driven Signal intents (
tweet/telegram/news) and recurring schedule intents (cron.every).
Prediction Markets Source (kalshi)
Trigger on Kalshi prediction-market activity. Each method takes a single
ticker arg (a full open Kalshi market ticker, e.g. KXBTC-26APR0803-T77799.99).
- Trade-backed:
yes_price,no_price,trade_size,taker_outcome_side,taker_book_side,is_block_trade - Market-backed:
status,result,settlement_value
A plan can only be created against a market that is currently open —
closed/settled tickers are rejected at validation. Operators are restricted per
method (price methods support crosses_above/crosses_below; enum/boolean
methods are equality-only).
Full method tables, operator allowlists, value enums, and example automations: Prediction Markets → Kalshi.
Prediction Markets Source (polymarket)
Trigger on Polymarket outcome-token activity. Each method takes a single
ticker arg — the outcome token asset_id (a long numeric id), not the
top-level market id.
- Methods:
price,bid,ask(number),size(number),side(enum"BUY"/"SELL")
A plan can only be created against a live outcome token — unknown/inactive
tokens are rejected at validation. Operators are restricted per method
(price/bid/ask support crosses_above/crosses_below; size is level-only;
side is equality-only). Polymarket does not support dynamic (field-vs-field)
values.
Full method tables, operator allowlists, value enums, and example automations: Prediction Markets → Polymarket.
SEC Filings Source (sec)
Trigger on enriched SEC filing metadata. Each method takes a single
ticker arg that contains the issuer CIK, not the stock ticker. Auto accepts
1-10 digit CIKs and stores the normalized 10-digit value.
- Enum methods:
base_form_type,form_category - Boolean flags:
is_amendment,is_late_filing,is_offering,is_ownership_filing, 8-K item flags,has_primary_document,has_xbrl,submission_match_found - Number method:
document_count
SEC filing conditions are event-like. A one-shot plan fires once on the first
matching filing; a repeat plan can fire once
per distinct accession. SEC does not support dynamic values.
Full method tables, operator allowlists, CIK rules, and examples: SEC Filings.
Funding Source (funding)
Trigger on perp funding rates — an overheated long bias, a flip to negative, or a
cross-venue divergence. Each method takes a single composite ticker of the form
SYMBOL:EXCHANGE (e.g. BTC:BINANCE, ETH:HYPERLIQUID).
- Venues:
binance,hyperliquid - Methods:
annualized_rate(canonical — percent APR, venue-comparable),interval_rate,interval_hours,exchange
Prefer annualized_rate: Binance settles funding every 8h and Hyperliquid every
1h, so the same interval_rate threshold means different things per venue.
"Funding flips negative" is annualized_rate crosses_below 0.
Full method tables, operator allowlists, ticker rules, and examples: Funding and Liquidations → Funding.
Liquidation Source (liquidation)
Trigger on liquidation flow in a trailing window — a cascade crossing a USD
threshold, a one-sided flush, or liquidations as a share of open interest. Same
composite SYMBOL:EXCHANGE ticker as funding.
- Venues:
binance,bybit,hyperliquid - USD methods:
total_usd_1m/5m/1h,long_usd_1m/5m/1h,short_usd_1m/5m/1h,largest_order_usd_1h - Other methods:
count_1h(level operators only),total_pct_oi_1m/5m/1h(percent of open interest),exchange
Two things to know before setting a threshold: feed quality differs by venue
(Binance is sampled, so its values are a lower bound; Bybit and Hyperliquid are
complete), and windows decay to zero, so a repeat plan fires once per
cascade rather than once ever.
Full method tables, the per-venue feed-quality table, and examples: Funding and Liquidations → Liquidation.
Fear & Greed Source (fear_greed)
Trigger on the market-wide Crypto Fear & Greed Index.
This is a keyless source — the index is one global reading with no per-market
identity, so its methods take no ticker. Pass an empty args: {}.
| Method | Arguments | Returns | Description |
|---|---|---|---|
value | (none) | number | The index score, an integer 0–100 (0 = extreme fear, 100 = extreme greed) |
classification | (none) | enum | The bucket label — see below |
Notes:
valueaccepts all eight operators.classificationaccepts only==/!=, and its value must be one of:"Extreme fear","Fear","Neutral","Greed","Extreme greed".- The labels map to fixed
valuebands —Extreme fear0–19,Fear20–39,Neutral40–59,Greed60–79,Extreme greed80–100— so a numeric threshold and the matching classification are interchangeable. Prefervaluewhen you want a precise threshold. - The index updates roughly every 15 minutes, so conditions react at that cadence.
A newly created condition has no observed value until the first reading arrives,
and a
crosses_above/crosses_belowleaf needs a prior reading to compare against — so it can only fire on the second reading after activation. fear_greeddoes not support dynamic values.
{
"source": "fear_greed",
"method": "value",
"args": {},
"operator": "crosses_below",
"value": 20
}
Follow Graph Sources (x_follow_received, x_follow_made, x_follow_overlap)
Trigger on new X follow edges Elfa detects. Three sources ask three questions about the same data:
x_follow_received— watch an account, fire when someone follows it. Methodfollower_count, argaccount.x_follow_made— watch an account, fire when it follows someone. Methodfollowee_follower_count, argaccount.x_follow_overlap— watch 2-25 accounts, fire when several follow the same account. Methoddistinct_followers, argaccounts.
All three take optional window (6h-7d) and period, accept only > and
>=, and do not support dynamic values. Follow data is collected on a
recurring check rather than streamed, so alerts are not real time and unfollows
are never detected.
x_follow_made and x_follow_overlap read the watched account's own following
list, so those accounts must be ones Elfa monitors; x_follow_received does not
require that.
{
"source": "x_follow_received",
"method": "follower_count",
"args": { "account": "elfa_ai", "window": "24h" },
"operator": ">",
"value": 10000
}
On x_follow_overlap the value floor is 2, and it cannot exceed the size of
accounts (one below it with >).
Full method tables, coverage limits, payload fields, and examples: Follow Graph.
Supported Operators
><>=<===!=crosses_abovecrosses_below
Cross operators use previous-state tracking and evaluate transitions:
crosses_above: previous<threshold and current>=thresholdcrosses_below: previous>threshold and current<=threshold
Dynamic Comparisons (Dynamic Values)
value does not need to be a static literal. It can also reference another
data source result at evaluation time.
This lets you compare one live metric against another live metric, for example current price vs. an indicator band.
Example: trigger when ETH price crosses above the current 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" }
}
}
]
}
}
Important:
- Dynamic values are supported only in condition
value. - Dynamic values are not supported in action parameters.
- Dynamic values are not supported by
sec,polymarket,fear_greed,funding, orliquidationconditions.
Timeframe and Period Enums
TA timeframe values:
1m,5m,15m,30m,1h,2h,4h,8h,12h,1d
period values for price args and TA indicator lookbacks:
1h,2h,4h,8h,12h,24h,1d,7d
Scheduling Period (cron / llm)
For cron interval methods (once, onceRemainTrue, every) and llm sources, period is a scheduling interval with a minimum of 1h.
Allowed values:
1h,2h,4h,8h,12h,24h,1d,7d
cron.schedule does not take a period — it is driven by its 5-field cron expression and follows the same 1h-minimum cadence (at most one fire per hour). See Cron Source.
Signal Match-Description Guidance
For X/Twitter Post, Telegram Channel, and Event, write args.text as a short factual claim.
X/Twitter Post examples:
- bad:
Bearish vibes-> good:Opens a short position on oil - bad:
Something bullish-> good:Announces a new stake in TSLA - bad:
Bullish on a coin-> good:Posts that they're bullish on $HYPE and $SOL
Telegram Channel examples:
- bad:
Alpha group update-> good:new Binance listing rumor - bad:
Team news-> good:team confirms mainnet launch - bad:
Whale chatter-> good:large OTC buyer interest
Event examples:
- bad:
Market crash-> good:Major DeFi protocol suffers a $200M exploit - bad:
War conflict-> good:US imposes new sanctions on Russia - bad:
Big news-> good:SEC approves a spot ETH ETF