Skip to content

KPI Equity Impact API

Retrieve prediction-market and Octagon-model estimates for company KPIs over REST, alongside the actual once the company reports. The API exposes two endpoints: a ranked board of upcoming and settled KPI prints, and the full event bundle for a single KPI.

Like the Chat Completions and Responses endpoints, these are direct REST endpoints called relative to the Octagon API base URL:

text
https://api.octagonai.co/v1

Endpoints

MethodPathPurpose
GET/predictions/kpi-eventsThe board — list / rank / search / paginate KPI events
GET/predictions/kpi-events/{event_id}One KPI event — the full event bundle

Conventions

  • KpiValue — every KPI-unit quantity is an object of the form { "value": <number>, "unit": <string>, "formatted": <string> } (e.g., { "value": 28060000, "unit": "customers", "formatted": "28.06M" }). It is null when the underlying number is absent. value is the numeric field for computation; formatted is display-only.
  • event_id — the Octagon-owned primary key. Curated series get a readable id (e.g. hood_funded_customers_2026q2); uncurated events get an opaque evt_<hash> (and kpi_<hash>).
  • period — the fiscal period the market forecasts, parsed from the event text ("in Q2 2026"Q2 2026; "in 2026"FY 2026). code / label / kind / start / end are populated for ~97% of events; null only for genuine non-period markets (e.g., a one-off corporate announcement). Quarter start / end are calendar quarters — a display window, not a fiscal-calendar mapping.
  • Probabilities are percentage points on a 0–100 scale (model_probability: 90.0 means 90%).
  • newsworthiness — a 0–100 sort key combining edge magnitude, liquidity tier, and report-date proximity.
  • Units — curated series carry curated units; uncurated series infer a unit from the event text (e.g., "card members" → members). unit may be empty or absent only when genuinely unknown.
  • Errors — JSON { "detail": "…" }; 400 bad parameters, 401 authentication ("Missing or invalid credentials"), 404 unknown event, 422 validation.

Authentication uses the standard bearer token — see Authentication.

List KPI events

GET /predictions/kpi-events

The board / reporting calendar.

Query Parameters

ParameterTypeRequiredDescription
statusstringNoall (default) | active | settled | reported.
sortstringNonewsworthiness (default) | volume | edge | abs_edge | edge_pp | report_date | reported_at | close_time.
qstringNoSubstring search over company / KPI name.
periodstringNoFilter by period code (e.g. 2026q2; see Conventions). A comma-separated list matches any of the codes.
limitintegerNoNumber of records to return. Default 50; minimum 1; maximum 200.
cursorstringNoOpaque pagination cursor. Use the next_cursor returned from a previous response to continue.

report_date sorts soonest-expected first; all other sorts are descending.

status semantics: settled means the event is past close, matching each row's status field — the actual may still be pending. reported means settled and a trusted actual is served (a captured-but-flagged actual — see the trust gate — does not count). "Settled but awaiting actual" is ?status=settled minus ?status=reported.

Response

jsonc
{
  "as_of": "2026-07-07T00:00:00Z",   // when this board snapshot was generated
  "aggregates": { "total_events": 146, "total_markets": 1039, "total_volume": 4874975.01 },  // illustrative — the board grows
  "sort": "newsworthiness",
  "status": "all",
  "data": [ /* rows, see below */ ],
  "next_cursor": null,
  "has_more": false
}

aggregates.total_volume is the summed contract volume across the filtered set; it is not exposed on individual rows.

Row fields (data[])

