changedOutput schema / (root)
Previous value: -nullNew value: +{
+ "properties": {
+ "available": {
+ "description": "False when no predictive bets[] have been computed for this event yet. forecasts[] can still populate on MLB/NFL/NCAAF/NBA/NCAAB/NHL. Free only when available is false and forecasts is empty.",
+ "type": "boolean"
+ },
+ "bets": {
+ "items": {
+ "properties": {
+ "alignment": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "attribution": {
+ "description": "Not published.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "best": {
+ "description": "Highest price-gap book across edges_by_book: {book, price, edge, quote_age_seconds}. Tier C informational line-shopping.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "bet_type": {
+ "description": "Canonical bet token, e.g. ML_HOME/ML_AWAY/ML_DRAW (soccer), ML_P1/ML_P2 (head-to-head sports), SPREAD_HOME/SPREAD_AWAY, OVER, UNDER.",
+ "type": "string"
+ },
+ "blend_w": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "computed_at": {
+ "description": "ISO-8601 UTC time this bet's numbers last materially changed — not when last checked. Rows are only rewritten when price, line, or probability moves beyond a tolerance, so an older value means 'unchanged since', not 'stale'. Differs between bets on one event because markets move independently.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "confidence_score": {
+ "description": "Not published. Use probability.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "coverage": {
+ "description": "Not published.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "drivers": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "edge": {
+ "description": "Expected profit per 1 unit staked at market.price. Null while no model-backed edge is published (Stage 1). Present on customer surface for recommend gating.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "edges_by_book": {
+ "description": "Price gap versus fair.probability per soft book (fair.probability × decimal_odds − 1). Line-shopping metric: rank soft books by gap.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "ev": {
+ "description": "Beta. Customer-facing EV estimate: {beta: true, book, price, ev_pct, kelly_fraction, quote_age_seconds, n_books}. Re-packages the same fair price gap for direct display. Moneyline only. n=1 Pinnacle is a valid fair (soccer/tennis). Null when the gap is ≤0, above 25% (stale-line), or only suppressed books remain (MLB ML × DK/FD proven null; BetMGM/Bet365/BetOnline unscreened).",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "fair": {
+ "description": "Sharp-consensus fair: {probability, books, n_books, is_consensus}. MLB/NFL: Pinnacle+Circa; MLS/tennis: Pinnacle. Price-gap reference for edges_by_book/best.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "fair_price": {
+ "description": "American-odds fair price implied by probability — the vig-free line. Compare to market.price for the book's margin on this side.",
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "interval": {
+ "description": "[lo, hi] band around probability — how much evidence backs the number, not a statistical confidence interval.",
+ "items": {
+ "type": "number"
+ },
+ "type": [
+ "array",
+ "null"
+ ]
+ },
+ "market": {
+ "description": "Market quote: {price: American odds, line: handicap/total line or null for moneyline, book: bookmaker slug when known (always set for probability-model sports)}.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "model_version": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "narrative": {
+ "description": "Not published.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "p_market": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis). Use probability/fair_price.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "p_model": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "phase": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "player_id": {
+ "description": "Set when this bet is about an individual player. Null for team bets and match-level tokens.",
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "player_name": {
+ "description": "Display name of the player or team this bet is about. Null for match-level tokens. Duplicates players[player_role].name.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "player_role": {
+ "description": "'home'/'away' or 'p1'/'p2'. Null for match-level tokens (OVER, UNDER, ML_DRAW).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "probability": {
+ "description": "Published probability for this outcome, 0-1. Outcomes of one market sum to 1. Customer surface for MLB, soccer, tennis, NFL.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "rationale": {
+ "description": "Not published. Top-level rationale is the event-level context overlay.",
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "signals": {
+ "description": "Not published.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "sufficiency": {
+ "description": "Internal — omitted from customer payloads (MLB/soccer/tennis).",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "team_id": {
+ "description": "Set when this bet is about a team. Null for match-level tokens (OVER, UNDER, ML_DRAW) — a draw is not a bet on either team, so summing exposure by team_id never double-counts it.",
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "tier": {
+ "description": "Confidence tier: 'very_high', 'strong', 'moderate', or 'avoid'. Null whenever edge is null. Present on MLB customer surface and all other shapes.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "validator": {
+ "description": "Not published.",
+ "type": [
+ "object",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "event_id": {
+ "description": "Lumify event ID this intelligence describes.",
+ "type": "integer"
+ },
+ "forecasts": {
+ "description": "Forecasted wagers for this event (same object as list_forecasts) — a model prediction, not a beat-the-market claim. Player-prop rows on team sports; tennis main-line via bet_type ML_P1/ML_P2 (moneyline), SPREAD_P1/SPREAD_P2 (game handicap), OVER/UNDER (total games). selected marks the top-conviction rows on the daily slate; the rest of the event catalog is included with selected:false. Read p_hit as P(the picked outcome hits). How + field catalog: https://lumify.ai/docs/forecasts",
+ "items": {
+ "properties": {
+ "away_team": {
+ "description": "Away team display name. Slate only.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "bet_type": {
+ "description": "Main-line token when this row is a main-line forecast — ML_P1/ML_P2/ML_HOME/ML_AWAY/ML_DRAW, SPREAD_P1/SPREAD_P2/SPREAD_HOME/SPREAD_AWAY, or OVER/UNDER (same vocabulary as get_intelligence bets[].bet_type and list_ev). Null on player-prop rows — that's the discriminator between the two row shapes. Tennis sets ML_P1/ML_P2 (moneyline), SPREAD_P1/SPREAD_P2 (game handicap), and OVER/UNDER (total games).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "books": {
+ "description": "American price for the picked outcome, keyed by bookmaker slug (e.g. {draftkings: -453}). Posted market price for the side/bet_type the model picked.",
+ "type": "object"
+ },
+ "commence_time": {
+ "description": "ISO-8601 UTC scheduled start. Slate only.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "conviction": {
+ "description": "Board rank key on 0–1: |p_hit−0.5|×2×sufficiency×research. A high p_hit on a thin sample ranks below a moderate p_hit on a long one. Highest conviction first on the daily slate.",
+ "type": "number"
+ },
+ "drivers": {
+ "description": "Signed contributions that moved p_hit. Read input as the measured rate/rating behind the pick and effect as how far it lifts the chosen outcome versus a baseline.",
+ "items": {
+ "properties": {
+ "direction": {
+ "description": "up / down / neutral from the sign of effect.",
+ "type": "string"
+ },
+ "effect": {
+ "description": "Signed shift in p_hit versus a baseline case on the same line. 0.0 on yardage markets.",
+ "type": "number"
+ },
+ "id": {
+ "description": "Prop rows: typically player.l10_rate — the recent-form rate that fed Poisson. Main-line rows would use a different namespace once a main-line forecast model ships.",
+ "type": "string"
+ },
+ "input": {
+ "description": "Measured rate/rating behind this driver, in native units.",
+ "type": [
+ "number",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "event_id": {
+ "description": "Lumify event ID. Present on list_forecasts; omitted on get_intelligence.forecasts (the event is the argument).",
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "home_team": {
+ "description": "Home team display name. Slate only.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "interval": {
+ "description": "[lo, hi] stated band around p_hit. Wider when sufficiency is low. A stated evidence band, not a statistical confidence interval.",
+ "items": {
+ "type": "number"
+ },
+ "type": "array"
+ },
+ "league": {
+ "description": "League slug, if any. Slate only.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "line": {
+ "description": "Posted line the model was scored against. Prop and totals main-line rows: Over/Under number. Spreads main-line rows: the spread number. Null on h2h/moneyline rows.",
+ "type": [
+ "number",
+ "null"
+ ]
+ },
+ "market": {
+ "description": "Player-prop rows: prop category (counting stats). MLB: strikeouts_pitcher, hits, rbis, runs, strikeouts_batter, hits_allowed, earned_runs, outs_recorded. NFL/NCAAF: passing/rushing/receiving_yards, receptions, passing_tds, rushing_tds, touchdowns (anytime-TD combo: rushing + receiving + defensive TDs). NBA/NCAAB: points, rebounds, assists, steals, blocks, threes_made. NHL: goals, hockey_assists, shots_on_goal. Main-line rows (bet_type set): the main-line family — h2h, spreads, or totals.",
+ "type": "string"
+ },
+ "model_version": {
+ "description": "Scorer version, e.g. forecast-v0.",
+ "type": "string"
+ },
+ "p_hit": {
+ "description": "Model probability (0–1) that the picked outcome (side on prop rows, bet_type on main-line rows) hits. Prop rows: built from the player's shrunken counting-stat rate (Poisson vs the posted Over/Under). Optional research may nudge a prop's p_hit by at most ±0.03; the chosen side stays the same.",
+ "type": "number"
+ },
+ "player": {
+ "description": "Player display name from the priced line. Null on main-line rows with no player attribution (bet_type is a match-level token like OVER/UNDER/ML_DRAW).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "player_id": {
+ "description": "Lumify player ID. Bound by exact / Jr-stripped name match. Null on main-line rows with no player attribution.",
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "player_role": {
+ "description": "'home'/'away' for team sports or 'p1'/'p2' for head-to-head sports, set only alongside a non-null bet_type. Null for player-prop rows and for match-level main-line tokens (OVER, UNDER, ML_DRAW).",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "reliability": {
+ "description": "Badge on this sport×market cell: emerging, moderate, high, or informational. v0 ships emerging for every wager.",
+ "type": "string"
+ },
+ "research": {
+ "description": "Optional Deep Research overlay on high-probability wagers (p_hit ≥ 0.80): {stance, conviction, note}. stance is validate / neutral / invalidate. note is the wager-level why. Validate / invalidate rows always carry a note. Validate nudges p_hit up by at most 0.03 and lifts conviction. Invalidate drops the wager from forecasts[] and the daily board — it is not a recommended pick. The chosen side stays. Null means read p_hit from the rate model alone.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "selected": {
+ "description": "True when this wager is on the daily board (top conviction). On get_intelligence the array includes selected and the rest of the event catalog.",
+ "type": "boolean"
+ },
+ "side": {
+ "description": "Prop rows: 'over' or 'under' — the more likely side given the player's shrunken rate versus line. Null on main-line rows — read the picked outcome from bet_type instead.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "sport": {
+ "description": "Sport slug. Slate only.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "sufficiency": {
+ "description": "Evidence weight on 0–1: n/(n+12), where n is the recent-form game count (typically L10). A player with 10 games has sufficiency ≈ 0.45. The wager still ships; this field tells you how much of p_hit is earned from this player's own boxes.",
+ "type": "number"
+ }
+ },
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "has_recommend": {
+ "description": "True when at least one bet meets the recommendation threshold; null when intelligence has not been computed. False while Edge is not published (current MLB/soccer/tennis Stage 1) — a recommendation requires a non-null tier derived from edge.",
+ "type": [
+ "boolean",
+ "null"
+ ]
+ },
+ "intelligence_updated_at": {
+ "description": "ISO-8601 UTC timestamp of the most recent change anywhere in this payload (max of per-bet computed_at). Use per-bet computed_at to reason about a specific bet.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "league": {
+ "description": "League slug for this event, if any.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "match_overview": {
+ "description": "Natural-language pre-game matchup preview — form, context, what to watch. Written before kickoff by a Search-backed overlay on every event sport (MLB, NFL, NCAAF, NBA, NCAAB, NHL, soccer, tennis); sport-shaped queries. The request path only reads the stored row. Null when the pre-kickoff job has not run or the fixture was not eligible.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "matchup": {
+ "description": "Not returned. Use get_stats for pitcher/lineup Data.",
+ "type": [
+ "object",
+ "null"
+ ]
+ },
+ "odds_source": {
+ "description": "Bookmaker bets[].market prices were sourced from. For probability-model sports this is the book the assessment was priced against, not a bookmaker overlay; per-bet market.book is authoritative if they ever differ.",
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "players": {
+ "description": "Home/away (or p1/p2) participant identification, keyed by role: {role: {name, player_id, team_id}}.",
+ "type": "object"
+ },
+ "rationale": {
+ "description": "Event-level factual pre-game matchup chips (injuries, recent form, lineup/availability news — sport-shaped). Written before kickoff; the request path only reads the stored row.",
+ "items": {
+ "type": "string"
+ },
+ "type": [
+ "array",
+ "null"
+ ]
+ },
+ "sport": {
+ "description": "Sport slug for this event.",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "type": "object"
+}