> TickerLayer documentation for AI agents and LLMs, the Markdown version of https://tickerlayer.com/docs/signalpoint
> REST base URL https://api.tickerlayer.com, API key in the `x-api-key` header. WebSocket wss://stream.tickerlayer.com?apiKey=YOUR_API_KEY.
> Any docs page reads as Markdown at its URL plus `.md`. Index: https://tickerlayer.com/llms.txt · Full API reference: https://tickerlayer.com/llms-full.txt

# SignalPoint API

Structured trade signals, each with its entry, target, stop and recorded exit. Source signals come from public financial content, momentum signals from price movement.

New Live since September 2026.

- **Auth:** x-api-key header
- **Base path:** /signals
- **WebSocket:** REST only
- **Symbol format:** Bare ticker (e.g. KO, BTC)

**SignalPoint is a data add-on:** $49/mo on Individual, $449/mo on Business, on its own or alongside your plan. [Get it on the add-ons page](https://tickerlayer.com/data-addons#signalpoint)

SignalPoint is a partner [data add-on](https://tickerlayer.com/data-addons#signalpoint), **powered by TradeZing**: TradeZing builds the signals and answers for their content and method, TickerLayer runs your access, billing and support. Without the add-on, `/signals` answers `403`.

## What a signal is

A directional thesis on one instrument, with entry, target and stop set from live prices when it is generated.

- **Lifetime:** Monitored for up to 10 days, then closed exactly once, with the exit reason and the realised move on the record. It can close at its target, at its stop, on its time limit or on expiry; the examples here show one close, not a typical one.
- **Coverage:** US-listed stocks and ETFs during the US session, and major USD crypto pairs around the clock. A symbol gets a signal when something is published about it, so there is no fixed list to subscribe to.
- **History:** Back to June 2026, the start of the record. Page through it with `before` and `meta.next_before`.

## Two kinds of signal

Each signal names its kind in `signal_class`; `/signals?signal_class=` reads one kind on its own.

| signal_class | Built from | Attribution |
| --- | --- | --- |
| `source` | Third-party financial content: news, analyst notes and creator commentary. | The outlet, its publication time and the sentiment read from it, in `source`. |
| `momentum` | TradeZing's own system, from price movement. | None: no third-party content stands behind it, so there is no `source`. |

## List signals

**Endpoint:** `GET /signals`

Signals newest first. Filters combine with AND. Every response names the partner under meta.attribution; show that notice wherever you show the signals.

### Query parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `ticker` | string | Instrument symbol, for example KO or BTC. |
| `direction` | string | Trade direction. Values: `buy`, `sell`. |
| `timeframe` | string | Holding horizon. Values: `intraday`, `short_term`, `swing`, `long_term`. |
| `asset_type` | string | Instrument type. Values: `stock`, `crypto`. |
| `signal_class` | string | Kind of signal; leave it out for both. Values: `source`, `momentum`. |
| `status` | string | Open or closed signals. Values: `open`, `closed`. |
| `since / before` | string | ISO-8601 window on the generation time. To page back, pass `meta.next_before` as `before` unchanged: it carries the id, so signals that share a second are never skipped. |
| `updated_since` | string | Everything created, closed or corrected after this point. Start with an ISO-8601 time, then pass back `meta.next_updated_since`. |
| `limit` | integer | Page size, 1 to 100. Default: `25`. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/signals?status=open&limit=3" \
  -H "x-api-key: <YOUR_API_KEY>"
```

### Response

```json
{
  "status": "ok",
  "data": [ { "id": 21141, "ticker": "EL", "...": "..." } ],
  "meta": {
    "count": 3,
    "has_more": true,
    "next_before": "2026-09-03T05:35:16.000Z|21098",
    "attribution": { "provider": "TradeZing", "notice": "Powered by TradeZing" }
  }
}
```

## Get a signal

**Endpoint:** `GET /signals/{id}`

One signal by id. 404 when the id is unknown.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | integer | Yes | Signal id. Stable for the life of the record, so it is the right primary key for your store. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/signals/21141" \
  -H "x-api-key: <YOUR_API_KEY>"
```

### Response

```json
{
  "id": 21141,
  "ticker": "EL",
  "asset_type": "stock",
  "signal_class": "source",
  "direction": "buy",
  "timeframe": "short_term",
  "entry_price": 99.1,
  "target_price": 107.41,
  "stop_loss": 94.12,
  "max_gain_pct": 8.38,
  "max_loss_pct": 5.03,
  "reasoning": "Strong fiscal Q4 performance and a sizable pre-market gain support bullish post-earnings sentiment.",
  "source": { "name": "The Globe and Mail", "brand": "theglobeandmail" },
  "sentiment": { "positive": 0.82, "negative": 0.1, "neutral": 0.08 },
  "status": "closed",
  "exit": {
    "reason": "profit_target",
    "change_pct": 8.38,
    "exited_at": "2026-08-26T14:18:02Z",
    "data_quality": "ok"
  },
  "content_published_at": "2026-08-19T16:18:31Z",
  "generated_at": "2026-08-19T16:50:24Z",
  "updated_at": "2026-08-26T14:18:02Z"
}
```

## Sources

**Endpoint:** `GET /signals/sources`

The outlets and creators whose content produces source signals. brand is a stable key that pools one outlet's accounts across platforms.

### Request

```bash
curl -sS "https://api.tickerlayer.com/signals/sources" \
  -H "x-api-key: <YOUR_API_KEY>"
```

### Response

```json
{
  "status": "ok",
  "data": [
    { "brand": "theglobeandmail", "name": "The Globe and Mail", "platforms": ["news"] }
  ]
}
```

## Signal object

| Parameter | Type | Description |
| --- | --- | --- |
| `id` | integer | Stable identifier. |
| `ticker / asset_type` | string | Instrument symbol, and stock or crypto. |
| `signal_class` | string | The kind of signal; see Two kinds of signal. Values: `source`, `momentum`. |
| `direction / timeframe` | string | buy or sell, over intraday, short_term, swing or long_term. |
| `entry_price / target_price / stop_loss` | number | Price levels set from live prices when the signal was generated. |
| `max_gain_pct / max_loss_pct` | number | Distance to target and to stop in percent, already adjusted for direction. |
| `atr_percentage` | number | Average true range as a percent of price when the levels were set. |
| `sector / industry` | string | Company classification for stocks. Absent for ETFs, crypto and unclassified symbols. |
| `reasoning` | string | The thesis in one to three plain sentences. |
| `source` | object | name and brand of the outlet whose content produced the signal. Source signals only, never on a momentum signal. |
| `sentiment` | object | positive, negative and neutral, summing to 1. |
| `status` | string | Whether the signal is still monitored. Values: `open`, `closed`. |
| `exit` | object | Absent while open. reason, change_pct, exited_at and data_quality once closed. |
| `content_published_at / generated_at / updated_at` | string | ISO-8601 times of the underlying content, the signal, and its last change: open, close or a later correction. |

| Parameter | Type | Description |
| --- | --- | --- |
| `reason` | string | Why the signal closed, as recorded. New reasons can be added; any value means the signal is closed. Values: `profit_target`, `stop_loss`, `time_limit`, `expired`, `news_catalyst`, `sentiment_shift`. |
| `change_pct` | number | Realised move from entry to exit, sign-adjusted for direction. Absent on expired. |
| `exited_at` | string | ISO-8601 exit time. |
| `data_quality` | string | An exit can be flagged suspect after the fact; leave suspect exits out of anything you compute. Values: `ok`, `suspect`. |

Fields can be added over time, so ignore what you do not use; a field that does not apply is absent, never `null`. An exit reason newer than this list arrives as `other`. `change_pct` is already adjusted for direction: do not flip its sign for a sell, and do not write zero for an `expired` signal, which has no realised move.

## Delta sync

Do not re-poll history. A record arrives again on every change: when it opens, when it closes, and when a closed exit is corrected (flagged `suspect`, or its price revised).

1. **Remember**: Keep the newest `updated_at` you hold.
2. **Poll**: Once a minute, call `/signals?updated_since=...` and follow `meta.next_updated_since` until `has_more` is false. Signals publish on a roughly five-minute cycle, so most polls come back empty.
3. **Upsert**: By `id`; the newest `updated_at` wins.

Signals are informational market analytics. They are not investment advice, a recommendation or a solicitation to trade, and recorded outcomes do not indicate future results. Outlet names identify analysed content only.
