Appearance
Prediction Markets Events API
Retrieve Octagon's analyzed prediction market events over REST. The Events API exposes two endpoints:
- List events — the latest snapshot of every analyzed event, including model/market probabilities, confidence scores, analysis summaries, and per-market outcome breakdowns.
- Event history — the historical snapshots for a single event by ticker, for time-series analysis and backtesting.
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/v1List Events
GET /predictions/events
Returns the latest snapshot of every analyzed prediction market event tracked by Octagon, ordered by most recently captured first.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Number of records to return. Default 10; minimum 1; maximum 200. |
cursor | string | No | Cursor for pagination. Use the cursor returned from a previous response to continue. |
has_history | boolean | No | When true, only return events that have multiple historical snapshots available for time-series use. |
include | string | No | Comma-separated list of optional per-row field groups. Supported: eligibility (see below). |
Response Fields
Each event in the data array includes:
| Field | Type | Description |
|---|---|---|
history_id | integer | Unique identifier for this snapshot. |
run_id | string (UUID) | The export run that produced this snapshot. |
captured_at | string (ISO 8601) | When this snapshot was captured. |
event_ticker | string | Ticker identifier for the event. |
name | string | Human-readable event name. |
slug | string | URL-friendly slug. |
image_url | string | Event image URL. |
series_category | string | Category (e.g., "Politics", "Crypto", "Economics"). |
available_on_brokers | boolean | Whether the event is available on supported brokers. |
mutually_exclusive | boolean | Whether the event's outcomes are mutually exclusive. |
analysis_last_updated | string (ISO 8601) | When the analysis was last refreshed. |
confidence_score | float | Octagon's confidence in the model output (0–10 scale). |
model_probability | float | Octagon model probability for the event's primary/most-liquid market (0–100 percentage scale). See outcome_probabilities for the full per-market breakdown. |
market_probability | float | Market-implied probability for the event's primary/most-liquid market (0–100 percentage scale). See outcome_probabilities for the full per-market breakdown. |
edge_pp | float | Model edge in percentage points (model_probability - market_probability). See Interpreting the model probability. |
expected_return | float | Expected return if the model is correct. |
r_score | float | Risk-adjusted score. |
total_volume | float | Total trading volume. |
total_open_interest | float | Total open interest. |
close_time | string | When the event closes. |
key_takeaway | string | One-line summary of the model's view. |
current_state_summary_richtext | string | Rich-text summary of the current state. |
short_answer_richtext | string | Rich-text short answer. |
executive_summary_richtext | string | Rich-text executive summary. |
outcome_probabilities | array | Per-market outcome breakdown (see below). null if unavailable. |
has_history | boolean | Whether this event has multiple historical snapshots for time-series analysis. |
research | object | The catalyst and evidence layer, grouped (see below). Regroups content that also remains in its original fields — additive, nothing is removed or renamed. Absent on responses that carry no analysis. |
The response envelope also includes next_cursor and has_more for pagination.
Eligibility fields
Present only when include=eligibility is set:
| Field | Type | Description |
|---|---|---|
eligible | boolean | null | Whether a fresh report can be generated for this event. |
eligibility_status | string | null | Market state on the marketplace: open, paused, unopened, closed, settled, or unknown. |
eligibility_reason | string | null | Human-readable explanation for the eligible value. |
Generate fresh reports with the Reports API.
Event History
GET /predictions/events/{event_ticker}/history
Returns historical snapshots for a single prediction market event by its ticker, newest first.
Finding the event ticker in a Kalshi URL. A Kalshi event URL has the form /markets/<series-ticker>/<event-slug>/<event-ticker>. In https://kalshi.com/markets/kxfeddecision/fed-meeting/kxfeddecision-26jun, the event ticker is KXFEDDECISION-26JUN. Market deeplinks end in a market ticker instead, which is the event ticker plus an outcome suffix: strip the suffix to get the event ticker (kxoaianth-40-oai → KXOAIANTH-40).
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Number of records to return. Default 50; minimum 1; maximum 200. |
cursor | string | No | Cursor for pagination. Use the cursor returned from a previous response to continue. |
captured_from | datetime (ISO 8601) | No | Start timestamp filter (inclusive) for snapshot capture time. |
captured_to | datetime (ISO 8601) | No | End timestamp filter (inclusive) for snapshot capture time. |
include | string | No | Set to analysis to include the analysis fields in the response. |
days | integer | No | Exclude snapshots where close_time is before now minus this many days. Snapshots with no close_time are always included. Minimum 1. |
exclude_empty_model | boolean | No | When true, exclude snapshots where model_probability is null (incomplete analysis). Default true. |
Response Fields
Each snapshot in the data array includes:
| Field | Type | Description |
|---|---|---|
history_id | integer | Unique identifier for this snapshot. |
run_id | string (UUID) | The export run that produced this snapshot. |
captured_at | string (ISO 8601) | When this snapshot was captured. |
event_ticker | string | Ticker identifier for the event. |
name | string | Human-readable event name. |
slug | string | URL-friendly slug. |
series_category | string | Category (e.g., "Politics", "Crypto", "Economics"). |
close_time | string | When the event closes. |
confidence_score | float | Octagon's confidence in the model output (0–10 scale). |
model_probability | float | Octagon model probability for the event (0–100 percentage scale). |
market_probability | float | Current market-implied probability (0–100 percentage scale). |
edge_pp | float | Model edge in percentage points (model_probability - market_probability). See Interpreting the model probability. |
expected_return | float | Expected return if the model is correct. |
r_score | float | Risk-adjusted score. |
total_volume | float | Total trading volume. |
total_open_interest | float | Total open interest. |
outcome_probabilities | array | Per-market outcome breakdown (see below). null if unavailable. |
When include=analysis is set, these additional fields are included:
| Field | Type | Description |
|---|---|---|
key_takeaway | string | One-line summary of the model's view. |
current_state_summary_richtext | string | Rich-text summary of the current state. |
short_answer_richtext | string | Rich-text short answer. |
executive_summary_richtext | string | Rich-text executive summary. |
The response envelope also includes the requested event_ticker, plus next_cursor and has_more for pagination.
research object
The catalyst and evidence behind a report are spread across roughly 28 separate response fields — chart_anomalies_json, what_could_change_*, twenty q1..q5_* fields, and current_state_* — with nothing naming them as a set. research groups exactly that content under one key so a consumer can take the research layer without knowing which prefixes compose it.
This is additive. Every existing field keeps its name, type and meaning; research quotes them rather than replacing them, and is absent on responses that carry no analysis. Treat it as an optional field: read it if you want the grouped view, ignore it otherwise. Clients that validate against a strict schema (additionalProperties: false) will need the new key added to theirs — that is the one case where a change is required.
| Field | Type | Description |
|---|---|---|
catalysts.observed | array | Price moves the pipeline attributed to a cause. One entry per detected move. |
catalysts.forward | object | null | Forward-looking catalysts (subtitle, narrative, sources). |
evidence | array | Research findings as a list, one entry per populated slot — up to five, not always five (slot, question, findings, table, sources). |
current_state | object | null | Present-state summary (summary, sources). |
sources | array | Deduped roll-up of every citation in the block, in first-appearance order. |
catalysts.observed items
| Field | Type | Description |
|---|---|---|
date | string | ISO date of the move. |
date_readable | string | Same date, formatted for display. |
direction | string | spike or drop. |
change_pct | float | Size of the move in percentage points. |
price_before | float | Contract price before the move (0–100 scale). |
price_after | float | Contract price after the move. |
market_ticker | string | The market that moved. |
outcome_name | string | Human-readable outcome that moved. |
description | string | One-line summary of the move. |
narrative | string | null | Rendered HTML explaining the move, with inline citations. |
sources | array | Citations supporting this specific move. |
catalysts.forward object
Forward-looking catalysts — what could still move the outcome. null when the report carries none.
| Field | Type | Description |
|---|---|---|
subtitle | string | null | Section heading as generated, e.g. "Key Catalysts". |
narrative | string | Rendered HTML describing the catalysts, with inline citations. |
sources | array | Citations supporting this section (see sources items below). |
evidence items
One entry per research question the report answers. This groups the flat q1..q5_* fields rather than replacing them — those fields remain in the response unchanged, and slot says which one each entry came from.
| Field | Type | Description |
|---|---|---|
slot | string | Which slot the finding came from: q1 … q5. |
question | string | null | The research question. |
findings | string | null | Rendered HTML answering it, with inline citations. |
table | string | null | Supporting table as rendered HTML, when the finding has one. |
sources | array | Citations supporting this finding. |
Entries appear only for slots the report populated, so the array may hold fewer than five.
current_state object
Present-state summary for the event. null when the report carries none.
| Field | Type | Description |
|---|---|---|
summary | string | Rendered HTML describing the current state, with inline citations. |
sources | array | Citations supporting the summary. |
sources items
Citations are carried inline in the prose as anchors, which renders well and parses badly. Each entry lifts one out:
| Field | Type | Description |
|---|---|---|
url | string | An absolute http(s) URL. Relative paths, bare hosts, fragments, protocol-relative links and non-http schemes are dropped rather than returned. Absolute form is a syntax guarantee, not an availability one — a source may still 404 or move. |
title | string | null | Source title as cited. |
lanes | array | Which retrieval lanes surfaced it (e.g. traditional, curated). |
outcome_probabilities items
Each item in the outcome_probabilities array represents one market/outcome within the event:
| Field | Type | Description |
|---|---|---|
market_ticker | string | Ticker for this specific market/outcome. |
outcome_name | string | Human-readable name for the outcome. |
model_probability | float | Octagon model probability for this outcome (0–100 percentage scale). |
model_probability_source | string | Provenance of model_probability — see Interpreting the model probability. null on rows written before this field existed. |
evidence_grade | string | Evidence quality behind model_probability (A–D), which bounds how far it may deviate from the market-derived anchor. null when unavailable. |
market_probability | float | Market-implied probability for this outcome (0–100 percentage scale). |
Interpreting the model probability
model_probability is market-anchored: it starts from the contract's own market price and is adjusted for the research evidence on that outcome. It is a calibrated read on the price, not a second estimate derived independently of it — treat it as correlated with market_probability rather than as an independent opinion.
For a second opinion to weigh against your own model, use rows where model_probability_source is recalibrated and evidence_grade is A or B. Those are the rows where research evidence moved the value furthest from the market-derived anchor. Other combinations track the market price closely by construction.
ladder_model answers a narrower question. Its fitted parameters come from the ladder's own prices, so a rung is independent of its own quote but not of the market as a whole. Use it to compare rungs within a ladder — relative levels and ordering — rather than as an independent read on whether the ladder is priced correctly. The two fields:
model_probability_source | Meaning |
|---|---|
ladder_model | A threshold ladder priced from barrier-touch geometry. The value follows from the contract's own threshold, not its own quote — see Ladder-priced rows. |
recalibrated | Research evidence moved the value away from the market-derived anchor. |
market_baseline | The market price re-expressed. Carries no signal beyond the price. |
unmodeled / out_of_scope | Not modelled; do not read as a forecast. |
determined | The market has settled; the outcome is known. |
evidence_grade bounds the maximum deviation from the anchor, so a low grade means the value is close to the market price by construction regardless of what the research said:
| Grade | Maximum deviation from anchor |
|---|---|
A | ±20pp |
B | ±12pp |
C | ±7pp |
D | ±3pp |
Ladder-priced rows
On a threshold ladder — a set of contracts on the same underlying at different levels ("above $95,000", "above $120,000") — rows marked ladder_model are derived differently from every other source. One spot and one volatility are fitted to the ladder as a whole, and each rung's probability is then the first-passage probability of reaching its own threshold under that single view.
Two consequences that matter when you consume these:
- Two rungs quoted at the same price receive different probabilities, because the value follows from the threshold rather than from the quote. Contrast
market_baseline, where equal prices give equal model probabilities by construction. (recalibratedrows may differ at equal prices when their evidence differs, but nothing guarantees it — onlyladder_modelseparates them structurally.) - Ordering is guaranteed.
P(above $95k) >= P(above $120k)holds as an identity, not as a best effort, so you can rely on monotonicity across a ladder without re-sorting.
One limit, stated plainly: the fitted spot and volatility come from the ladder's own prices. A rung's value is independent of its own quote, but the ladder's overall level is still market-derived, so this will not tell you that an entire ladder is mispriced. Rows fall back to recalibrated or market_baseline whenever the fit does not describe the book.
Use Cases
- Discover all events currently tracked and analyzed by Octagon, or build a catalog/dashboard of active events.
- Monitor the latest model probabilities, confidence scores, and analysis across all events.
- Filter to events with historical data (
has_history=true), then drill into each event's time-series via the history endpoint. - Build time-series views of model vs. market probability for a specific event ticker.
- Backtest signal quality (for example,
edge_ppandexpected_return) across historical snapshots. - Backtest multi-outcome events using
outcome_probabilitiesper snapshot. - Track how confidence and liquidity metrics evolve as an event approaches resolution.
Notes
- On Event History, prefer bounded time windows (
captured_fromandcaptured_to) for predictable page sizes. - Probability and score scales follow the Kalshi Search API conventions.