# GET /v2/signals/{signal}

**Signal state**

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 / path parameters

| Name | In | Type | Required | Description |
|------|----|----|----------|-------------|
| `signal` | path | string | yes | A 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`. Example: `rsi_14`. |
| `asof` | query | string | no | Optional. Target moment as `YYYY-MM-DD` (that day's close) or an ISO timestamp (that intraday moment; daily-only signals then carry the previous session's close, never that day's) — the same read as it stood then, unlimited depth. Full contract under [As of a past date](). Example: `2026-07-11`. |
| `interval` | query | string | no | Grain the past state is read at: `1m`, `1h`, `1d`, or `auto` (default). `auto` blends: each signal comes from its freshest grain at or before the instant (minute, then hourly, then the last closed daily session), so nothing is refused for grain and no ticker is dropped; `_meta.blended` and `_meta.intervals_present` say what contributed. Pin a grain for the fastest response: one grain is read instead of three, and every ticker is captured on the same clock. A signal the pinned grain does not store is a `400 interval_unavailable` naming the grains that carry it (`rsi_14`, fundamentals and valuation ratios are `1d`-only). Only valid alongside `asof`: a live read with `interval` is a 400. Enum: `1m`, `1h`, `1d`, `auto`. Default: `auto`. |
| `condition` | query | string | no | Required 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). Example: `>70`. |
| `universe` | query | string | no | Optional. Scope to a system or caller-owned universe slug. Example: `top_10`. |
| `limit` | query | integer | no | Page size. Max 200. Default: `50`. Example: `10`. |
| `cursor` | query | string | no | Opaque cursor from the previous response. |
| `sort_by` | query | string | no | Row 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). Enum: `default`, `market_cap`. Default: `default`. |
| `include_active_since` | query | boolean | no | Built-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`. Default: `false`. Example: `true`. |

## Returns

- `as_of` (string) — Server time this response was assembled (ISO 8601).
- `signal` (string) — The signal you asked for.
- `condition` (string) — The bound you passed, echoed; `null` for boolean and custom signals.
- `universe` (string) — The universe you scoped to, echoed; `null` when unscoped.
- `_meta` (object) — This endpoint's own keys, with `asof`: `interval_scope` and `minute_only_columns_fell_back_to_daily`; see the as-of read below. Shared keys: see [the `_meta` reference](/docs/asof#meta).
- `count` (number) — Rows in this page.
- `next_cursor` (string) — Opaque token for the next page; `null` on the last page. Pass it back as `cursor`.
- `results` (array) — Matching tickers with the signal value.

## Status codes

- **200** — Success — the response shape is documented under Returns above.
- **400** — Non-boolean signal called without `condition`, 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`.
- **404** — Signal name does not exist on the schema.

## Sample response

```json
{
  "as_of": "2026-08-11T21:33:54.670Z",
  "signal": "rsi_14",
  "condition": ">70",
  "universe": null,
  "count": 3,
  "next_cursor": "eyJhZnRlcl92YWx1ZSI6OTkuMjY0NCwiYWZ0ZXJfdGlja2VyIjoiU0dWQSJ9",
  "results": [
    { "ticker": "TOMDF", "name": "Todos Medical Ltd",                       "value": 100 },
    { "ticker": "CMBO",  "name": "Wayfinder Dynamic U.S. Interest Rate ETF", "value": 99.4075 },
    { "ticker": "SGVA",  "name": "F/m Accumulator Ultrashort Treasury Fund", "value": 99.2644 }
  ]
}
```

## More examples

### Tickers at a 52-week high (boolean)

Request:

```shell
curl "https://api.tickerbot.io/v2/signals/at_52w_high?limit=3" \
  -H "Authorization: Bearer YOUR_KEY"
```

Response (`200`):

```json
{
  "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 }
  ]
}
```

## Notes

- 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)](/docs/endpoints/signals/get).
- Custom signals: `{signal}` may be one of your custom signals — it resolves as a boolean signal (matches where its predicate is true; `condition` is 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 `asof` to ask "who matched as of a past date" — see [Ticker matches (as-of)](/docs/endpoints/signals/get). For a per-ticker time series of one signal, see [Series](/docs/endpoints/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.

---

Interactive sandbox + parameter editor: https://tickerbot.io/docs/endpoints/signals/get
