Signal state
https://api.tickerbot.io/ v2/ signals/ {signal}The state of a signal is the set of tickers matching it right now, or with asof, as of any moment. One name, the whole market, one call.
Query parameters
stringrequiredA signal name. Booleans (e.g. golden_cross, above_sma_50) are detected automatically; every other type (numeric rsi_14, timestamp price_asof, date earnings_date, string asset_class) requires a condition.
stringOptional. Target moment as YYYY-MM-DD (that day's close) or an ISO timestamp (that intraday moment) — the same read as it stood then, unlimited depth. Full contract under As of a past date.
enumdefault autoGrain the past state is reconstructed at: 1m, 1h, 1d, or auto (default). Only valid alongside asof — a live read with interval is a 400. Details under As of a past date.
1m | One minute. The finest stored tier; carries the intraday column subset and ~1,100 of ~13,700 tickers. |
1h | One hour. Stored tier, intraday column subset, full universe. |
1d | One day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals). |
autodefault | Let the server pick the finest grain whose columns and ticker coverage both work out, resolving upward on a miss. Reported in _meta.interval. |
stringRequired for every non-boolean signal; the shape follows the signal's type in the catalog. Single bound, <op><value>. **numeric**: >70, <=200, !=0 (operators >, >=, =, !=, <, <=). **timestamp**: an ISO instant, <YYYY-MM-DDTHH:MM:SSZ or >=YYYY-MM-DD (a bare date is midnight UTC). **date**: >=YYYY-MM-DD or =YYYY-MM-DD. **string**: =ETF or !=ETF (= and != only; quotes optional). A relative window ("older than 15 minutes") is a /v2/scan query: price_asof < now() - interval '15 minutes'. Sending a condition with a boolean or custom signal returns 400 (it does not apply).
stringOptional. Scope to a system or caller-owned universe slug.
integerdefault 50Page size. Max 200.
stringOpaque cursor from the previous response.
enumdefault defaultRow order: default (alphabetic for booleans, highest-value-first for numerics) or market_cap (desc NULLS LAST; adds market_cap to each row). Live only — with asof it is a 400 (the snapshot's order is fixed).
defaultdefault | The endpoint’s own ordering — alphabetical for boolean matches, signal value descending for numerics. |
market_cap | Largest companies first. |
booleandefault falseBuilt-in booleans only: adds active_since and days_live per row — the first day of the current true streak, from daily state (the day after the last false day; if the boolean has never been false since it first computed, the first true day). Looks back five years, so a boolean true for longer reports the window edge as a lower bound. Live only — a 400 with asof.
Returns
as_ofstringServer time this response was assembled (ISO 8601).
signalstringThe signal you asked for.
conditionstringThe bound you passed, echoed; `null` for boolean and custom signals.
universestringThe universe you scoped to, echoed; `null` when unscoped.
_metaobjectWith `asof`: how the read was resolved — interval served and requested, blending, sources, frozen fields (see the as-of read below). On any read, `deprecated_columns` when you named the signal under its pre-2026-09-07 spelling and it was served under its current name.
countnumberRows in this page.
next_cursorstringOpaque token for the next page; `null` on the last page. Pass it back as `cursor`.
resultsarrayMatching tickers with the signal value.
Status codes
200400condition, a condition whose shape does not match the signal's type, invalid cursor, or interval on a live read — interval selects the grain a PAST state is reconstructed at, so it is only valid alongside asof.404Notes
- Numeric matches come back sorted by signal value descending; boolean matches alphabetically by ticker.
- For the match set as of a past date, add
?asof=— see Ticker matches (as-of). - Custom signals:
{signal}may be one of your custom signals — it resolves as a boolean signal (matches where its predicate is true;conditionis ignored). See Create a custom signal. - For booleans, the response value is
true/false. For numerics it's the signal value at the time of the request. - Pair with
asofto ask "who matched as of a past date" — see Ticker matches (as-of). For a per-ticker time series of one signal, see Series. - Membership: live reads return currently-active tickers only. As-of reads use point-in-time listing instead (was the ticker listed and not yet delisted at that instant), so a since-delisted name can legitimately appear in a historical match set.
More examples
curl "https://api.tickerbot.io/v2/signals/at_52w_high?limit=3" \
-H "Authorization: Bearer YOUR_KEY"{
"as_of": "2026-08-11T21:35:37.719Z",
"signal": "at_52w_high",
"condition": null,
"universe": null,
"count": 3,
"next_cursor": "eyJhZnRlcl90aWNrZXIiOiJBQk5HIn0",
"results": [
{ "ticker": "AAAP", "name": "Pacer Barings CLO Market Flex ETF", "value": true },
{ "ticker": "ABCS", "name": "Alpha Blue Capital US Small-Mid Cap Dynamic ETF", "value": true },
{ "ticker": "ABNG", "name": "Leverage Shares 2x Long ABNB Daily ETF", "value": true }
]
}Ticker matches (as-of)
https://api.tickerbot.io/ v2/ signals/ {signal}?asof=The set of tickers that matched one signal as of a past date.
Query parameters
stringrequiredA signal name. Booleans (e.g. golden_cross, above_sma_50) are detected automatically; every other type (numeric rsi_14, timestamp price_asof, date earnings_date, string asset_class) requires a condition.
stringrequiredTarget moment as YYYY-MM-DD (the close of that day) or full ISO timestamp (that intraday moment). Unlimited depth.
enumdefault autoGrain the past state is reconstructed at: 1m, 1h, 1d, or auto (default). Same name and values as Series and Bars. Not every signal exists at every grain (rsi_14, fundamentals and valuation ratios are 1d-only), and a cross-section must resolve to ONE grain — so without this, one 1d-only column in the projection silently re-dated every other column in the request. With it set, that case is a 400 interval_unavailable naming the signal and the grains that carry it. auto picks the finest servable grain and reports which in _meta.interval / _meta.interval_reason.
1m | One minute. The finest stored tier; carries the intraday column subset and ~1,100 of ~13,700 tickers. |
1h | One hour. Stored tier, intraday column subset, full universe. |
1d | One day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals). |
autodefault | Let the server pick the finest grain whose columns and ticker coverage both work out, resolving upward on a miss. Reported in _meta.interval. |
stringRequired for every non-boolean signal; the shape follows the signal's type in the catalog. Single bound, <op><value>. **numeric**: >70, <=200, !=0 (operators >, >=, =, !=, <, <=). **timestamp**: an ISO instant, <YYYY-MM-DDTHH:MM:SSZ or >=YYYY-MM-DD (a bare date is midnight UTC). **date**: >=YYYY-MM-DD or =YYYY-MM-DD. **string**: =ETF or !=ETF (= and != only; quotes optional). A relative window ("older than 15 minutes") is a /v2/scan query: price_asof < now() - interval '15 minutes'. Sending a condition with a boolean or custom signal returns 400 (it does not apply).
stringScope to a system or caller-owned universe slug.
integerdefault 50Page size. Max 200.
stringOpaque cursor from the previous response.
Returns
as_ofstringThe moment you asked about — the date's close, or the timestamp you passed.
signalstringThe signal you asked for.
conditionstringThe bound you passed, echoed; `null` for boolean and custom signals.
universestringThe universe you scoped to, echoed; `null` when unscoped.
_metaobjectGrain served (`interval`), why (`interval_reason`), `frozen_fields`, and `coverage_gap` when one applies. `_meta.resolution` is a deprecated alias of `interval`. `deprecated_columns` lists any column you named under its pre-2026-09-07 spelling that was served under its current name (`requested`, `use`, `note`).
countnumberRows in this page.
next_cursorstringOpaque token for the next page; `null` on the last page. Pass it back as `cursor`.
resultsarrayTickers that matched at that instant.
Status codes
200400asof, non-boolean signal called without condition (or a condition whose shape does not match the signal's type), or invalid cursor.404Notes
- This is
GET /v2/signals/{signal}with?asof=— as-of at one-signal scope, the second tense of the same page because point-in-time is its own question. The response envelope matches the live call, plus_metadescribing the grain served and why. - Pass
asofas aYYYY-MM-DDdate (that day's close) or a full ISO timestamp (that intraday moment), and pick the grain withinterval. A match set is a cross-section, so it resolves to ONE grain — and1mis only servable for a scopeduniverse, since the minute tier carries ~1,100 of ~13,700 tickers. - Custom signals:
{signal}may be one of your custom signals — it resolves as a boolean signal. See Create a custom signal. - A match set spans every asset class the signal is defined for, so
R:rates andX:FX/crypto instruments appear alongside equities — the example above is topped by Fed funds rates, not stocks. Scope withuniverse(or filterasset_classvia /v2/scan) when you want one class. - Static fields aren't historized —
name,sector,industry,asset_type, andexchangereflect their *current* values._meta.frozen_fieldslists exactly which ones. - For per-ticker time series of one signal across many bars (not a point-in-time snapshot), use Series —
?ticker={t}&columns={signal}. - Unlimited depth.
- A date-only
asofresolves to the close of that day. A full ISO timestamp (…T15:30:00Z) resolves intraday at the grain you name withinterval(1m/1h/1d/auto)._meta.intervalreports the grain served and_meta.interval_reasonwhy; tickers with no row at that grain are disclosed in_meta.coverage_gapwith a sample. Illiquid instruments (SPAC warrants, units, rights) routinely have no intraday print, so a smallcoverage_gapat1m/1his normal rather than a fault. If there is no state exactly at the requested moment (weekend, holiday, or a gap), the server carries forward the most-recent row within the lookback window (14 days at daily resolution, 5 days for intraday granularities) — a Saturdayasofreturns Friday's values, not an empty set. Beyond the window you get an emptyresultsarray with the echoedasof. (/v2/tickers/{ticker}?asof=applies the identical staleness rule since 2026-07-27, and 404s withlast_availablewhen nothing is fresh enough.) - Membership is point-in-time (survivorship-safe): the as-of set includes tickers that were listed and not yet delisted at that instant, so a since-delisted name can legitimately appear. The live read of this same endpoint returns currently-active tickers only.
More examples
curl "https://api.tickerbot.io/v2/signals/at_52w_high?asof=2024-02-23&limit=3" \
-H "Authorization: Bearer YOUR_KEY"{
"as_of": "2024-02-23",
"signal": "at_52w_high",
"condition": null,
"universe": null,
"_meta": {
"interval": "1d",
"interval_requested": "auto",
"interval_reason": "date-only asof resolves to the daily close",
"resolution": "daily",
"frozen_fields": ["name", "sector", "industry", "asset_type", "exchange", "asset_class", "ticker_category"]
},
"count": 3,
"next_cursor": "eyJhZnRlcl90aWNrZXIiOiJBRkxHIn0",
"results": [
{ "ticker": "ABEQ", "name": "Absolute Select Value ETF", "value": true },
{ "ticker": "ACR", "name": "ACRES Commercial Realty Corp.", "value": true },
{ "ticker": "AFLG", "name": "First Trust Active Factor Large Cap ETF", "value": true }
]
}