FieldTypeDescription
idstringOctagon event_id (primary key).
kpi_idstringStable across periods.
company_name, company_tickerstring | nullcompany_ticker is the stock symbol; null for uncurated events.
kpi_namestring | nullHuman-readable KPI name.
period, period_label, period_kindstring | nullMachine + human period + kind (best-effort; see Conventions).
statusstringactive | settled.
expected_report_datestring | nullExpected report date.
market_impliedKpiValueThe same market-implied central the detail response serves, read from a stored copy refreshed every 20 minutes; see market_implied_as_of for the figure's own timestamp. Where the refresh has not yet reached an event, it falls back to the most recent day of stored daily candles within 30 days, then to the stored snapshot.
market_implied_as_ofstring | nullThe moment the figure in market_implied describes — never the moment it was read, and never borrowed from another field. It follows whichever source answered: the refreshed copy carries the timestamp of the market observation it was resolved from; the candle fallback carries that candle's day; the stored-snapshot fallback carries that snapshot's capture time. It is present independently of market_implied: a row with no central still carries the snapshot time it would have stamped, so read the value's presence from market_implied, not from this field.
octagon_estimate_valueKpiValueOctagon model central estimate.
edge_absolute_valueKpiValueModel minus market, in KPI units.
edge_market_age_daysinteger | nullHow old the market side of edge_absolute_value is: whole days from market_implied_as_of to this row's snapshot time — not to the time of your request, so the number describes the figure rather than how long ago you fetched it. Truncated toward zero, so a gap under 24 hours reads 0; a market value stamped later than the snapshot also reads 0 rather than going negative. null when edge_absolute_value is null, or when either timestamp is missing — never a substituted 0, which would assert a freshness the data does not support.
actualKpiValue | nullSettled reported figure.
company_guidanceKpiValue | nullCompany-issued guidance for the KPI, when available.
model_probability, market_probability, edge_ppnumber | nullProbability-space signal (percentage points).
signalstring | nullabove_market | in_line | below_market.
near_settledbooleantrue when the market probability is ≥97% or ≤3% — the edge is settlement noise.
newsworthinessinteger0–100 desk sort key.
liquidity_tierstring | nullhigh | medium | low — replaces raw volume.
strike_count, strike_periodinteger / stringMarket structure summary (no ladder detail). strike_count is a count; strike_period is an upstream-formatted period string (e.g. "26Q2") — prefer period / period_label.
actual_sourcestring | nullPresent only when a trusted actual is served. A method label, e.g. company_report.
reported_atstring | nullWhen the result landed. Exact when the settlement/report time is known; otherwise the expected report date, then close time. Populates on settled rows independently of actual.
close_timestring | nullWhen the underlying markets close.

Get one KPI event

GET /predictions/kpi-events/{event_id}

Query Parameters

ParameterTypeRequiredDescription
include_historybooleanNoInclude the prediction_market_estimate.trend series. Default true.
selected_estimate_idstringNoPick a specific Octagon estimate run.
start_ts, end_tsintegerNoForecast window bounds, as Unix seconds.
period_intervalintegerNoTrend point spacing in minutes: 1440 for daily (default, day-aligned UTC) or 60 for hourly.
percentilesstringNoComma-separated list of percentiles (09999, up to 10). Adds a percentile_points map to each trend point, keyed by percentile with numeric KPI-unit values; the default fan is p25/p50/p75. The trend value itself is always the p50 series.

Both centrals are medians (p50), so edge_vs_market.direction agrees with probability_signal.edge_pp.

Response

