{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/infersports-dev/json-schema/infersports-dev-find-value-result-schema.json",
  "title": "FindValueResult",
  "description": "One-call NL→value scan: where does a book beat the sharp de-vigged fair line?\n\nDETECTION ONLY (read-only): we surface the edge, not stakes or bet links. ``status`` is the\nsame go/no-go as get_sharp_line (ok | ambiguous | not_found; ambiguous never guessed). Requires\na sharp reference to de-vig — on the Free tier the sharp book (Pinnacle) is gated, so fair odds\nfall back to the tightest available book and ``note`` flags the reduced confidence.",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/infersports-dev-openapi.json#/components/schemas/FindValueResult",
  "properties": {
    "status": {
      "type": "string",
      "title": "Status"
    },
    "query": {
      "type": "string",
      "title": "Query"
    },
    "summary": {
      "type": "string",
      "title": "Summary"
    },
    "match": {
      "anyOf": [
        {
          "$ref": "#/$defs/MatchSummary"
        },
        {
          "type": "null"
        }
      ]
    },
    "value_bets": {
      "items": {
        "$ref": "#/$defs/ValueBet"
      },
      "type": "array",
      "title": "Value Bets"
    },
    "fair_source": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Fair Source",
      "description": "Bookmaker key whose de-vigged line was used as the fair reference."
    },
    "note": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Note",
      "description": "Caveats (e.g. Free tier: no sharp book, fair is approximate)."
    },
    "alternatives": {
      "items": {
        "$ref": "#/$defs/MatchAlternative"
      },
      "type": "array",
      "title": "Alternatives"
    },
    "ask_user": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Ask User"
    },
    "as_of": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "As Of"
    },
    "stale": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Stale",
      "description": "Freshness of the odds (W4); null if no match."
    },
    "decision": {
      "$ref": "#/$defs/Decision",
      "description": "Pre-computed go/no-go (W3): safe_to_proceed + suggested next_action."
    }
  },
  "type": "object",
  "required": [
    "status",
    "query",
    "summary",
    "decision"
  ],
  "$defs": {
    "Decision": {
      "properties": {
        "safe_to_proceed": {
          "type": "boolean",
          "title": "Safe To Proceed",
          "description": "True when the result is unambiguous enough to act on without asking the user."
        },
        "confidence": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "Confidence",
          "description": "Resolution confidence 0–1 (null when not applicable)."
        },
        "ask_user": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Ask User",
          "description": "A disambiguation question to put to the user; null when safe_to_proceed."
        },
        "next_action": {
          "anyOf": [
            {
              "$ref": "#/$defs/NextAction"
            },
            {
              "type": "null"
            }
          ],
          "description": "Suggested next call; null when the caller must ask first or nothing follows."
        }
      },
      "type": "object",
      "required": [
        "safe_to_proceed"
      ],
      "title": "Decision",
      "description": "Pre-computed go/no-go for the caller (W3): we decide whether it's safe to proceed so the\nagent doesn't have to reason it out (and risk guessing). Branch on ``safe_to_proceed``:\ntrue → act on the result without asking; false → put ``ask_user`` to the human, or follow\n``next_action`` when there's a clear recovery step (e.g. nothing resolved → list fixtures)."
    },
    "MatchAlternative": {
      "properties": {
        "event_id": {
          "type": "string",
          "title": "Event Id"
        },
        "label": {
          "type": "string",
          "title": "Label",
          "description": "'Home vs Away' label for disambiguation."
        },
        "confidence": {
          "type": "number",
          "title": "Confidence"
        }
      },
      "type": "object",
      "required": [
        "event_id",
        "label",
        "confidence"
      ],
      "title": "MatchAlternative",
      "description": "A runner-up fixture when a query is ambiguous."
    },
    "MatchSummary": {
      "properties": {
        "event_id": {
          "type": "string",
          "title": "Event Id",
          "description": "Canonical event id (evt_…); pass to get_match_odds / compare_lines."
        },
        "sport": {
          "type": "string",
          "title": "Sport",
          "description": "football | basketball"
        },
        "league": {
          "type": "string",
          "title": "League",
          "description": "League name, e.g. 'English Premier League'."
        },
        "home_team": {
          "type": "string",
          "title": "Home Team"
        },
        "away_team": {
          "type": "string",
          "title": "Away Team"
        },
        "scheduled_at": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Scheduled At",
          "description": "Kickoff, ISO-8601 UTC."
        },
        "scheduled_at_local": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Scheduled At Local",
          "description": "Kickoff in the requested timezone (ISO-8601); null when no timezone was given."
        },
        "status": {
          "type": "string",
          "title": "Status",
          "description": "scheduled | live | finished"
        },
        "score": {
          "anyOf": [
            {
              "$ref": "#/$defs/Score"
            },
            {
              "type": "null"
            }
          ],
          "description": "Current score when live, else null."
        },
        "red_cards": {
          "anyOf": [
            {
              "$ref": "#/$defs/Score"
            },
            {
              "type": "null"
            }
          ],
          "description": "Red cards per side; null when not tracked by upstream."
        },
        "clock": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Clock",
          "description": "Match clock when live, humanized for display: e.g. '1st half 25'', '2nd half 47'' (the real minute, not estimated) or 'half-time'; null pre-match or when the feed omits it. Basketball clocks (e.g. 'Q2 4:12') pass through as-is."
        },
        "confidence": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "Confidence",
          "description": "Fuzzy-match confidence 0–1 (find_match only; null elsewhere)."
        },
        "summary": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Summary",
          "description": "One-line human-readable status, e.g. \"Man City vs Arsenal — LIVE 1h 23 2-1.\" or \"… — Kicks off 18:00 UTC on Jun 01.\" — ready to read to a user."
        }
      },
      "type": "object",
      "required": [
        "event_id",
        "sport",
        "league",
        "home_team",
        "away_team",
        "status"
      ],
      "title": "MatchSummary",
      "description": "A fixture flattened for agent consumption (teams as names, optional live score)."
    },
    "NextAction": {
      "properties": {
        "tool": {
          "type": "string",
          "title": "Tool",
          "description": "Tool to call next, e.g. 'get_match_odds' | 'compare_lines' | 'list_today_matches'."
        },
        "args": {
          "additionalProperties": {
            "type": "string"
          },
          "type": "object",
          "title": "Args",
          "description": "Ready-to-use arguments for that call, e.g. {'event_id': 'evt_…'}."
        },
        "reason": {
          "type": "string",
          "title": "Reason",
          "description": "Why this is the suggested next step."
        }
      },
      "type": "object",
      "required": [
        "tool",
        "reason"
      ],
      "title": "NextAction",
      "description": "The single best next call to make, pre-computed so the agent doesn't have to plan it (W3)."
    },
    "Score": {
      "properties": {
        "home": {
          "type": "integer",
          "title": "Home"
        },
        "away": {
          "type": "integer",
          "title": "Away"
        }
      },
      "type": "object",
      "required": [
        "home",
        "away"
      ],
      "title": "Score"
    },
    "ValueBet": {
      "properties": {
        "market_type": {
          "type": "string",
          "title": "Market Type"
        },
        "period": {
          "type": "string",
          "title": "Period"
        },
        "line": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "Line",
          "description": "AH/totals line; null for 1x2."
        },
        "outcome": {
          "type": "string",
          "title": "Outcome",
          "description": "home | draw | away | over | under."
        },
        "bookmaker": {
          "type": "string",
          "title": "Bookmaker",
          "description": "The book offering the value price (its key)."
        },
        "price": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "integer"
            }
          ],
          "title": "Price",
          "description": "Best available price, in the requested format."
        },
        "decimal": {
          "type": "number",
          "title": "Decimal",
          "description": "That price in decimal (for comparison)."
        },
        "fair_price": {
          "type": "number",
          "title": "Fair Price",
          "description": "De-vigged fair decimal price from the sharp reference book."
        },
        "edge_pct": {
          "type": "number",
          "title": "Edge Pct",
          "description": "(decimal / fair_price − 1) × 100. Positive ⇒ +EV."
        },
        "format": {
          "type": "string",
          "title": "Format",
          "default": "decimal"
        }
      },
      "type": "object",
      "required": [
        "market_type",
        "period",
        "outcome",
        "bookmaker",
        "price",
        "decimal",
        "fair_price",
        "edge_pct"
      ],
      "title": "ValueBet",
      "description": "A single +EV outcome: a book's price exceeds the de-vigged fair price for that outcome."
    }
  }
}