---
title: "Api V2 Signals Score Get"
method: GET
path: "/api/v2/signals/score"
tags: ["Trade Signals (v2)"]
---

# Api V2 Signals Score Get

`GET /api/v2/signals/score`

## Request

- Base URL: `https://api.zerogex.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.zerogex.io/api/v2/signals/score`
- Auth: HTTP bearer

Composite Market State Index (MSI) — single 0–100 regime gauge.

Aggregates 6 option-structure components into one reading of "what kind
of market are we in right now?" Each component returns a raw score in
[-1, +1], multiplied by its weight (points) to form a signed contribution.
The contributions are summed into a single signed offset, which is squashed
onto the final scale: `MSI = 50 + 50 * tanh(sum_offset / 50)`, clamped to
[0, 100]. This is a **directionless** regime gauge: a high MSI means trends
can run (NOT bullish) and a low MSI means the tape is choppy / fragile (NOT
bearish). Read direction from the Trade Bias panel, never from this number.

**Params:** `underlying` (default `SPY`). Returns 404 when no rows exist.

**Components and weights:**

| Component | Max pts | What it measures |
|---|---|---|
| `net_gex_sign` | 16 | Sign of dealer net gamma |
| `gamma_anchor` | 30 | Blended proximity to gamma flip / local gamma density / max-gamma strike |
| `put_call_ratio` | 12 | OI-weighted P/C tilt |
| `volatility_regime` | 6 | Realized/VIX regime |
| `order_flow_imbalance` | 19 | Smart-money premium-weighted call vs put flow |
| `dealer_delta_pressure` | 17 | Dealer net delta forced-hedge direction |

`gamma_anchor` exposes its three sub-signals nested under `context`:
`flip_distance_subscore`, `local_gamma_subscore`, `price_vs_max_gamma_subscore`,
plus the active `blend_weights`. Use those for the per-sub-signal breakdown
that previously appeared as standalone components.

**Returns:**
```json
{
  "composite_score": 63.42,
  "components": {
    "net_gex_sign":          {"max_points": 16, "contribution":  9.60, "score":  0.6},
    "gamma_anchor":          {
      "max_points": 30,
      "contribution":  -2.10,
      "score": -0.07,
      "context": {
        "score": -0.07,
        "flip_distance_subscore":  0.21,
        "local_gamma_subscore":   -0.42,
        "price_vs_max_gamma_subscore": 0.17,
        "blend_weights": {"flip_distance": 0.45, "local_gamma": 0.35, "price_vs_max_gamma": 0.20}
      }
    },
    "put_call_ratio":        {"max_points": 12, "contribution":  2.40, "score":  0.2},
    "volatility_regime":     {"max_points":  6, "contribution": -0.08, "score": -0.013},
    "order_flow_imbalance":  {"max_points": 19, "contribution":  6.65, "score":  0.35},
    "dealer_delta_pressure": {"max_points": 17, "contribution":  3.40, "score":  0.2}
  }
}
```

- `composite_score` — float [0, 100]; `50` is the neutral/fallback value.
- `components[*].max_points` — the component's weight ceiling.
- `components[*].contribution` — signed points fed into the pre-squash sum (`sum_offset`), rounded to 4 decimals.
- `components[*].score` — raw component score [-1, +1], 6-decimal precision.
- `components[*].context` — optional, present when the component emits diagnostic
  sub-fields (e.g. `gamma_anchor` exposes its three subscores here).

**Regime interpretation:**
- **≥ 70** — trend/expansion; favor directional trades in the prevailing bias.
- **40–70** — controlled trend; moderate directional edge, size down.
- **20–40** — chop/range; fade extremes, avoid trend trades.
- **< 20** — high-risk reversal; mean-reversion only.

**Page design.** Big radial gauge (0–100). Horizontal bar stack below showing
each component's signed contribution. Hover for `score` and `max_points`.
For `gamma_anchor` specifically, render a smaller secondary breakdown of the
three subscores from `context` so operators retain visibility into which
sub-signal is driving the blended reading.

## Query parameters

- `underlying` string

## Response `200`

Successful Response

- EnvelopeAny
  - `data` unknown, required
  - `freshness` Freshness, required: The v2 freshness envelope. Present on every ``/api/v2/*`` response.
    - `evaluated_at` string, date-time, required: When the API evaluated this response (server wall clock, UTC). Endpoint-health signal: advances on every request even when the underlying data is unchanged.
    - `generated_at` string, date-time, required: When the served data was computed. Equals the snapshot stamp for cycle-backed endpoints, or evaluated_at for endpoints computed on demand for this request.
    - `source_timestamp` string, date-time, nullable: Timestamp of the upstream market observation the payload derives from. This is what freshness_status is measured against. Null when the endpoint has no upstream feed or returned no rows.
    - `latest_event_at` string, date-time, nullable: Newest event timestamp present in the payload (last bar, last trade, last scored row). Best-effort on very large responses, which are sampled rather than fully walked.
    - `age_seconds` number, nullable: evaluated_at - source_timestamp, in seconds. Null when source_timestamp is null.
    - `market_session_status` string, required: pre-market | regular | after-hours | closed (US/Eastern).
    - `expected_update_cadence` string, nullable: ISO-8601 duration for how often this endpoint's data is expected to change right now, e.g. PT60S. Null means no updates are expected (weekend, holiday, or a feed that only runs during the session).
    - `expected_update_cadence_seconds` number, nullable: expected_update_cadence as a number of seconds.
    - `cadence_profile` string, required: Identifier of the cadence class this endpoint belongs to, e.g. analytics_cycle. Stable across releases; the seconds behind it may be retuned.
    - `stale_after` string, date-time, nullable: Instant after which this payload should be treated as stale. Null whenever expected_update_cadence is null.
    - `freshness_status` 'fresh' | 'aging' | 'stale' | 'session_closed' | 'static' | 'unknown', required: The rolled-up freshness verdict for one response. ``fresh`` ``source_timestamp`` is within one expected update cadence. ``aging`` Past one cadence but not yet past ``stale_after`` — the grace band that absorbs normal cycle jitter. Not an error; a client that polls faster than the cadence sees this routinely. ``stale`` Past ``stale_after`` while updates *were* expected. This is the actionable state: the feed behind this endpoint is late. ``session_closed`` A feed-backed endpoint whose feed is not due to produce anything right now (weekend, holiday, or a feed that only runs during the session). The payload is the last good value — deliberately NOT reported as ``stale``, because an overnight consumer polling a closed market is not observing a fault and should not page on it. ``static`` The endpoint is not feed-backed at all: completed history, or a result computed from the caller's own inputs. Age here carries no health meaning and never becomes a fault. ``unknown`` No source timestamp could be resolved from the payload (e.g. a pure calculator, an admin endpoint, or an empty result set). A consumer should fall back to ``evaluated_at`` for endpoint health and make no claim about data age.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/zerogex/apis/zerogex-api.md) · [All operations](https://skmtc.dev/zerogex/apis/zerogex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zerogex/apis/zerogex-api/revisions/753b26bf0592?raw)