jsonc
{
  "event_id": "hood_funded_customers_2026q2",
  "kpi_id": "hood_funded_customers",

  "company": {
    "name": "Robinhood Markets, Inc.",
    "ticker": "HOOD",            // stock symbol, NOT an upstream market id
    "exchange": "NASDAQ",
    "sector": "Financials",
    "industry": "Capital Markets"
  },

  "kpi": {
    "title": "Funded Customers",
    "description": "Funded Customers for Robinhood Markets, Inc.",
    "unit": "customers",
    "type": "accounts",          // subscribers|deliveries|dau|mau|orders|accounts|revenue|margin|units|members|passengers|transactions|headcount|other
    "directionality": "higher_is_better"
  },

  "period": {                    // best-effort; null when non-standard
    "label": "Q2 2026", "code": "2026q2", "kind": "fiscal_quarter",
    "start": "2026-04-01", "end": "2026-06-30"
  },

  "prediction_market_estimate": {          // source-agnostic; no ticker/book/raw volume
    "central": { "value": 28060000, "unit": "customers", "formatted": "28.06M" },
    "as_of": "2026-07-06T00:00:00Z",       // latest trend point
    "trend": [ {                                    // p50 over time
      "as_of": "2026-06-15T00:00:00Z",
      "value": 27500000,
      "percentile_points": { "25": 27100000, "50": 27500000, "75": 27900000 }  // only with ?percentiles=
    } ],
    "liquidity_tier": "high",
    "source": "aggregated_prediction_markets"
  },

  "octagon_model_estimate": {
    "central": { "value": 28700000, "unit": "customers", "formatted": "28.7M" },
    "confidence": 82,
    "as_of": "2026-06-30T20:00:00Z",
    "trend": [ { "as_of": "2026-06-28T00:00:00Z", "value": 28650000 } ],
    "methodology_url": "https://octagonai.co/methodology/kpi"
  },

  "actual": {                              // null until a TRUSTED actual exists (see lifecycle)
    "value": { "value": 28100000, "unit": "customers", "formatted": "28.1M" },
    "reported_at": "2026-08-28T20:00:00Z", // exact when known (settlement/report time); else approximate (expected report date → close time)
    "precision": "exact",                  // exact|rounded|range
    "range": null,                         // market-derived cross-check band when available
    "verified": true,                      // true only for company_report
    "sources": [ { "name": "Company report", "url": "https://investors.robinhood.com/" } ],
    "source_method": "company_report"      // octagon_deep_research|company_report|market_ladder_reconstruction|market_settlement_value
  },

  "analysis": {
    "edge_vs_market": {
      "value": -640000, "unit": "customers", "formatted": "-640K",
      "percent": -0.0223, "direction": "negative",
      "signal": "below_market",            // above_market|in_line|below_market
      "model_as_of": "2026-06-30T20:00:00Z",   // the compared values can be ~a day apart —
      "market_as_of": "2026-07-06T00:00:00Z"   // place the model dot by ITS as_of, never after a newer market point
    },
    "edge_vs_consensus": null,
    "surprise": null,                      // populated once settled and reported
    "model_accuracy": null,
    "near_settled": false,                 // true when the market prob is ≥97% or ≤3%
    "probability_signal": {                // time-attributed: each side carries its own as_of
      "model_probability": 62.0,
      "market_probability": 58.0,
      "edge_pp": 4.0,                      // = model_probability − market_probability
      "badge": "leads",                    // leads (model above market) | rich (market above model) | confirms (aligned)
      "model_as_of": "2026-06-30T20:00:00Z",
      "market_as_of": "2026-07-06T00:00:00Z"
    },
    "newsworthiness": 74
  },

  "editorial": {
    "status": "scheduled",                 // scheduled|imminent|reported|settled (reported = trusted actual served)
    "expected_report_date": "2026-08-28",
    "date_confirmed": false,
    "change_since_last": null,
    "headline": "Market sees Robinhood Markets, Inc. Q2 2026 Funded Customers near 28.06M; Octagon models higher at 28.7M",
    "summary": "Prediction markets imply ~28.06M for Robinhood Markets, Inc.'s Q2 2026 Funded Customers, while Octagon's model points to 28.7M.",
    "chart_url": null,
    "octagon_report_link": "https://octagonai.co/reports/hood_funded_customers_2026q2",
    "permalink": "https://octagonai.co/company-kpi-tracker/hood-funded-customers-2026q2",
    "tags": [],
    "peers": []
  },

  "as_of": "2026-07-07T00:00:00Z"
}

Settled events and actuals lifecycle

  1. activesettled on close. The event immediately appears under ?status=settled; actual is still null (awaiting the print).
  2. Actual capture, usually within a day of close. The source_method on the actual tells you how it was obtained:
    • market_settlement_value — the settlement venue published a clean numeric settlement figure that agrees with the market-derived range. Served as precision: exact (or rounded for abbreviated figures like 148.5M), with the cross-check range attached.
    • octagon_deep_research — no usable settlement figure, so the reported number is researched from primary sources (filings, shareholder letters) with citations in sources, cross-checked against the market range when one exists.
    • company_report — a directly-verified company figure (verified: true); reconciles or overwrites earlier methods when available.
  3. settledreported the moment a trusted actual is served; surprise (actual vs. the pre-report market median) populates on the detail response.

The trust gate: every researched actual is validated against market-derived bounds. A value that fails validation is never served — the event stays settled without an actual rather than showing a suspect number. Categorical markets (outcomes are names, not numeric thresholds — e.g., "which company ships the top model") never emit a numeric actual; they remain settled permanently.

Coverage & known gaps

The board tracks every KPI-tagged prediction market event (146 and growing as of July 2026):

  • Uncurated events return company_ticker: null and a derived company_name. Market/model estimates, edge, and signal populate regardless of curation.

Use Cases

  • Build a KPI reporting calendar or "earnings board" ranked by newsworthiness.
  • Surface where Octagon's model disagrees with the market (signal, edge_pp, edge_absolute_value) ahead of a print.
  • Track settled prints and surprises with ?status=reported and the detail response's analysis.surprise.
  • Power editorial workflows directly from the editorial block (headline, summary, permalink).
  • Monitor a single company KPI across periods via the stable kpi_id.

Notes

  • Edge values cached before July 2026 reflect a weighted-mean model central; expect a small one-time shift against current values.