Skip to main content
Glama

Lumify Sports Intelligence

Server Details

Schedules, scores, odds, splits & explainable AI bet confidence — 8+ sports, free instant key.

Ownership verified
Status
Healthy
Uptime
99.9% over 47 days
Last Tested
Transport
Streamable HTTP · MCP 2025-06-18
URL
Repository
lumifyai/lumify
GitHub Stars
7
Server Listing
Lumify Sports Intelligence

TDQS

A4.4/5.0

Scored across 28 tools

Disambiguation4/5

The tools map to mostly distinct data products: events, odds, props, scores, stats, players, teams, intelligence, forecasts, and identity resolution. The only mild overlap is between list_ev and list_forecasts, and somewhat between get_event and get_live_score, but the descriptions are detailed enough to guide correct selection.

Naming Consistency5/5

Tool names follow a consistent verb_noun pattern throughout: get_*, list_*, search_*, resolve_*, query_*, batch_get_*, estimate_*, and grade_*. There is no mixing of naming conventions or vague standalone verbs.

Tool Count4/5

28 tools is on the heavier side, but the sports intelligence domain is broad and each tool covers a distinct capability such as odds, props, stats, injuries, forecasts, grading, and entity resolution. No tool feels redundant, though the set could be streamlined by merging some very granular getters.

Completeness4/5

The set covers event discovery, live scores, odds and line movement, period/player/team props, statistics, intelligence, forecasts, EV opportunities, injury status, and slip grading. Minor gaps exist — no batch player/team fetch, no historical intelligence endpoint, and no webhook management — but core sports-data workflows are well covered.

Available Tools

28 tools
batch_get_eventsA
Read-onlyIdempotent
Inspect

Get multiple events by id in one call — for agents that already have a list of ids and want full detail for each without one call per event. Max 25 ids. Returns full detail for every id that exists plus a not_found list for any that don't (never billed). Use get_event for a single id, or list_events / query_events to discover ids first.

ParametersJSON Schema
NameRequiredDescriptionDefault
bookmakerNoBookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all.
event_idsYesEvent ids to fetch (max 25); duplicates are billed once.
include_oddsNoInline current odds scoped by bookmaker (default: pinnacle). Does not add credits — each found event stays 1 credit.
include_intelligenceNoInline bet intelligence on each event. Does not add credits.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
eventsNoFull event detail (same shape as get_event) for every found id.
not_foundNoRequested event_ids that don't exist. Never billed.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the max 25 id limit, the not_found list for missing ids, that not_found entries are never billed, and that include_odds/include_intelligence do not add credits. It also clarifies that duplicates are billed once, which is crucial for cost-sensitive agents.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero wasted words. The primary purpose is front-loaded, followed by the max limit, return behavior, billing nuance, and sibling alternatives. Every clause adds value, and the structure guides the agent from action to edge cases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that an output schema exists, the description doesn't need to enumerate return fields. It covers the critical contextual points: id list requirement, max 25, not_found behavior, billing implications, and when to use siblings. The description fully equips an agent to decide and call correctly without missing prerequisites or caveats.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented in the input schema. The description does not add new parameter-specific meaning beyond what the schema provides; it restates the max 25 limit and duplicates-billed-once, which are also in the schema. Baseline of 3 applies because the schema fully covers parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb+resource ('Get multiple events by id in one call') and immediately distinguishes it from sibling tools by stating it's for agents that already have ids and want full detail without one call per event. It also names the sibling alternatives (get_event, list_events, query_events) and explains the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('for agents that already have a list of ids') and when not to, naming the alternatives: 'Use get_event for a single id, or list_events / query_events to discover ids first.' This is clear guidance with no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimate_costA
Read-onlyIdempotent
Inspect

Estimate the credit cost of one or more planned tool calls before making them — no credits are spent. Costs are data-dependent (e.g. odds/intelligence/splits not yet ingested for an event are free, and batch_get_events ids that don't exist cost nothing), so this returns a [min_credits, max_credits] range per call rather than a single number. Pass the exact tool name and arguments you're considering, e.g. {"tool": "get_event", "arguments": {"event_id": 123, "include_odds": true}}.

ParametersJSON Schema
NameRequiredDescriptionDefault
callsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
estimatesNo
total_max_creditsNo
total_min_creditsNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description adds valuable behavioral detail: no credits are spent, results are a [min_credits, max_credits] range, costs are data-dependent, and specific free-call cases are given. This goes well beyond the structured safety hints and enriches the agent's mental model.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences accomplish all goals: purpose, behavior, and usage example. Nothing is redundant; every sentence carries essential information. The structure is front-loaded with the core function and then elaborates with context and a concrete example.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (array input, max 50 items) and the presence of an output schema, the description fully covers what an agent needs to invoke it correctly: the input format, the output format (range), and special cost edge cases. No critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by explaining the required 'calls' array structure, the 'tool' and 'arguments' fields, and providing a concrete JSON example. The agent knows exactly what to pass without needing to infer from a bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Estimate') and resource ('credit cost of planned tool calls'), making it unmistakable. It explicitly states 'before making them' and 'no credits are spent,' distinguishing it from all sibling tools that actually fetch data. This is a model of clear purpose differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly conveys when to use the tool (before executing calls, to estimate cost) and provides a usage example. However, it does not explicitly state when not to use it or name alternatives. The context makes the use case obvious, but explicit exclusion guidance is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_eventA
Read-onlyIdempotent
Inspect

Get a single event with participants and venue. Optionally inline current odds and/or bet intelligence (same 1 credit as the event call). Raises a not-found error if event_id doesn't exist. Use list_events / query_events to discover ids first, or batch_get_events to fetch several ids in one call.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.
bookmakerNoBookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all.
include_oddsNoInline current odds scoped by bookmaker (default: pinnacle). Does not add credits — the event call stays 1 credit.
include_intelligenceNoInline bet intelligence. Does not add credits.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNo
nameNo
sportNo
venueNo
leagueNo
statusNo
starts_atNo
updated_atNo
participantsNo
inprogress_sinceNoISO-8601 UTC when status first became inprogress (first live tick). Null until then; stays set after final.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds valuable context beyond annotations: it states that a not-found error is raised for invalid ids and that inlining odds/intelligence does not add credits. This enriches the behavioral profile without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core purpose, then covers alternatives and error behavior efficiently. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has an output schema, the description need not explain return values. It covers discovery, batching, error handling, and credit semantics. Nothing an agent needs to correctly invoke it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful extra semantics by noting that include_odds and include_intelligence do not increase the credit cost, which is not present in the schema. This justifies a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Get' and the resource 'a single event with participants and venue', which is specific and distinguishes it from batch_get_events, list_events, and query_events. It also mentions optional inlining of odds and intelligence, further clarifying scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs the agent to use list_events/query_events to discover ids first, or batch_get_events for multiple ids. It also clarifies when to use this tool versus alternatives, which is exactly what usage guidelines require.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_injuriesA
Read-onlyIdempotent
Inspect

Beta. Get late-breaking player injury and availability status for an event (out / doubtful / questionable / probable / day_to_day / ir / suspended / available), with previous_status, body_part, note, source_url, and severity (info / material / critical). Beta coverage: NFL and MLB (more sports rolling out). NFL monitoring starts ~4.5 days before kickoff (Wednesday/Thursday practice reports); MLB stays on a 48-hour window. Returns available:false with no charge until the injury monitor has written a first structured report. Checks run on cadence, on a significant main-market odds move, and at a guaranteed pre-kickoff checkpoint. Subscribe to webhook event_type=injury for material/critical changes. No in-game feed. Use exclude_status to drop noisy long-standing designations (e.g. ir) from the response — does not affect available or credit cost.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.
exclude_statusNoComma-separated statuses to drop, e.g. "ir" to hide injured-reserve/long-term-IL rows (long-standing roster designations, not late-breaking news). Valid values: out, doubtful, questionable, probable, day_to_day, ir, suspended, available.

Output Schema

ParametersJSON Schema
NameRequiredDescription
event_idNo
injuriesNoPer-player rows: player, player_id, team, team_id, status, previous_status, body_part, note, source_url, severity, last_changed_at. team/team_id prefer the player's current roster team when that team is a participant in this event.
availableNo
confirmed_atNo
next_check_atNo
last_checked_atNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even with annotations already marking readOnly/openWorld/idempotent, the description adds substantial behavioral detail: beta status, league coverage windows, the 'no charge' behavior before a first structured report, polling triggers, the absence of an in-game feed, and the non-effect of exclude_status on availability or credit. This goes well beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence contributes operational knowledge an agent needs. It is front-loaded with the primary purpose and then efficiently covers coverage, timing, webhooks, and parameter behavior without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is exceptionally complete for a complex data tool: it covers availability semantics, timing, charge behavior, update triggers, webhook subscription, limitations, and parameter nuances. The presence of an output schema means return-value documentation is handled elsewhere, so no essential calling context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both parameters. The description adds extra semantic value for exclude_status, explaining its purpose as dropping noisy long-standing designations and clarifying that it does not affect availability or credit, which is not evident from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Get late-breaking player injury and availability status for an event,' naming a specific verb, resource, and scope. It also enumerates the specific statuses and fields returned, and it is clearly distinct from sibling tools like get_event or get_player because it targets injury intelligence.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides strong contextual guidance: Beta coverage is limited to NFL and MLB, with specific monitoring windows and cadence. It also explains when the tool may return 'available:false' and directs users to webhooks for material/critical changes, though it does not explicitly contrast with alternative tools since no direct sibling exists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_intelligenceA
Read-onlyIdempotent
Inspect

Get predictive bet intelligence for an event: vig-stripped probability, fair_price, Price overlay, main-line ev (Beta), and forecasts[] — forecasted wagers from the model (same objects as list_forecasts): player props plus high-confidence main-line picks on tennis, NFL, NCAAF, MLB, and soccer. bets[] is live for MLB, tennis, soccer (MLS + big-five), NFL, and NCAAF. forecasts[] covers MLB, NFL, NCAAF, NBA, NCAAB, NHL, tennis, and soccer and can populate when available is false. Fair-price + line-shopping on bets[] today (edge/tier null; has_recommend false). bookmaker is ignored. Match-level tokens (OVER, UNDER, ML_DRAW) have null player/team attribution. Free only when available is false and forecasts is empty. Field catalog: https://lumify.ai/docs/reference#event-intelligence

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.
bookmakerNoIgnored. Intelligence always reports the book the assessment was priced against. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada.

Output Schema

ParametersJSON Schema
NameRequiredDescription
betsNo
sportNoSport slug for this event.
leagueNoLeague slug for this event, if any.
matchupNoNot returned. Use get_stats for pitcher/lineup Data.
playersNoHome/away (or p1/p2) participant identification, keyed by role: {role: {name, player_id, team_id}}.
event_idNoLumify event ID this intelligence describes.
availableNoFalse 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.
forecastsNoForecasted wagers for this event (same object as list_forecasts) — a model prediction, not a beat-the-market claim. Player-prop rows on team sports; high-confidence main-line picks on tennis, NFL, NCAAF, MLB, and soccer via bet_type (ML_P1/ML_P2/ML_HOME/ML_AWAY/ML_DRAW, SPREAD_*/OVER/UNDER). selected marks the pick — high-confidence main-lines and the top-conviction prop rows on the daily slate. Coin-flip main-lines are not picked. A selected main-line research.note is copied to bets[].narrative. Read p_hit as P(the picked outcome hits). How + field catalog: https://lumify.ai/docs/forecasts
rationaleNoEvent-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.
odds_sourceNoBookmaker 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.
has_recommendNoTrue 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.
match_overviewNoNatural-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.
intelligence_updated_atNoISO-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.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/openWorld/idempotent annotations by disclosing real behavioral quirks: bookmaker is ignored, match-level tokens have null player/team attribution, edge/tier are null with has_recommend false today, and 'Free only when available is false and forecasts is empty.' This is exactly the kind of context annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place — sports coverage, pricing mode, free condition, attribution, and docs link are all material — but the prose is a rambling run-on structure with nested dashes, colons, and inconsistent capitalization ('Price overlay', 'main-line ev (Beta)'). Front-loading is adequate (purpose first), but readability suffers.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex predictive tool, the description covers the decision-relevant facts: sports coverage per array, live vs. populate conditions, free-access condition, ignored parameter, and null-attribution behavior, plus a field-catalog link. With an output schema present, it doesn't need to spell out return values; the main ambiguity is what 'available' means and what happens when the call is not free.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents event_id and the ignored bookmaker parameter; the description merely reinforces that bookmaker is ignored without adding new semantics. Baseline 3 is appropriate because the schema carries the load and the description adds nothing beyond it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'Get predictive bet intelligence for an event' — and enumerates the payload (vig-stripped probability, fair_price, main-line ev, forecasts[]), which clearly differentiates it from siblings like get_odds, get_event, and list_forecasts. Explicitly cross-references list_forecasts ('same objects as list_forecasts'), making the scope obvious.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides rich context on when the tool is useful — which sports bets[] is live for, which sports forecasts[] covers, and the condition under which forecasts can populate ('when available is false'). It lacks explicit exclusions or routing to alternatives (e.g., when to use get_odds instead), so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_live_scoreA
Read-onlyIdempotent
Inspect

Get a lightweight live score snapshot for an event: status, period, clock, per-participant score and period-by-period scores, and last-updated time. Cheaper and faster than get_event when you only need the score, not participants or venue. Capped at 20 calls/min per key (shared with GET /v1/events/{id}/score and list_events include_scores=true). For live updates prefer the SSE stream. Raises a not-found error if event_id doesn't exist.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
clockNo
periodNo
scoresNo
statusNo
event_idNo
finishedNo
updated_atNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, but the description adds material operational context they do not cover: a 20 calls/min per-key cap shared with two other endpoints, a preference for the SSE stream under live updates, and a not-found error when event_id is invalid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences with the payload, the cost/sibling comparison, the rate limit, and the error condition front-loaded in that order. No filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-field detail need not be re-explained; the description still summarizes the payload shape. Rate limiting, error behavior, and the streaming alternative are all covered, leaving nothing an agent needs to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Single required parameter with 100% schema description coverage, so the schema already documents event_id and its provenance (list_events, query_events, search results). The prose adds nothing beyond that, which is the expected baseline when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource (get a live score snapshot) and enumerates the returned fields (status, period, clock, per-participant score, period scores, last-updated). It explicitly contrasts itself with the sibling get_event, so an agent can separate the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States when to choose this over the alternative ("cheaper and faster than get_event when you only need the score, not participants or venue") and names a third option for live updates ("prefer the SSE stream"). Both a selection condition and an exclusion are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_oddsA
Read-onlyIdempotent
Inspect

Get current betting odds for an event: per-bookmaker lines and last-updated time. Includes in-play quotes while the event is underway; books that have not quoted since kickoff are omitted. bookmaker defaults to pinnacle. Use 'all' or a comma-separated list for multiple books — still 1 credit. Default is main lines (is_main=true); set include_alts for alternate spread/total rungs. Final events include result (won/lost/push/void) graded from the pre-kickoff close. MLB, tennis, and soccer (MLS + big-five) mains also include fair_price and consensus mirrored from published assessments. Returns available:false with no charge if odds aren't posted for this event yet. If bookmaker is omitted and Pinnacle hasn't posted a line yet (common for the first/last games of a preseason slate), falls back to the best-covered other book and adds requested_bookmaker='pinnacle' plus fallback_bookmaker to the response instead of reporting no odds; an explicit bookmaker='pinnacle' never falls back. Use get_odds_history for line movement over time.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.
bookmakerNoBookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list.
include_altsNoInclude alternate spread/total rungs. Default false (mains only).

Output Schema

ParametersJSON Schema
NameRequiredDescription
event_idNo
availableNo
bookmakersNoPer-book markets. Outcomes include is_main. In-play omits books that have not quoted since kickoff. Final events add result (won/lost/push/void) and close on the pre-kickoff point.
last_updatedNo
fallback_bookmakerNoThe book actually returned when requested_bookmaker is present.
requested_bookmakerNoPresent only when the default (no bookmaker arg) request fell back to a different book because Pinnacle has no line yet — always 'pinnacle' when present.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this read-only and idempotent, but the description adds substantial behavioral detail beyond that: no-charge available:false responses, fallback to another bookmaker, credit cost for multiple books, omission of books that have not quoted since kickoff, and result grading from pre-kickoff close. This is far more than the annotations alone provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded with the core purpose, and every sentence adds useful operational or behavioral context. No filler is present, and the detail about fallback, credits, and alternatives earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the existence of an output schema, the description is complete enough for correct invocation. It covers defaults, edge cases (unposted odds, preseason slates), in-play behavior, final-event results, and related tools, leaving no critical ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes well beyond the schema: it explains 'all' and comma-separated lists cost 1 credit, clarifies the default main-lines behavior, and documents the fallback semantics when bookmaker is omitted. This adds meaning that the schema does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get current betting odds for an event: per-bookmaker lines and last-updated time.' It clearly defines the tool's scope and distinguishes it from get_odds_history by directing line-movement queries to that sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit usage context: defaults, multi-book selection, in-play behavior, final-event result grading, and a clear alternative ('Use get_odds_history for line movement over time'). It also explains fallback behavior when Pinnacle has no posted line, which helps the agent decide when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_odds_historyA
Read-onlyIdempotent
Inspect

Get line-movement history for an event: a list of past odds snapshots (movements), each with its own timestamp, up to limit entries. bookmaker defaults to pinnacle. Use get_odds instead if you only need the current line.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax line-movement entries to return. Default 50.
event_idYesEvent id, from list_events, query_events, or search results.
bookmakerNoBookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
event_idNo
movementsNoOdds snapshots over time; each entry carries its own timestamp.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is covered. The description adds useful context about the output structure (list of movements with timestamps) and the limit behavior. It does not mention ordering or pagination details, but given the annotation coverage, this is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero fluff. The main purpose is front-loaded, the default is stated, and the alternative is given. Every word earns its place; the description is efficient and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with three parameters (one required), 100% schema coverage, an output schema present, and rich annotations, the description covers everything an agent needs to invoke it correctly. It explains what the tool returns, the default bookmaker, and when to use a sibling. No critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: all three parameters (limit, event_id, bookmaker) are fully documented with defaults and valid values. The description adds only marginal clarification (e.g., 'up to limit entries' and 'bookmaker defaults to pinnacle'), which essentially restates schema information. Baseline 3 is appropriate since the schema already does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the specific verb and resource: 'Get line-movement history for an event' and describes the output as 'a list of past odds snapshots (movements), each with its own timestamp.' It explicitly distinguishes from sibling get_odds by saying 'Use get_odds instead if you only need the current line.' This leaves no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage guidance by naming the alternative (get_odds) and the condition for choosing it ('if you only need the current line'). It also mentions the default bookmaker, which sets expectations for typical use. No exclusions are needed beyond the single alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_period_oddsA
Read-onlyIdempotent
Inspect

Get first-half / first-five / first-set lines and live progress for an NFL, NCAAF, NBA, NCAAB, MLB, soccer, or tennis event. Joins persisted first_half_spreads / first_half_totals mains to this-event period scores (1H = Q1+Q2, NCAAB or soccer native 1H; MLB F5 = innings 1–5; tennis S1 = first-set games) and grades the period, not the full game. GET /odds / get_odds stay on moneyline/spread/total. Returns available:false with no charge if no period mains have been ingested. Other sports return HTTP 400.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
clockNoGame clock from the live score snapshot.
sportNoSport slug: nfl, ncaaf, nba, ncaab, mlb, soccer, or tennis.
periodNoCurrent period from the live score snapshot.
statusNoEvent status (scheduled, inprogress, delayed, final, …).
event_idNoLumify event ID.
availableNoFalse when no first-half / first-five / first-set mains have been ingested; period_odds is empty and the call isn't billed.
period_oddsNoOne row per (scope, market, line). Fields: scope (1H, F5, or S1), market (first_half_spreads / first_half_totals), line (home-perspective for spreads), home_score, away_score, current (totals only), current_margin (spreads only), pct_of_line, settleable, scope_complete, result (totals), home_result / away_result (spreads), books ({book_slug: {home, away} or {over, under}}).

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only/idempotent/non-destructive, and the description adds meaningful behavior beyond that: it joins persisted period mains to live scores, grades the period rather than the full game, explains the no-charge available:false state, and documents the HTTP 400 restriction. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place and the main purpose is front-loaded. The description is somewhat dense and the phrase 'GET /odds / get_odds' is slightly awkward, but overall it is efficiently structured for the amount of domain nuance it conveys.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of period definitions and sport-specific rules, the description is remarkably complete. It covers supported sports, how period scores are computed, the difference from full-game grades, the no-charge empty state, and the error case. With an output schema present, nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% coverage for the single required parameter, event_id, and already explains where it comes from. The description does not add parameter-specific detail, but the schema carries the full burden, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a specific resource ('first-half / first-five / first-set lines and live progress'), and the sports covered. It explicitly distinguishes itself from get_odds, which stays on moneyline/spread/total, so an agent can immediately tell what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says when to use this tool: when period-specific lines/progress are needed, not full-game odds. It names the alternative (GET /odds / get_odds) and gives exclusion signals such as 'Other sports return HTTP 400' and 'available:false with no charge if no period mains have been ingested.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_playerA
Read-onlyIdempotent
Inspect

Get a single player identity profile: name, sport, country, position/handedness, physical stats, current team, rankings (tennis {singles, points}; null on every other sport), and image_url (Lumify media URL, null until the sport's headshot/enrichment job). Raises a not-found error if player_id doesn't exist. Resolve ids via search_players.

ParametersJSON Schema
NameRequiredDescriptionDefault
player_idYesPlayer id, from search_players.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNoLumify player ID.
slugNoURL-safe unique slug.
sportNoSport slug, e.g. mlb, tennis, nfl.
positionNoRoster position abbreviation when the sport has one (e.g. C, P, SS for MLB; QB, WR for NFL). Null for tennis and when not yet ingested.
rankingsNoSport ranking block. Tennis: {singles, points} from ATP/WTA standings. Null for every other sport. Tennis /stats also exposes ranking / ranking_points on the tennis player block.
birthdateNoYYYY-MM-DD date of birth.
full_nameNoDisplay name.
height_cmNoHeight in centimetres. Null when not ingested.
image_urlNoLumify media URL for the player headshot (https://lumify.ai/media/players/{sport}/{id}.{ext}). Null until the sport's headshot/enrichment job. Never a vendor CDN.
is_activeNoFalse when deactivated or retired.
last_nameNo
weight_kgNoWeight in kilograms. Null when not ingested.
first_nameNo
handednessNoleft | right | switch. Meaning is sport-specific (bats for MLB, shoots for NHL, playing hand for tennis). Null when unknown.
retired_atNoYYYY-MM-DD retirement date when known.
country_codeNoISO 3166-1 alpha-3 country code.
current_team_idNoLumify team ID when the player is on a club roster. Null for tennis.
current_team_nameNoCurrent team display name. Null for tennis.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, idempotent, non-destructive), the description discloses important runtime behavior: it raises a not-found error for invalid player_id, and it explains null semantics for rankings on non-tennis sports and image_url before enrichment. This gives the agent accurate expectations for edge cases and return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense but well-structured and front-loaded. Every sentence earns its place: the first defines the tool and its output fields, the second states error behavior, and the third gives id resolution guidance. There is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single required parameter, a high-coverage schema, an output schema, and strong annotations, the description is complete. It covers the return payload's special cases, the error case, and how to obtain a valid player_id. An agent has everything needed to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents player_id with 100% coverage, including 'from search_players.' The description reinforces this by saying 'Resolve ids via search_players,' but it does not add meaningful new parameter semantics beyond what the schema provides. The error behavior is useful context but is more behavioral than parameter-specific.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Get a single player identity profile', then enumerates the fields returned (name, sport, country, position/handedness, physical stats, current team, rankings, image_url). It clearly distinguishes from siblings like get_team, get_player_events, and get_player_props by scoping the tool to identity/profile data rather than events, odds, or props.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: to retrieve a single player's identity profile, and it explicitly routes id resolution via search_players. It does not explicitly state when not to use it or name alternatives for events/props, but the profile-scoped wording and the mention of search_players provide adequate guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_player_eventsA
Read-onlyIdempotent
Inspect

List a player's events (schedule/results), paginated by id (after_id). Defaults to ±30 days around today when no date filter is given. Resolve player_id via search_players first.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoEnd date YYYY-MM-DD.
fromNoStart date YYYY-MM-DD.
limitNoMax events to return per page.
statusNoFilter to events in this status.
after_idNoCursor: last event id from the previous page's next_after_id.
player_idYesPlayer id, from search_players.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoEvents in the same shape as list_events' EventSummary.
has_moreNo
player_idNo
next_after_idNoPass as after_id to fetch the next page; null on the last page.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only and idempotent. The description adds useful behavioral details: pagination by after_id and the default ±30-day date window when no filter is provided. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, front-loaded with the core action. Every clause adds value: scope, pagination, default window, and prerequisite. Zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and rich annotations, the description doesn't need to detail return format or safety. It covers core behavior, pagination, defaults, and the player_id prerequisite, making it complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema descriptions cover 100% of parameters, including player_id origin and after_id cursor semantics. The description reiterates these but doesn't add substantially new parameter-level information beyond connecting the pagination flow.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists a player's events, with 'player's' distinguishing it from broader event tools. The parenthetical (schedule/results) and pagination mention add specificity. This is a specific verb+resource+scope, meeting the top criteria.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: it's for retrieving a specific player's events, and instructs to resolve player_id via search_players first. However, it does not explicitly contrast with alternative event-listing tools like list_events or query_events, so it lacks explicit exclusions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_player_propsA
Read-onlyIdempotent
Inspect

Get player-prop lines and live progress for an NFL, NCAAF, NBA, NCAAB, NHL, MLB, or soccer event. Joins persisted player-prop mains to this-event player box counts and grades over/under/push (1:1 slugs, combo sums including rush+rec and pass+rush yards, weighted total bases, anytime TD, double-double/triple-double, hockey points). Sport × market catalog: https://lumify.ai/docs/player-props. GET /odds / get_odds stay on moneyline/spread/total. Returns available:false with no charge if no prop mains have been ingested. Other sports return HTTP 400.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
clockNoGame clock from the live score snapshot.
sportNoSport slug: nfl, ncaaf, nba, ncaab, nhl, or mlb.
periodNoCurrent period from the live score snapshot.
statusNoEvent status (scheduled, inprogress, delayed, final, …).
event_idNoLumify event ID.
availableNoFalse when no player-prop mains have been ingested; player_props is empty and the call isn't billed.
player_propsNoOne row per (player, market, line). Fields: player, player_id (null if unmatched), market (prop category), line, current (this-event box count), pct_of_line, settleable, result (in_progress / over / under / push / dnp — box landed and this player has zero rows / no_stat — played but this slug never landed, unmatched, or box not landed yet; null when not settleable), books ({book_slug: {over, under}} American prices).

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld/idempotent annotations, the description discloses no-charge behavior, available:false semantics, HTTP 400 for unsupported sports, and the joined/grading logic. These are concrete behavioral traits not inferable from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

First sentence front-loads purpose, and each subsequent sentence earns its place: market catalog, sibling distinction, no-charge condition, and error behavior. No waste or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Description covers what the tool returns, which sports are supported, behavior when data is absent, HTTP error cases, and where to find the full catalog. Since an output schema and annotations exist, the description does not need to explain return values or safety traits.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter event_id is fully documented in the schema, so baseline is 3. The description adds sport restrictions and error behavior for invalid event types, adding meaning beyond the schema's generic 'from list_events' source.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a specific verb and object: 'Get player-prop lines and live progress' for a defined set of sports. It clearly scopes the resource and differentiates itself from get_odds by stating that odds endpoints stay on moneyline/spread/total.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells an agent to use get_odds for non-player-prop markets, and states when the tool returns available:false or HTTP 400. This gives clear conditions for selecting this tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_splitsA
Read-onlyIdempotent
Inspect

Get public betting splits (bets% and handle%) for an event: a consensus split plus a per-bookmaker breakdown (bookmakers[].bookmaker uses the same odds slugs as get_odds, e.g. draftkings — not upstream short keys like dk), with a captured_at timestamp. Available for MLB, NBA, NHL, NFL, NCAAF, and NCAAB. Not available for tennis or soccer (upstream 400). Returns available:false with no charge if splits haven't been captured for this event yet or the sport is unsupported.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
event_idNo
availableNo
consensusNoAggregate bets%/handle% across bookmakers.
bookmakersNoPer-bookmaker splits. Each item has bookmaker (odds slug), name, moneyline, spread, total.
captured_atNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, openWorld, idempotent, and non-destructive behavior. The description adds valuable detail beyond that: no charge when splits are unavailable, upstream 400 errors for unsupported sports, and the bookmaker slug mapping convention relative to get_odds.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the core purpose, followed by availability and fallback behavior. The first sentence is long with parentheticals, but every part earns its place; it could be slightly restructured for readability without losing content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only tool with an output schema, the description is complete: it states what is returned, which sports are supported, when no data is available, and the billing behavior. No critical calling context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully covers the only required parameter, event_id, with guidance to source it from list_events, query_events, or search results. The description does not add extra parameter-level meaning beyond what the schema already provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with a specific verb and resource: 'Get public betting splits (bets% and handle%) for an event'. It clearly distinguishes the tool from siblings like get_odds by describing the exact data returned: consensus split, per-bookmaker breakdown, and captured_at timestamp.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context by listing supported sports (MLB, NBA, NHL, NFL, NCAAF, NCAAB) and explicitly stating tennis and soccer are not available. It also explains when the tool returns available:false, but it does not name an alternative tool or explicitly say when to prefer get_splits over get_odds.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_statsA
Read-onlyIdempotent
Inspect

Get raw, deterministic team/match statistics for a soccer, MLB, tennis, NFL, NCAAF, NBA, NCAAB, or NHL event — no odds (use get_odds) and no scoring (use get_intelligence). Payload is sport-specific: teams.home/away except tennis (players.player_1/player_2). Tennis doubles/qualifying return available:false. Form/record/H2H exclude walkovers and NFL/NCAAF/NBA/NCAAB preseason. Other sports return HTTP 400. Field catalog: https://lumify.ai/docs/reference#event-stats

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
matchNoTennis only. Match context: surface, competition_id/name, tier, round (ingested labels like 'Round of 16'/'Quarterfinal'/'Final', not 'R16'), court (not currently populated), status, result_type, scoreboard (sets_won + per-set games; tiebreak_score not currently populated).
teamsNoSoccer/MLB/NFL/NCAAF/NBA/NCAAB/NHL only (home/away). Each side includes image_url (Lumify media URL, null until ingest; never a vendor CDN). Soccer: recent_form, team_strength, venue, rest_days, sos, lineup, rates_l5, rates_season. MLB: record, recent_form, rest_days, rates_l5/rates_season (incl. OBP/SLG/OPS/RBI/TB), starting_pitcher (post-box only), lineup, player_box (this event's per-player batting/pitching counting stats; final, in-progress, and delayed when rows exist). NFL/NCAAF: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (total/passing/rushing yards, attempts, turnovers, third_down_pct), player_box (one players[] line per athlete with passing/rushing/receiving/defense/kicking counts; final, in-progress, and delayed when rows exist). NBA/NCAAB: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (rebounds/assists/steals/blocks/turnovers/fouls, fg_pct/three_point_pct/free_throw_pct as ratio-of-sums), player_box (points/rebounds/assists/…; final, in-progress, and delayed when rows exist). NHL: record (goals_for/against), recent_form (goals_scored/allowed), rest_days, rates_l5/rates_season (shots_on_goal/hits/penalty_minutes/power_play_goals/giveaways/takeaways/blocked_shots), player_box (skaters[] + goalies[]; assists/hits remapped from assists_nhl/hits_nhl; final, in-progress, and delayed when rows exist). Settleables stay on get_player_props. Absent on tennis responses — use players instead.
playersNoTennis only (player_1/player_2). Each side: player_id, name, country_code, ranking, ranking_points, rest_days, recent_form, surface_form, record (tour_lookback wins/losses), career_rates (Stage-2 serve/return percentages; null until ingest), career_surface (Stage-2 match-surface W/L over windows.career_surface_years; null when empty). History windows exclude walkovers (unplayed) and include retirements.
profileNoSoccer only. 'world_cup' or 'club'.
windowsNoExplicit sample depths. Soccer: recent_form (5), rates_l5 (5), rates_season ('season'), head_to_head (10), sos (5). MLB/NFL/NCAAF/NBA/NCAAB/NHL: recent_form (5), rates_l5 (5), rates_season ('season'), head_to_head (10). Tennis: recent_form (10), surface_form (10), head_to_head (10), record_lookback_days (365), career_surface_years (3).
event_idNoLumify event ID.
availableNoFalse when participants haven't resolved, or tennis draw_type is not exactly 'singles' (doubles/qualifying out of scope); every other field is omitted and the call isn't billed.
draw_typeNoTennis only. Always 'singles' when available is true. Values other than 'singles' (including 'doubles' and 'qualifying') return available:false.
league_slugNoLeague/tour slug, e.g. 'mls', 'mlb', 'nfl', 'atp', 'wta'.
head_to_headNoPast meetings: {window, meetings, total}. Soccer: {home_goals, away_goals}. MLB: {home_runs, away_runs}. NFL/NCAAF/NBA/NCAAB: {home_points, away_points}. NHL: {home_goals, away_goals}. Tennis: {event_id, starts_at, surface, winner_role, sets_won} relative to this fixture's player_1/player_2 (walkovers excluded).
neutral_siteNoSoccer only. Whether this fixture is at a neutral venue. Informational here; factored into home-advantage scoring on get_intelligence.
league_contextNoSoccer only. {avg_goals_per_team}: league-wide baseline goals/team/game, used by get_intelligence's attack/defense scoring. Null for fixed-baseline competitions.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as read-only, idempotent, and non-destructive, so the bar is lower, but the description still adds meaningful behavioral detail: deterministic results, sport-specific payload shapes, tennis doubles/qualifying returning available:false, and exclusion of walkovers and certain preseason games. It goes well beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: core purpose, explicit exclusions, sport-specific payload note, edge-case behavior, and a pointer to the field catalog. It is front-loaded with the most important information and does not waste words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's multi-sport complexity, the single event_id parameter, the rich annotations, and the presence of an output schema, the description covers all essential call-time knowledge. It even provides a documentation URL for field-level details, making it fully sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers 100% of the single parameter, event_id, including its source from list_events, query_events, or search results. The description reinforces that this is an event-level statistics tool but adds no new parameter-specific semantics beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Get raw, deterministic team/match statistics' for an event, and enumerates the supported sports. It explicitly distinguishes itself from get_odds and get_intelligence, so an agent can immediately tell what this tool does and what it does not do.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when not to use this tool: 'no odds (use get_odds) and no scoring (use get_intelligence)' and warns that 'Other sports return HTTP 400.' This gives the agent concrete routing guidance and exclusion criteria beyond the bare schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_teamA
Read-onlyIdempotent
Inspect

Get a single team profile with its home venue. Raises a not-found error if team_id doesn't exist. Resolve ids via list_teams.

ParametersJSON Schema
NameRequiredDescriptionDefault
team_idYesTeam id, from list_teams.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNo
cityNo
nameNo
slugNo
sportNo
venueNo
leagueNo
divisionNo
image_urlNoLumify media URL for the team logo (https://lumify.ai/media/teams/{sport}/{id}.png). Null until ingest. Never a vendor CDN.
is_activeNo
conferenceNo
abbreviationNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal read-only, idempotent, non-destructive behavior. The description adds value by disclosing the not-found error behavior for invalid team_id, which the annotations do not cover, and notes the return includes home venue.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each carrying distinct information: purpose, error behavior, and id resolution. No filler or repetition of annotation fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one required parameter, a full output schema, and strong annotations, the description covers the essential call pattern and failure mode. Nothing needed to invoke correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents team_id as an id from list_teams, so the baseline is 3. The description adds meaning by warning that a nonexistent team_id triggers an error and reinforces the resolution path, going slightly beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Get' with the resource 'single team profile' and adds 'with its home venue' to define scope. It contrasts with list_teams by indicating a single team, and the explicit mention of list_teams helps disambiguate from that sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear prerequisite sequence: resolve ids via list_teams before calling get_team. It implies use when a single team profile or home venue is needed, though it does not enumerate exclusions like team props or stats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_team_propsA
Read-onlyIdempotent
Inspect

Get team-total lines and live progress for an NFL, NCAAF, MLB, or soccer event. Joins persisted Pinnacle team-total mains (each team's full-game points/runs/goals Over/Under) to this-event participant scores and grades over/under/push. GET /odds / get_odds stay on moneyline/spread/total. Returns available:false with no charge if no team-total mains have been ingested. Other sports return HTTP 400.

ParametersJSON Schema
NameRequiredDescriptionDefault
event_idYesEvent id, from list_events, query_events, or search results.

Output Schema

ParametersJSON Schema
NameRequiredDescription
clockNoGame clock from the live score snapshot.
sportNoSport slug: nfl, ncaaf, mlb, or soccer.
periodNoCurrent period from the live score snapshot.
statusNoEvent status (scheduled, inprogress, delayed, final, …).
event_idNoLumify event ID.
availableNoFalse when no team-total mains have been ingested; team_props is empty and the call isn't billed.
team_propsNoOne row per (team, line). Fields: team, team_id, side (home/away), market (team_total), line, current (this-event team score), pct_of_line, settleable, result (in_progress / over / under / push, or null), books ({book_slug: {over, under}} American prices).

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, and non-destructive behavior. The description adds meaningful operational context: joining persisted Pinnacle team-total mains to live scores, grading over/under/push, and no-charge behavior when data is unavailable. This goes well beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four tightly packed sentences with no filler. The main action is front-loaded, and every clause adds new information: supported sports, data join logic, sibling differentiation, and edge-case behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and only one well-documented parameter, the description covers all essential selection and invocation context. It includes sport restrictions, no-data behavior, and the relationship to get_odds, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, event_id, is already fully described in the schema with sourcing guidance ('from list_events, query_events, or search results'). The description's supported-sport scope is useful but does not add parameter-level mechanics, so the high schema coverage baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource ('team-total lines and live progress') and scopes it to NFL, NCAAF, MLB, and soccer events. It explicitly contrasts with get_odds's moneyline/spread/total scope, so an agent can distinguish it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when to use this tool for team-total props and indicates that GET /odds and get_odds cover moneyline/spread/total instead. It also gives practical fallback/edge behavior: available:false with no charge when no team-total mains exist, and HTTP 400 for unsupported sports.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

grade_slipA
Read-onlyIdempotent
Inspect

Grade settleable player-prop legs (over / under / push / in_progress / dnp / no_stat) for nfl, nba, ncaaf, ncaab, nhl, mlb, and soccer — the same sport coverage as get_player_props — plus structured game markets (h2h / spreads / totals) on any sport get_odds already settles. Prefer structured event_id + market_key + side; player_id and line are required on props, line is required on spreads/totals, and both player_id and line are omitted on h2h. team_total requires team_id + line + over/under and is only gradable on nfl/ncaaf/mlb/soccer. draw is only gradable on soccer h2h — off soccer it comes back unmapped. Free-text game phrases (Chiefs -3.5, Over 47.5 vs Bills, Yankees ML, Yankees to win, Yankees over 4.5 runs, Over 52.5 Syracuse vs Pittsburgh, Novak Djokovic ML) grade when the team or player and event resolve uniquely — Over 47.5 alone stays unmapped and is never the first slate game. A tennis moneyline leftover is a player, not a team; vs is the opponent player. Last-name-only tennis stays unmapped. A last-name-only player prop (Bergeron over 1.5 shots on goal last night) grades when a date is present and that surname is unique in scope — a named sport, team, or event narrows it (Johnson nhl last night); with no such clue, uniqueness is across every prop sport the key can see. No date, or a surname shared by more than one player in that scope, stays unmapped unless a date is present and exactly one of those candidates played in the window (optionally vs a named opponent). A colliding team nickname plus a date promotes only the unique in-window club; a football-sized line will not pick a baseball club. anytime goal / anytime assist (soccer_goals/soccer_assists over 0.5) and over a hit / over a homer (hits/home_runs over 1.0) need no explicit number. Free-text player props are graded only when player and event resolve uniquely — never guesses an ambiguous name. A roster-team mention (CIN, Niners) is resolved first; unique team_id scopes the player, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent and narrows the event, not the player's team. Ambiguous events stay on event_resolve with candidates. Read legs[].result / current / market for the grade; use resolve.player_id to re-issue structured props. Call this tool with an API key to grade from an agent. Capped at 3 concurrent calls per key (shared with POST /v1/grade/slip). The public /grade sheet uses the same engine without a key (20 grades / IP / day). How-to: https://lumify.ai/docs/grade. Not live trading odds. Not wagering advice. Attribution is always Graded by Lumify.

ParametersJSON Schema
NameRequiredDescriptionDefault
legsNo
textNoFree-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Over 52.5 Syracuse vs Pittsburgh / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, this Thursday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. "anytime goal"/"anytime assist" implies soccer_goals/soccer_assists over 0.5 with no explicit number; "over a hit"/"over a homer" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped.
cluesNoOptional sport / league / event_id / team_id / team_text hints for free-text mode.

Output Schema

ParametersJSON Schema
NameRequiredDescription
legsNo
statusNograded | partial | pending | unmapped
honestyNo
slip_idNo
summaryNo
brandingNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool read-only and idempotent, and the description adds substantial operational context: rate limits ('Capped at 3 concurrent calls per key'), public-sheet quotas ('20 grades / IP / day'), 'Not live trading odds', attribution behavior, and where to read results via legs[].result / current / market. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loaded and dense, moving from core purpose to structured usage to free-text edge cases to operational caveats. Every sentence contributes a distinct rule or constraint; there is no filler or repetition that weakens it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers structured and free-text inputs, disambiguation rules, failure modes, rate limits, authentication context, output location, and documentation links. With an output schema already present, the absence of explicit return-value detail is acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even with 67% schema coverage, the description adds decisive parameter context: line is signed to the submitted side, player_id and line are required on props, line is required on spreads/totals, both are omitted on h2h, team_total requires team_id and line, and draw is only gradable on soccer h2h. This goes well beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Grade settleable player-prop legs' and 'structured game markets'. It also distinguishes the tool from siblings by explicitly referencing get_player_props and get_odds for sport-coverage comparison.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly advises preferring structured event_id + market_key + side and explains when free-text grading succeeds or stays unmapped. It names sibling tools for coverage context but does not give an explicit 'use X instead when...' exclusion, so it stops just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_evA
Read-onlyIdempotent
Inspect

Beta. List pregame main-line +EV opportunities for a predictive-framework sport (soccer, mlb, tennis, nfl, ncaaf), sorted by ev_pct descending. market=h2h (default, moneyline), spreads, or totals. Tennis totals are not offered (Stage 1 is moneyline + spreads). Same gates as bets[].ev on get_intelligence: sharp-fair price gap, positive and ≤25%, suppressed MLB moneyline null books skipped in favor of the next eligible book. 1 credit. Field catalog: https://lumify.ai/docs/reference#intelligence-ev

ParametersJSON Schema
NameRequiredDescriptionDefault
bookNoRestrict opportunities to one sportsbook slug (e.g. fanduel).
limitNoMax opportunities to return (1–200). Default 50.
sportYesSport slug: soccer, mlb, tennis, nfl, or ncaaf.
leagueNoOptional league slug (mls, epl, atp, …). Soccer without a league scans every published soccer league (MLS + big-five).
marketNoMain-line family: h2h (default, moneyline), spreads, or totals. Tennis + totals returns 400.
min_evNoMinimum EV% to include. Default 0. Clamped to 0–25.

Output Schema

ParametersJSON Schema
NameRequiredDescription
betaNoAlways true.
bookNoBook filter, or null.
sportNoSport slug this scan was run for.
totalNoCount of opportunities on this page.
leagueNoLeague filter, or null for the whole sport.
marketNoh2h, spreads, or totals — the family scanned.
max_evNoStale-line cap (25).
min_evNoMinimum EV% applied.
opportunitiesNoPositive-EV main-line rows: {event_id, sport, league, commence_time, home_team, away_team, side, team, bet_type, line, fair_probability, ev}.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly, idempotent, and non-destructive behavior. The description adds substantial context beyond that: the tool costs 1 credit, is in Beta, sorts by ev_pct, suppresses MLB moneyline null books, skips to the next eligible book, applies sharp-fair price gates, and returns 400 for tennis totals.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized, front-loading the core purpose and then adding constraints, gates, cost, and a reference link. Every sentence earns its place; there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description does not need to explain return values. It covers supported sports, market families, default behavior, edge cases, EV gates, cost, and links to the full field catalog, making it fully actionable for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining the market default, the tennis totals 400 error, the MLB null-book behavior, and the soccer league scanning behavior, adding useful semantics for parameter selection.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists pregame main-line +EV opportunities, names the supported sports, and specifies sorting by ev_pct descending. It also differentiates the tool from siblings by mentioning market families and the tennis totals exclusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: it is for pregame +EV opportunities, not live events, and it specifies market defaults and unsupported combinations. It references get_intelligence for the shared EV gates, which helps an agent relate the tool to a sibling, though it does not explicitly say 'use this instead of X'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_eventsA
Read-onlyIdempotent
Inspect

List events (schedules and live scores), paginated by id (after_id). Filter by sport, league, status, date range, season, or team_id (resolve teams via list_teams / get_team). Returns event id, name, sport/league, start time, status, and venue for each; pass include_scores to also inline participants + scores (intended for small result sets — use get_event for one event's full detail, or query_events for free-text/natural-language filters instead of structured params). include_scores shares the 20/min score-poll budget with get_live_score; prefer the SSE stream for live boards.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoUTC end date YYYY-MM-DD (inclusive).
dateNoUTC date YYYY-MM-DD (single day).
fromNoUTC start date YYYY-MM-DD.
sortNoSort order. sort=status is incompatible with after_id.time
limitNoMax events to return per page.
sportNoSport slug, e.g. mlb, nfl, tennis, soccer.
leagueNoLeague slug, e.g. nfl, atp, mls.
statusNoFilter to events in this status.
team_idNoFilter to events where this team participates. Resolve ids via list_teams.
after_idNoCursor: return events with id > after_id (from the previous page's next_after_id).
season_idNoFilter by season ID (from list_seasons).
has_recommendNoWhen true, only events with at least one recommended bet.
include_scoresNoInline participants + scores in each event (intended for small result sets). Shares the 20/min score-poll budget with get_live_score.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
eventsNo
next_after_idNoPass as after_id to fetch the next page; null on the last page.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), but the description adds genuinely non-structured behavior: include_scores shares the 20/min score-poll budget with get_live_score and is intended only for small result sets. It also discloses cursor pagination via next_after_id. It stops short of describing pagination edge cases or failure behavior, so a 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the core purpose and pagination lead, then filtering, then the routing caveats. Nearly every clause carries information, though the long parenthetical about include_scores/query_events/get_event is syntactically sprawling and could be split for scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter filtering tool with an output schema, the description covers purpose, pagination, filtering dimensions, alternatives, and a rate-limit caveat. Return values are already handled by the output schema, so nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 13 parameters are already documented in the schema, including the sort/after_id incompatibility. The description restates which filters exist and the include_scores cost, but adds no syntax or format detail beyond the schema. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List events (schedules and live scores)') and immediately scopes what is returned. It distinguishes itself from siblings by naming get_event for single-event detail and query_events for free-text filtering. An agent can pick this tool without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: use get_event for one event's full detail, query_events for natural-language filters instead of structured params, list_teams/get_team to resolve team_id, and the SSE stream for live boards. This is when-to-use plus named alternatives, exceeding the bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_forecastsA
Read-onlyIdempotent
Inspect

Daily board of forecasted wagers from Lumify's model — a prediction, not a beat-the-market claim (no OOS/independence gate; see list_ev for the gated main-line +EV claim). Player props (rate model) on MLB, NCAAF, NFL, NBA, NCAAB, NHL. High-confidence main-line picks on tennis, NFL, NCAAF, MLB, and soccer: one side per moneyline / spread / total when the uncertainty band does not include a coin flip. Tennis moneyline is ranking Bradley-Terry; tennis spreads/totals are a Normal-approx games model. Other sports use the published assessment probability. Each wager has p_hit, conviction, and posted books prices. Use list_ev to scan main lines by sharp-fair price gap; use this tool to scan high-probability forecasts. reliability is emerging on v0. 1 credit; empty slate is still 200. How + field catalog: https://lumify.ai/docs/forecasts Worked wager: https://lumify.ai/docs/understanding-odds#forecasts

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoUTC slate date YYYY-MM-DD. Defaults to today UTC.
limitNoMax wagers (1–100). Default 25.
sportYesSport slug: mlb, ncaaf, nfl, nba, ncaab, nhl, tennis, or soccer.
marketNoMain-line family filter (h2h, spreads, or totals). Main-line sports publish a high-confidence side of each family when the lean clears the coin-flip gate. Ignored on prop-only sports (nba, ncaab, nhl).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateNoUTC slate date (YYYY-MM-DD).
sportNoSport slug this slate was scored for.
totalNoCount of wagers on this page.
wagersNoSelected forecasted wagers, highest conviction first. Read p_hit as P(the picked outcome — side on prop rows, bet_type on main-line rows — hits); conviction is the board rank. How + field catalog: https://lumify.ai/docs/forecasts
reliabilityNoDefault badge on this slate. v0 ships emerging; each wager repeats the same field.
model_versionNoScorer version (forecast-v0).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool read-only, idempotent, and non-destructive. The description adds meaningful behavioral context beyond that: it clarifies this is not an OOS/independence-gated claim, notes that reliability is emerging on v0, states the cost as 1 credit, and reveals that an empty slate still returns 200. It also explains that market filtering is ignored on prop-only sports, which is a subtle behavior an agent needs to know.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but information-rich. It front-loads the core purpose and sibling differentiation, then adds behavioral and model context. A few sentences about model methodology (e.g., Bradley-Terry) are more than strictly necessary for invocation, but they support trust calibration healthy for a forecasting tool. Overall it earns each sentence, though it is longer than a minimal definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with an output schema and minimal required parameters, this description is remarkably complete. It covers purpose, scope, sport coverage, market behavior, field expectations (p_hit, conviction, posted books prices), cost, empty-slate behavior, and links to full documentation. There are no obvious gaps that would prevent an agent from invoking it correctly or choosing it over list_ev.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already has 100% description coverage, so the baseline is 3. The description adds useful semantics beyond the schema by enumerating which sports have player props vs. main-line picks)Skip? Actually, the description names sports and market applicability, and clarifies the meaning of market for prop-only sports. This adds value over the plain schema descriptions, justifying a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a daily board of forecasted wagers from Lumify's model, specifying the exact resource being listed. It also distinguishes itself from list_ev by explaining that this is a high-probability forecast tool, not a beat-the-market claim. This makes the purpose unambiguous and differentiates it from the closest sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool: 'use this tool to scan high-probability forecasts' and contrasts it with list_ev for sharp-fair price gap scanning. It also explains the coverage by sport and market type, and clarifies that market is ignored on prop-only sports. This is strong, actionable guidance for an agent deciding between tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_seasonsA
Read-onlyIdempotent
Inspect

List seasons per sport/league. By default returns only currently active seasons; pass current_only=false to include historical seasons. Optionally filter by sport. Returns each season's id, year, phase, start/end dates, and whether it is_current. Use list_sports for just each sport's current season.

ParametersJSON Schema
NameRequiredDescriptionDefault
sportNoFilter by sport slug, e.g. nhl, nba, soccer.
current_onlyNoReturn only currently active seasons (default true). Pass false for historical seasons.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
seasonsNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (read-only, idempotent, non-destructive), and the description adds meaningful behavior: default active-only filtering, optional historical inclusion, and return field details. It does not contradict annotations and provides useful context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the core purpose, then defaults, return fields, and an alternative. Every sentence earns its place with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with an output schema and full annotations, the description fully covers defaults, filtering, and alternatives. There are no meaningful gaps for selection or invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description mirrors the schema's current_only and sport semantics without adding new parameter-level details, but it does reinforce them in natural language.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'List' with a clear resource 'seasons' and scope 'per sport/league'. It explicitly distinguishes itself from the sibling list_sports by directing users there for just current-season info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the default behavior (only active seasons), how to opt into historical seasons (current_only=false), optional sport filtering, and explicitly names list_sports as an alternative when simpler data suffices. This provides clear when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_sportsA
Read-onlyIdempotent
Inspect

List supported sports with their leagues and current season. Returns each sport's id, slug, name, team-sport flag, and its leagues (each with its current_season). Use list_seasons with current_only=false for historical seasons.

ParametersJSON Schema
NameRequiredDescriptionDefault
active_onlyNoWhen true (default), omit sports with no active coverage.

Output Schema

ParametersJSON Schema
NameRequiredDescription
totalNo
sportsNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only and non-destructive behavior. The description adds useful context about the returned data structure (sport id, slug, name, team-sport flag, leagues with current_season) that is not redundant with the output schema, and it clarifies the tool's scope beyond the hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first leads with the action and key outcome, the second details return fields and the alternative for historical data. Every sentence earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the single optional parameter, rich annotations, and presence of an output schema, the description fully covers the tool's purpose, return shape, and related tool guidance. No important gaps remain for a simple list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides a full description for active_only (100% coverage), so the schema does the heavy lifting. The description does not add additional parameter meaning beyond what is in the schema, meeting the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists supported sports with their leagues and current season, naming the exact fields returned. It distinguishes from sibling tools by explicitly pointing to list_seasons for historical seasons, and the scope (sports vs teams/events) is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance to use list_seasons with current_only=false for historical seasons, which is a clear alternative. Does not enumerate all when-not-to-use scenarios, but the primary use case is evident and the alternative is well-targeted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_teamsA
Read-onlyIdempotent
Inspect

List teams, paginated by id (after_id). Filter by sport, league, conference, division, country, active status, or name (q, partial match). Returns each team's id, slug, name, city, conference/division, venue, and image_url (Lumify media URL, null until ingest). Use get_team for full detail on one id once resolved here.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoTeam name search (partial match).
limitNoMax teams to return per page.
sportNoSport slug, e.g. nfl, nba, soccer.
activeNoFilter by active status.
leagueNoLeague slug, e.g. nfl, mls.
countryNoISO country code, e.g. USA.
after_idNoCursor: last team id from the previous page's next_after_id.
divisionNoDivision name, e.g. AFC East.
conferenceNoConference name, e.g. AFC, Eastern.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
has_moreNo
next_after_idNoPass as after_id to fetch the next page; null on the last page.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description only needs to add extra context. It adds useful behavioral details: pagination is driven by after_id, results are a summary set, and image_url is null until ingest.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler; the main action and pagination are front-loaded, followed by filters, return fields, and the sibling-tool handoff. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list endpoint with an output schema and annotations covering safety and idempotency, the description covers how to paginate, what filters exist, what fields come back, and how to get full detail afterwards. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all nine optional parameters. The description mostly restates the filter categories and cursor semantics rather than adding new parameter-level meaning, which is adequate but not additive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (List teams), names the pagination mechanism, enumerates filters, and specifies the returned fields. It also distinguishes itself from get_team, so an agent can tell the two apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use this tool: resolve a team id here, then call get_team for full detail. This explicit routing to a sibling tool eliminates ambiguity about the boundary between list and detail operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_eventsA
Read-onlyIdempotent
Inspect

Search events with a natural-language query instead of structured filters — e.g. 'live nfl games today' or 'college basketball this week'. Rule-based (not an LLM): recognizes sport (nfl/nba/mlb/nhl/tennis/soccer/ncaaf/ncaab + aliases like hockey, american football, college basketball), status (live/final/upcoming/…), dates (today/tomorrow, this week, next N days, YYYY-MM-DD ranges). Bare 'football' is ambiguous and left unrecognized. Response includes interpreted filters, equivalent REST call, and unrecognized_terms. Prefer list_events when you already know the structured filters you want.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoOverrides any limit parsed from the query text. Max 100.
queryYesFree text, e.g. 'live nfl games today'.

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryNoThe original natural-language query text.
totalNo
eventsNo
interpretedNoThe list_events-equivalent filters parsed from the query text (sport, status, date, from, to, limit).
next_after_idNo
equivalent_requestNoThe literal GET /v1/events request this query was translated to.
unrecognized_termsNoQuery words that didn't map to a known filter.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (read-only, idempotent, non-destructive), the description adds critical behavioral details: it is rule-based not an LLM, specific language features are recognized, bare 'football' is ambiguous and left unrecognized, and the response includes interpreted filters, equivalent REST call, and unrecognized_terms.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence contributes useful information. It opens with the primary purpose, provides illustrative examples, explains internal behavior, and closes with usage guidance—all without fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's natural-language processing complexity, the description thoroughly covers usage scope, behavioral limitations, and response contents. The output schema handles return values, so no additional detail is needed there. The description is comprehensive for an AI agent to decide when and how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema documents both parameters, the description enriches the 'query' parameter by detailing supported sports, statuses, date formats, and the ambiguity behavior. It also clarifies the 'limit' parameter's override semantics, adding value beyond the schema fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: search events using natural-language queries instead of structured filters. It provides concrete examples and explicitly distinguishes it from sibling tools like list_events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit guidance on when to use this tool versus the alternative, stating 'Prefer list_events when you already know the structured filters you want.' This directly addresses tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_eventA
Read-onlyIdempotent
Inspect

Resolve event identity from an event_id, or a player_id/team_id clue plus an optional date window, to a Lumify event_id. Falls back to a player's roster team schedule for team sports (only individual sports like tennis track per-player game participation directly). Combine team_id + opponent_team_id for a specific matchup. Returns ambiguous instead of guessing when the window has more than one candidate — never auto-pick candidates[0].

ParametersJSON Schema
NameRequiredDescriptionDefault
cluesNoevent_id (ground truth), or player_id/team_id plus a date window.
optionsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
sportNo
leagueNo
methodNo
statusNoresolved | ambiguous | not_found | error
messageNo
event_idNo
away_teamNo
home_teamNo
starts_atNo
candidatesNo
clues_usedNo
confidenceNo
event_statusNo
match_reasonsNo
participant_conflictNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive, so the description only needs to add behavioral nuance. It does: it returns 'ambiguous' rather than guessing when multiple candidates exist, and explicitly warns never to auto-pick candidates[0]. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and each subsequent sentence adds a distinct, useful fact: fallback behavior, matchup combination, and ambiguity handling. There is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the nested schema, output schema, and safety annotations, the description covers the main resolution modes, sports-specific fallback, matchup logic, and the critical ambiguous-return behavior. An agent has enough to invoke the tool correctly without major gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaningful semantics beyond the schema for clues: event_id is authoritative, player/team clues need an optional date window, and team_id + opponent_team_id forms a specific matchup. However, the options object (max_candidates, min_confidence) receives no narrative guidance, and schema description coverage is only 50%, so compensation is partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource: 'Resolve event identity from an event_id, or a player_id/team_id clue plus an optional date window, to a Lumify event_id.' It also differentiates itself from siblings like get_event and resolve_player by focusing on identity resolution rather than retrieval or player/team resolution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage context: event_id is ground truth, player/team clues need a date window, team_id plus opponent_team_id handles matchups, and team sports fall back to roster schedules while individual sports track participation directly. It does not explicitly name sibling alternatives or state when not to use this tool, but the guidance is otherwise clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_playerA
Read-onlyIdempotent
Inspect

Resolve messy sports player names to a Lumify player_id using sport, team, or event clues. Prefer this before grade_slip when the name is a fragment, initial, or nickname. Returns ambiguous instead of guessing — never auto-pick candidates[0]. A sport-scoped key binds the in-scope side of a collision and returns not_found when every hit is out of scope. Does not grade props.

ParametersJSON Schema
NameRequiredDescriptionDefault
cluesNoOptional sport, team, event, or position clues.
queryYesMessy player name or fragment, e.g. J. Chase.
optionsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
sportNo
statusNoresolved | ambiguous | not_found | error
messageNo
team_idNo
player_idNo
candidatesNo
clues_usedNo
confidenceNo
display_nameNo
match_reasonsNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description discloses the ambiguity policy ('Returns ambiguous instead of guessing — never auto-pick candidates[0]'), collision behavior for sport-scoped keys, and the not_found result when all hits are out of scope. These are critical behavioral traits not visible in annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four compact sentences, with the core purpose first and every sentence adding distinct information. No filler or repetition of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the readOnly annotations, nested input schema, output schema, and sibling context, the description covers purpose, ambiguity behavior, collision handling, and exclusion of prop grading. Nothing critical for selecting or invoking the tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already documents query, sport slug, and team_text, and has 67% coverage. The description adds meaning by tying clues to resolution, explaining the 'fragment, initial, or nickname' use case, and describing sport-scoped collision semantics. It doesn't explain mode/max_candidates/min_confidence, but those are largely self-describing with defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb (resolve), resource (messy sports player names), output (Lumify player_id), and clue inputs (sport/team/event). It also contrasts with grade_slip, so an agent can distinguish it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to prefer resolve_player before grade_slip when the name is a fragment, initial, or nickname, and clarifies what the tool does not do ('Does not grade props'). This is direct when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_teamA
Read-onlyIdempotent
Inspect

Resolve messy team names, abbreviations, metros, or aliases to a Lumify team_id using sport, league, event, or player clues. Prefer this before list_teams when the string is a nickname or city token. Returns ambiguous instead of guessing — never auto-pick candidates[0]. City-only metros sit below the auto-resolve floor.

ParametersJSON Schema
NameRequiredDescriptionDefault
cluesNoOptional sport, league, event, player, or team-id clues.
queryNoTeam string, e.g. Niners, CIN, NY Giants.
optionsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
sportNo
leagueNo
methodNo
statusNoresolved | ambiguous | not_found | error
messageNo
team_idNo
candidatesNo
clues_usedNo
confidenceNo
abbreviationNo
display_nameNo
match_reasonsNo
sport_conflictNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, open-world, non-destructive. The description adds genuinely new behavioral detail: it returns ambiguous rather than guessing, never auto-picks candidates[0], and city-only metros fall below the auto-resolve floor. It doesn't discuss the confidence scoring model or pagination limits, but the ambiguity contract is a meaningful addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, zero filler, with the primary purpose front-loaded and routing/behavioral caveats following. Every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return-value structure need not be explained, and the description still covers the key ambiguity/return contract. Minor gaps remain around confidence semantics and what the candidate list contains, but overall complete for a resolver tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% and the description adds meaning to the resolution behavior tied to min_confidence ('city-only metros sit below the auto-resolve floor'), which clarifies the otherwise undocumented options.min_confidence parameter. The clues and query params are already described in the schema, so this compensates appropriately without redundancy.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Resolve) and resource (messy team names, abbreviations, metros, aliases) and names the output artifact (Lumify team_id). It explicitly distinguishes itself from the sibling list_teams, so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance ('Prefer this before list_teams when the string is a nickname or city token'), naming the alternative and the condition that selects it. The rule about not auto-picking candidates[0] further constrains how the caller should behave on ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_playersA
Read-onlyIdempotent
Inspect

Search players by name, sport, country, ranking, or active status, paginated by id (after_id). Returns the same identity object on every sport (null means unknown, not wrong sport). Tennis standings nest under rankings.{singles, points}; rankings is null on every other sport. Use get_player for full detail on one id, or get_player_events for a player's schedule/results.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoName search (partial match).
limitNoMax players to return per page.
sportNoSport slug, e.g. tennis, nba.
activeNoFilter by active status.
rankedNoIf true, only tennis players with an ATP/WTA singles ranking (rankings.singles).
countryNoISO 3166-1 alpha-3 country code, e.g. USA.
after_idNoCursor: last player id from the previous page's next_after_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
has_moreNo
next_after_idNoPass as after_id to fetch the next page; null on the last page.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as readOnly, openWorld, idempotent, and non-destructive, so the bar is lower. The description adds valuable behavioral context: the identity object is the same across sports with null meaning unknown, not wrong sport, and that rankings only nests under tennis while being null elsewhere. This goes beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. The main action and filters are front-loaded in the first sentence, behavior notes in the second, and routing to alternatives in the third. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations cover the safety profile, the description covers the remaining important context: null/unknown semantics, sport-specific rankings shape, and the relationship to sibling tools. Nothing critical is missing for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description reinforces the role of parameters like sport, country, ranking, and after_id, and clarifies pagination via id, but it does not significantly deepen the semantics beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search players by name, sport, country, ranking, or active status, paginated by id (after_id).' It clearly identifies the action, the target, and the available filters, and distinguishes itself from get_player and get_player_events by naming them as alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use alternatives: 'Use get_player for full detail on one id, or get_player_events for a player's schedule/results.' It also provides pagination context with after_id and next_after_id, making the usage conditions clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updates
    • Changedget_intelligence3 fields changed
      • changedOutput schema / properties / bets / items / properties / narrative / description
        Previous value: -"Not published."New value: +"Pick-defense rationale for a selected main-line side. Present only when a matching forecasts[] row is selected: true. Null when no pick was made on this token."
      • changedOutput schema / properties / forecasts / description
        Previous value: -"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"New value: +"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; high-confidence main-line picks on tennis, NFL, NCAAF, MLB, and soccer via bet_type (ML_P1/ML_P2/ML_HOME/ML_AWAY/ML_DRAW, SPREAD_*/OVER/UNDER). selected marks the pick — high-confidence main-lines and the top-conviction prop rows on the daily slate. Coin-flip main-lines are not picked. A selected main-line research.note is copied to bets[].narrative. Read p_hit as P(the picked outcome hits). How + field catalog: https://lumify.ai/docs/forecasts"
      • changedOutput schema / properties / forecasts / items / properties / research / description
        Previous value: -"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {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."New value: +"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {stance, conviction, note}. stance is validate / neutral / invalidate. note is the wager-level why — on a selected main-line row it is also copied to bets[].narrative. 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."
    • Changedlist_forecasts3 fields changed
      • changedInput schema / properties / market / description
        Previous value: -"Main-line family filter (h2h, spreads, or totals). Tennis publishes all three (moneyline, game-handicap, total-games). Ignored on prop-only sports."New value: +"Main-line family filter (h2h, spreads, or totals). Main-line sports publish a high-confidence side of each family when the lean clears the coin-flip gate. Ignored on prop-only sports (nba, ncaab, nhl)."
      • changedInput schema / properties / sport / description
        Previous value: -"Sport slug: mlb, ncaaf, nfl, nba, ncaab, nhl, or tennis."New value: +"Sport slug: mlb, ncaaf, nfl, nba, ncaab, nhl, tennis, or soccer."
      • changedOutput schema / properties / wagers / items / properties / research / description
        Previous value: -"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {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."New value: +"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {stance, conviction, note}. stance is validate / neutral / invalidate. note is the wager-level why — on a selected main-line row it is also copied to bets[].narrative. 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."
  2. 2 tool updates
    • Changedget_intelligence1 field changed
      • changedOutput schema / properties / forecasts / items / properties / market / description
        Previous value: -"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."New value: +"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), rush_rec_yards, pass_rush_yards. 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."
    • Changedlist_forecasts1 field changed
      • changedOutput schema / properties / wagers / items / properties / market / description
        Previous value: -"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."New value: +"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), rush_rec_yards, pass_rush_yards. 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."
  3. 1 tool update
    • Changedgrade_slip1 field changed
      • changedInput schema / properties / text / description
        Previous value: -"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, this Thursday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. \"anytime goal\"/\"anytime assist\" implies soccer_goals/soccer_assists over 0.5 with no explicit number; \"over a hit\"/\"over a homer\" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."New value: +"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Over 52.5 Syracuse vs Pittsburgh / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, this Thursday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. \"anytime goal\"/\"anytime assist\" implies soccer_goals/soccer_assists over 0.5 with no explicit number; \"over a hit\"/\"over a homer\" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."
  4. 1 tool update
    • Changedgrade_slip1 field changed
      • changedInput schema / properties / text / description
        Previous value: -"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. \"anytime goal\"/\"anytime assist\" implies soccer_goals/soccer_assists over 0.5 with no explicit number; \"over a hit\"/\"over a homer\" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."New value: +"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, this Thursday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. \"anytime goal\"/\"anytime assist\" implies soccer_goals/soccer_assists over 0.5 with no explicit number; \"over a hit\"/\"over a homer\" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."
  5. 1 tool update
    • Changedget_stats1 field changed
      • changedOutput schema / properties / teams / description
        Previous value: -"Soccer/MLB/NFL/NCAAF/NBA/NCAAB/NHL only (home/away). Each side includes image_url (Lumify media URL, null until ingest; never a vendor CDN). Soccer: recent_form, team_strength, venue, rest_days, sos, lineup, rates_l5, rates_season. MLB: record, recent_form, rest_days, rates_l5/rates_season (incl. OBP/SLG/OPS/RBI/TB), starting_pitcher (post-box only), lineup, player_box (this event's per-player batting/pitching counting stats). NFL/NCAAF: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (total/passing/rushing yards, attempts, turnovers, third_down_pct), player_box (one players[] line per athlete with passing/rushing/receiving/defense/kicking counts; final only). NBA/NCAAB: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (rebounds/assists/steals/blocks/turnovers/fouls, fg_pct/three_point_pct/free_throw_pct as ratio-of-sums), player_box (points/rebounds/assists/…; final only). NHL: record (goals_for/against), recent_form (goals_scored/allowed), rest_days, rates_l5/rates_season (shots_on_goal/hits/penalty_minutes/power_play_goals/giveaways/takeaways/blocked_shots), player_box (skaters[] + goalies[]; assists/hits remapped from assists_nhl/hits_nhl; final only). Settleables stay on get_player_props. Absent on tennis responses — use players instead."New value: +"Soccer/MLB/NFL/NCAAF/NBA/NCAAB/NHL only (home/away). Each side includes image_url (Lumify media URL, null until ingest; never a vendor CDN). Soccer: recent_form, team_strength, venue, rest_days, sos, lineup, rates_l5, rates_season. MLB: record, recent_form, rest_days, rates_l5/rates_season (incl. OBP/SLG/OPS/RBI/TB), starting_pitcher (post-box only), lineup, player_box (this event's per-player batting/pitching counting stats; final, in-progress, and delayed when rows exist). NFL/NCAAF: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (total/passing/rushing yards, attempts, turnovers, third_down_pct), player_box (one players[] line per athlete with passing/rushing/receiving/defense/kicking counts; final, in-progress, and delayed when rows exist). NBA/NCAAB: record (points_for/against), recent_form (points_scored/allowed), rest_days, rates_l5/rates_season (rebounds/assists/steals/blocks/turnovers/fouls, fg_pct/three_point_pct/free_throw_pct as ratio-of-sums), player_box (points/rebounds/assists/…; final, in-progress, and delayed when rows exist). NHL: record (goals_for/against), recent_form (goals_scored/allowed), rest_days, rates_l5/rates_season (shots_on_goal/hits/penalty_minutes/power_play_goals/giveaways/takeaways/blocked_shots), player_box (skaters[] + goalies[]; assists/hits remapped from assists_nhl/hits_nhl; final, in-progress, and delayed when rows exist). Settleables stay on get_player_props. Absent on tennis responses — use players instead."
  6. 3 tool updates
    • Changedget_intelligence1 field changed
      • changedOutput schema / properties / forecasts / items / properties / research / description
        Previous value: -"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."New value: +"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {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."
    • Changedgrade_slip1 field changed
      • changedInput schema / properties / text / description
        Previous value: -"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."New value: +"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML / Yankees to win / Yankees over 4.5 runs / Novak Djokovic ML / Mbappe anytime goal / Judge over a hit / Bergeron over 1.5 shots on goal last night). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A roster-team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. vs/at on a player prop is the opponent, not the player's team. A tennis moneyline leftover is a player; vs is the opponent player. \"anytime goal\"/\"anytime assist\" implies soccer_goals/soccer_assists over 0.5 with no explicit number; \"over a hit\"/\"over a homer\" implies hits/home_runs over 1.0. A last-name-only player prop grades when a date is present and the surname is unique in scope (a named sport, team, or event narrows it; otherwise every visible prop sport); no date, or a shared surname in that scope, still refuses. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."
    • Changedlist_forecasts1 field changed
      • changedOutput schema / properties / wagers / items / properties / research / description
        Previous value: -"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."New value: +"Optional Deep Research overlay when the background job has written a row for this wager — every wager on the daily board (selected: true), plus other high-probability wagers (p_hit ≥ 0.80) in the catalog: {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."
  7. 1 tool update
    • Changedgrade_slip8 fields changed
      • addedInput schema / properties / legs / items / properties / line / description
        Added value: +"Required on props, spreads, totals, and team_total. Omit on h2h. Signed to the submitted side, not the favorite — side=home with a home -3.5 favorite is line=-3.5."
      • changedInput schema / properties / legs / items / properties / market_key / description
        Previous value: -"e.g. receiving_yards. Aliases such as player_reception_yds are accepted."New value: +"Player-prop slug (e.g. receiving_yards), game market h2h | spreads | totals, or team_total. Aliases accepted: player_reception_yds -> receiving_yards, moneyline/ml -> h2h, spread -> spreads, total/ou -> totals, team totals/tt -> team_total."
      • addedInput schema / properties / legs / items / properties / player_id / description
        Added value: +"Required on player-prop markets. Forbidden on h2h, spreads, totals, and team_total."
      • changedInput schema / properties / legs / items / properties / side / description
        Previous value: -"over or under"New value: +"Props and totals: over | under (o | u also accepted). Spreads: home | away, matching the signed line above. Moneyline: home | away, or draw on soccer only."
      • addedInput schema / properties / legs / items / properties / side / enum
        Added value: +[
        +  "home",
        +  "away",
        +  "over",
        +  "under",
        +  "draw"
        +]
      • addedInput schema / properties / legs / items / properties / team_id
        Added value: +{
        +  "description": "Required on team_total. Forbidden on player-prop, h2h, spreads, and totals.",
        +  "type": "integer"
        +}
      • changedInput schema / properties / legs / items / required
        Previous value: -[
        -  "event_id",
        -  "player_id",
        -  "market_key",
        -  "line",
        -  "side"
        -]New value: +[
        +  "event_id",
        +  "market_key",
        +  "side"
        +]
      • changedInput schema / properties / text / description
        Previous value: -"Free-text slip (e.g. Chase over 74.5 receiving yards tonight). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A team span is resolved first; unique team_id scopes the player, and ambiguous/not_found stays on team_resolve. Graded only when player and event are unique."New value: +"Free-text slip (e.g. Chase over 74.5 receiving yards tonight, or Chiefs -3.5 / Over 47.5 vs Bills / Yankees ML). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A team span is resolved first; unique team_id scopes a player or binds a game/team-total leg, and ambiguous/not_found stays on team_resolve. Graded only when team/player and event are unique. A bare Over 47.5 stays unmapped."
  8. 1 tool update
    • Changedgrade_slip1 field changed
      • changedInput schema / properties / text / description
        Previous value: -"Free-text slip (e.g. Chase over 74.5 receiving yards). A team span is resolved first; unique team_id scopes the player, and ambiguous/not_found stays on team_resolve. Graded only when player and event are unique."New value: +"Free-text slip (e.g. Chase over 74.5 receiving yards tonight). Date words (today, tonight, yesterday, last night, last Wednesday, or an ISO date) narrow the event. A team span is resolved first; unique team_id scopes the player, and ambiguous/not_found stays on team_resolve. Graded only when player and event are unique."
  9. 1 tool update
    • Addedresolve_event
  10. 4 tool updates
    • Addedgrade_slip
    • Changedlist_events1 field changed
      • changedInput schema / properties / include_scores / description
        Previous value: -"Inline participants + scores in each event (intended for small result sets)."New value: +"Inline participants + scores in each event (intended for small result sets). Shares the 20/min score-poll budget with get_live_score."
    • Addedresolve_player
    • Addedresolve_team
  11. 24 tool updates
    • Addedbatch_get_events
    • Addedestimate_cost
    • Changedget_event5 fields changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker for inlined odds; defaults to pinnacle, 'all' for every book."New value: +"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all."
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • changedInput schema / properties / include_intelligence / description
        Previous value: -"Inline bet intelligence (+1 credit when available)."New value: +"Inline bet intelligence. Does not add credits."
      • changedInput schema / properties / include_odds / description
        Previous value: -"Inline current odds (+1 credit when odds are available)."New value: +"Inline current odds scoped by bookmaker (default: pinnacle). Does not add credits — the event call stays 1 credit."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "id": {
        +      "type": "integer"
        +    },
        +    "inprogress_since": {
        +      "description": "ISO-8601 UTC when status first became inprogress (first live tick). Null until then; stays set after final.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "league": {
        +      "type": "string"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "participants": {
        +      "items": {
        +        "properties": {
        +          "is_winner": {
        +            "type": [
        +              "boolean",
        +              "null"
        +            ]
        +          },
        +          "participant_id": {
        +            "type": "integer"
        +          },
        +          "player": {
        +            "type": [
        +              "object",
        +              "null"
        +            ]
        +          },
        +          "role": {
        +            "type": "string"
        +          },
        +          "score": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "team": {
        +            "type": [
        +              "object",
        +              "null"
        +            ]
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "sport": {
        +      "type": "string"
        +    },
        +    "starts_at": {
        +      "type": "string"
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "venue": {
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_injuries
    • Changedget_intelligence3 fields changed
      • addedInput schema / properties / bookmaker / description
        Added value: +"Ignored. Intelligence always reports the book the assessment was priced against. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada."
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • 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"
        +}
    • Changedget_live_score2 fields changed
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "clock": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "event_id": {
        +      "type": "integer"
        +    },
        +    "finished": {
        +      "type": "boolean"
        +    },
        +    "period": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "scores": {
        +      "items": {
        +        "properties": {
        +          "abbreviation": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "is_winner": {
        +            "type": [
        +              "boolean",
        +              "null"
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "period_scores": {
        +            "items": {
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "role": {
        +            "type": "string"
        +          },
        +          "score": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "status": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedget_odds4 fields changed
      • addedInput schema / properties / bookmaker / description
        Added value: +"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • addedInput schema / properties / include_alts
        Added value: +{
        +  "description": "Include alternate spread/total rungs. Default false (mains only).",
        +  "type": "boolean"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "available": {
        +      "type": "boolean"
        +    },
        +    "bookmakers": {
        +      "description": "Per-book markets. Outcomes include is_main. In-play omits books that have not quoted since kickoff. Final events add result (won/lost/push/void) and close on the pre-kickoff point.",
        +      "items": {
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "event_id": {
        +      "type": "integer"
        +    },
        +    "fallback_bookmaker": {
        +      "description": "The book actually returned when requested_bookmaker is present.",
        +      "type": "string"
        +    },
        +    "last_updated": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "requested_bookmaker": {
        +      "description": "Present only when the default (no bookmaker arg) request fell back to a different book because Pinnacle has no line yet — always 'pinnacle' when present.",
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedget_odds_history4 fields changed
      • addedInput schema / properties / bookmaker / description
        Added value: +"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • addedInput schema / properties / limit / description
        Added value: +"Max line-movement entries to return. Default 50."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "event_id": {
        +      "type": "integer"
        +    },
        +    "movements": {
        +      "description": "Odds snapshots over time; each entry carries its own timestamp.",
        +      "items": {
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_period_odds
    • Changedget_player2 fields changed
      • addedInput schema / properties / player_id / description
        Added value: +"Player id, from search_players."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "birthdate": {
        +      "description": "YYYY-MM-DD date of birth.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "country_code": {
        +      "description": "ISO 3166-1 alpha-3 country code.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "current_team_id": {
        +      "description": "Lumify team ID when the player is on a club roster. Null for tennis.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "current_team_name": {
        +      "description": "Current team display name. Null for tennis.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "first_name": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "full_name": {
        +      "description": "Display name.",
        +      "type": "string"
        +    },
        +    "handedness": {
        +      "description": "left | right | switch. Meaning is sport-specific (bats for MLB, shoots for NHL, playing hand for tennis). Null when unknown.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "height_cm": {
        +      "description": "Height in centimetres. Null when not ingested.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "id": {
        +      "description": "Lumify player ID.",
        +      "type": "integer"
        +    },
        +    "image_url": {
        +      "description": "Lumify media URL for the player headshot (https://lumify.ai/media/players/{sport}/{id}.{ext}). Null until the sport's headshot/enrichment job. Never a vendor CDN.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "is_active": {
        +      "description": "False when deactivated or retired.",
        +      "type": "boolean"
        +    },
        +    "last_name": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "position": {
        +      "description": "Roster position abbreviation when the sport has one (e.g. C, P, SS for MLB; QB, WR for NFL). Null for tennis and when not yet ingested.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "rankings": {
        +      "description": "Sport ranking block. Tennis: {singles, points} from ATP/WTA standings. Null for every other sport. Tennis /stats also exposes ranking / ranking_points on the tennis player block.",
        +      "properties": {
        +        "points": {
        +          "description": "ATP/WTA ranking points. Tennis only.",
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        },
        +        "singles": {
        +          "description": "ATP/WTA singles ranking. Tennis only.",
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        }
        +      },
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "retired_at": {
        +      "description": "YYYY-MM-DD retirement date when known.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "slug": {
        +      "description": "URL-safe unique slug.",
        +      "type": "string"
        +    },
        +    "sport": {
        +      "description": "Sport slug, e.g. mlb, tennis, nfl.",
        +      "type": "string"
        +    },
        +    "weight_kg": {
        +      "description": "Weight in kilograms. Null when not ingested.",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedget_player_events5 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last event id from previous page."New value: +"Cursor: last event id from the previous page's next_after_id."
      • addedInput schema / properties / limit / description
        Added value: +"Max events to return per page."
      • addedInput schema / properties / player_id / description
        Added value: +"Player id, from search_players."
      • addedInput schema / properties / status / description
        Added value: +"Filter to events in this status."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Events in the same shape as list_events' EventSummary.",
        +      "items": {
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "has_more": {
        +      "type": "boolean"
        +    },
        +    "next_after_id": {
        +      "description": "Pass as after_id to fetch the next page; null on the last page.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "player_id": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_player_props
    • Changedget_splits2 fields changed
      • addedInput schema / properties / event_id / description
        Added value: +"Event id, from list_events, query_events, or search results."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "available": {
        +      "type": "boolean"
        +    },
        +    "bookmakers": {
        +      "description": "Per-bookmaker splits. Each item has bookmaker (odds slug), name, moneyline, spread, total.",
        +      "items": {
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "captured_at": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "consensus": {
        +      "description": "Aggregate bets%/handle% across bookmakers.",
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "event_id": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_stats
    • Changedget_team2 fields changed
      • addedInput schema / properties / team_id / description
        Added value: +"Team id, from list_teams."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "abbreviation": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "city": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "conference": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "division": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "id": {
        +      "type": "integer"
        +    },
        +    "image_url": {
        +      "description": "Lumify media URL for the team logo (https://lumify.ai/media/teams/{sport}/{id}.png). Null until ingest. Never a vendor CDN.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "league": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "slug": {
        +      "type": "string"
        +    },
        +    "sport": {
        +      "type": "string"
        +    },
        +    "venue": {
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedget_team_props
    • Addedlist_ev
    • Changedlist_events7 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: return events with id > after_id."New value: +"Cursor: return events with id > after_id (from the previous page's next_after_id)."
      • changedInput schema / properties / league / description
        Previous value: -"League slug, e.g. nfl, atp, fifa_world_cup."New value: +"League slug, e.g. nfl, atp, mls."
      • addedInput schema / properties / limit / description
        Added value: +"Max events to return per page."
      • changedInput schema / properties / season_id / description
        Previous value: -"Filter by season ID."New value: +"Filter by season ID (from list_seasons)."
      • addedInput schema / properties / status / description
        Added value: +"Filter to events in this status."
      • addedInput schema / properties / team_id
        Added value: +{
        +  "description": "Filter to events where this team participates. Resolve ids via list_teams.",
        +  "type": "integer"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "EventSummary": {
        +      "properties": {
        +        "clock": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "id": {
        +          "type": "integer"
        +        },
        +        "inprogress_since": {
        +          "description": "ISO-8601 UTC when status first became inprogress (first live tick). Null until then; stays set after final.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "league": {
        +          "type": "string"
        +        },
        +        "name": {
        +          "type": "string"
        +        },
        +        "period": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "season_id": {
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        },
        +        "sport": {
        +          "type": "string"
        +        },
        +        "starts_at": {
        +          "description": "ISO-8601 UTC start time.",
        +          "type": "string"
        +        },
        +        "status": {
        +          "type": "string"
        +        },
        +        "venue": {
        +          "type": [
        +            "object",
        +            "null"
        +          ]
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "events": {
        +      "items": {
        +        "$ref": "#/$defs/EventSummary"
        +      },
        +      "type": "array"
        +    },
        +    "next_after_id": {
        +      "description": "Pass as after_id to fetch the next page; null on the last page.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedlist_forecasts
    • Changedlist_seasons3 fields changed
      • changedInput schema / properties / current_only / default
        Previous value: -falseNew value: +true
      • changedInput schema / properties / current_only / description
        Previous value: -"Return only currently active seasons."New value: +"Return only currently active seasons (default true). Pass false for historical seasons."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "seasons": {
        +      "items": {
        +        "properties": {
        +          "end_date": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "id": {
        +            "type": "integer"
        +          },
        +          "is_current": {
        +            "type": "boolean"
        +          },
        +          "league": {
        +            "type": "object"
        +          },
        +          "name": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "phase": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "sport": {
        +            "type": "object"
        +          },
        +          "start_date": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "year": {
        +            "type": [
        +              "integer",
        +              "null"
        +            ]
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_sports2 fields changed
      • addedInput schema / properties / active_only / description
        Added value: +"When true (default), omit sports with no active coverage."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "sports": {
        +      "items": {
        +        "properties": {
        +          "id": {
        +            "type": "integer"
        +          },
        +          "is_team_sport": {
        +            "type": "boolean"
        +          },
        +          "leagues": {
        +            "items": {
        +              "properties": {
        +                "current_season": {
        +                  "type": [
        +                    "object",
        +                    "null"
        +                  ]
        +                },
        +                "id": {
        +                  "type": "integer"
        +                },
        +                "name": {
        +                  "type": "string"
        +                },
        +                "slug": {
        +                  "type": "string"
        +                }
        +              },
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "slug": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_teams7 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last team id from previous page."New value: +"Cursor: last team id from the previous page's next_after_id."
      • addedInput schema / properties / conference / description
        Added value: +"Conference name, e.g. AFC, Eastern."
      • addedInput schema / properties / division / description
        Added value: +"Division name, e.g. AFC East."
      • addedInput schema / properties / league / description
        Added value: +"League slug, e.g. nfl, mls."
      • addedInput schema / properties / limit / description
        Added value: +"Max teams to return per page."
      • addedInput schema / properties / sport / description
        Added value: +"Sport slug, e.g. nfl, nba, soccer."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "Team": {
        +      "properties": {
        +        "abbreviation": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "city": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "conference": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "country_code": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "division": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "id": {
        +          "type": "integer"
        +        },
        +        "image_url": {
        +          "description": "Lumify media URL for the team logo (https://lumify.ai/media/teams/{sport}/{id}.png). Null until ingest. Never a vendor CDN.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "is_active": {
        +          "type": "boolean"
        +        },
        +        "league": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "name": {
        +          "type": "string"
        +        },
        +        "short_name": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "slug": {
        +          "type": "string"
        +        },
        +        "sport": {
        +          "type": "string"
        +        },
        +        "state": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "venue": {
        +          "type": [
        +            "object",
        +            "null"
        +          ]
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "data": {
        +      "items": {
        +        "$ref": "#/$defs/Team"
        +      },
        +      "type": "array"
        +    },
        +    "has_more": {
        +      "type": "boolean"
        +    },
        +    "next_after_id": {
        +      "description": "Pass as after_id to fetch the next page; null on the last page.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedquery_events
    • Changedsearch_players5 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last player id from previous page."New value: +"Cursor: last player id from the previous page's next_after_id."
      • addedInput schema / properties / limit / description
        Added value: +"Max players to return per page."
      • changedInput schema / properties / ranked / description
        Previous value: -"If true, only players with a tennis ranking."New value: +"If true, only tennis players with an ATP/WTA singles ranking (rankings.singles)."
      • addedInput schema / properties / sport / description
        Added value: +"Sport slug, e.g. tennis, nba."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$defs": {
        +    "Player": {
        +      "properties": {
        +        "birthdate": {
        +          "description": "YYYY-MM-DD date of birth.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "country_code": {
        +          "description": "ISO 3166-1 alpha-3 country code.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "current_team_id": {
        +          "description": "Lumify team ID when the player is on a club roster. Null for tennis.",
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        },
        +        "current_team_name": {
        +          "description": "Current team display name. Null for tennis.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "first_name": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "full_name": {
        +          "description": "Display name.",
        +          "type": "string"
        +        },
        +        "handedness": {
        +          "description": "left | right | switch. Meaning is sport-specific (bats for MLB, shoots for NHL, playing hand for tennis). Null when unknown.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "height_cm": {
        +          "description": "Height in centimetres. Null when not ingested.",
        +          "type": [
        +            "integer",
        +            "null"
        +          ]
        +        },
        +        "id": {
        +          "description": "Lumify player ID.",
        +          "type": "integer"
        +        },
        +        "image_url": {
        +          "description": "Lumify media URL for the player headshot (https://lumify.ai/media/players/{sport}/{id}.{ext}). Null until the sport's headshot/enrichment job. Never a vendor CDN.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "is_active": {
        +          "description": "False when deactivated or retired.",
        +          "type": "boolean"
        +        },
        +        "last_name": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "position": {
        +          "description": "Roster position abbreviation when the sport has one (e.g. C, P, SS for MLB; QB, WR for NFL). Null for tennis and when not yet ingested.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "rankings": {
        +          "description": "Sport ranking block. Tennis: {singles, points} from ATP/WTA standings. Null for every other sport. Tennis /stats also exposes ranking / ranking_points on the tennis player block.",
        +          "properties": {
        +            "points": {
        +              "description": "ATP/WTA ranking points. Tennis only.",
        +              "type": [
        +                "integer",
        +                "null"
        +              ]
        +            },
        +            "singles": {
        +              "description": "ATP/WTA singles ranking. Tennis only.",
        +              "type": [
        +                "integer",
        +                "null"
        +              ]
        +            }
        +          },
        +          "type": [
        +            "object",
        +            "null"
        +          ]
        +        },
        +        "retired_at": {
        +          "description": "YYYY-MM-DD retirement date when known.",
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "slug": {
        +          "description": "URL-safe unique slug.",
        +          "type": "string"
        +        },
        +        "sport": {
        +          "description": "Sport slug, e.g. mlb, tennis, nfl.",
        +          "type": "string"
        +        },
        +        "weight_kg": {
        +          "description": "Weight in kilograms. Null when not ingested.",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "properties": {
        +    "data": {
        +      "items": {
        +        "$ref": "#/$defs/Player"
        +      },
        +      "type": "array"
        +    },
        +    "has_more": {
        +      "type": "boolean"
        +    },
        +    "next_after_id": {
        +      "description": "Pass as after_id to fetch the next page; null on the last page.",
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    }
        +  },
        +  "type": "object"
        +}
  12. 24 tool updates
    • Removedbatch_get_events
    • Removedestimate_cost
    • Changedget_event5 fields changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all."New value: +"Bookmaker for inlined odds; defaults to pinnacle, 'all' for every book."
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • changedInput schema / properties / include_intelligence / description
        Previous value: -"Inline bet intelligence. Does not add credits."New value: +"Inline bet intelligence (+1 credit when available)."
      • changedInput schema / properties / include_odds / description
        Previous value: -"Inline current odds scoped by bookmaker (default: pinnacle). Does not add credits — the event call stays 1 credit."New value: +"Inline current odds (+1 credit when odds are available)."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "id": {
        -      "type": "integer"
        -    },
        -    "inprogress_since": {
        -      "description": "ISO-8601 UTC when status first became inprogress (first live tick). Null until then; stays set after final.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "league": {
        -      "type": "string"
        -    },
        -    "name": {
        -      "type": "string"
        -    },
        -    "participants": {
        -      "items": {
        -        "properties": {
        -          "is_winner": {
        -            "type": [
        -              "boolean",
        -              "null"
        -            ]
        -          },
        -          "participant_id": {
        -            "type": "integer"
        -          },
        -          "player": {
        -            "type": [
        -              "object",
        -              "null"
        -            ]
        -          },
        -          "role": {
        -            "type": "string"
        -          },
        -          "score": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "team": {
        -            "type": [
        -              "object",
        -              "null"
        -            ]
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "sport": {
        -      "type": "string"
        -    },
        -    "starts_at": {
        -      "type": "string"
        -    },
        -    "status": {
        -      "type": "string"
        -    },
        -    "updated_at": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "venue": {
        -      "type": [
        -        "object",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedget_injuries
    • Changedget_intelligence3 fields changed
      • removedInput schema / properties / bookmaker / description
        Removed value: -"Ignored. Intelligence always reports the book the assessment was priced against. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada."
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • changedOutput schema / (root)
        Previous 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"
        -}New value: +null
    • Changedget_live_score2 fields changed
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "clock": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "event_id": {
        -      "type": "integer"
        -    },
        -    "finished": {
        -      "type": "boolean"
        -    },
        -    "period": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "scores": {
        -      "items": {
        -        "properties": {
        -          "abbreviation": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "is_winner": {
        -            "type": [
        -              "boolean",
        -              "null"
        -            ]
        -          },
        -          "name": {
        -            "type": "string"
        -          },
        -          "period_scores": {
        -            "items": {
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "role": {
        -            "type": "string"
        -          },
        -          "score": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "status": {
        -      "type": "string"
        -    },
        -    "updated_at": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Changedget_odds4 fields changed
      • removedInput schema / properties / bookmaker / description
        Removed value: -"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • removedInput schema / properties / include_alts
        Removed value: -{
        -  "description": "Include alternate spread/total rungs. Default false (mains only).",
        -  "type": "boolean"
        -}
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "available": {
        -      "type": "boolean"
        -    },
        -    "bookmakers": {
        -      "description": "Per-book markets. Outcomes include is_main. In-play omits books that have not quoted since kickoff. Final events add result (won/lost/push/void) and close on the pre-kickoff point.",
        -      "items": {
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "event_id": {
        -      "type": "integer"
        -    },
        -    "fallback_bookmaker": {
        -      "description": "The book actually returned when requested_bookmaker is present.",
        -      "type": "string"
        -    },
        -    "last_updated": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "requested_bookmaker": {
        -      "description": "Present only when the default (no bookmaker arg) request fell back to a different book because Pinnacle has no line yet — always 'pinnacle' when present.",
        -      "type": "string"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Changedget_odds_history4 fields changed
      • removedInput schema / properties / bookmaker / description
        Removed value: -"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • removedInput schema / properties / limit / description
        Removed value: -"Max line-movement entries to return. Default 50."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "event_id": {
        -      "type": "integer"
        -    },
        -    "movements": {
        -      "description": "Odds snapshots over time; each entry carries its own timestamp.",
        -      "items": {
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "total": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedget_period_odds
    • Changedget_player2 fields changed
      • removedInput schema / properties / player_id / description
        Removed value: -"Player id, from search_players."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "birthdate": {
        -      "description": "YYYY-MM-DD date of birth.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "country_code": {
        -      "description": "ISO 3166-1 alpha-3 country code.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "current_team_id": {
        -      "description": "Lumify team ID when the player is on a club roster. Null for tennis.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "current_team_name": {
        -      "description": "Current team display name. Null for tennis.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "first_name": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "full_name": {
        -      "description": "Display name.",
        -      "type": "string"
        -    },
        -    "handedness": {
        -      "description": "left | right | switch. Meaning is sport-specific (bats for MLB, shoots for NHL, playing hand for tennis). Null when unknown.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "height_cm": {
        -      "description": "Height in centimetres. Null when not ingested.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "id": {
        -      "description": "Lumify player ID.",
        -      "type": "integer"
        -    },
        -    "image_url": {
        -      "description": "Lumify media URL for the player headshot (https://lumify.ai/media/players/{sport}/{id}.{ext}). Null until the sport's headshot/enrichment job. Never a vendor CDN.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "is_active": {
        -      "description": "False when deactivated or retired.",
        -      "type": "boolean"
        -    },
        -    "last_name": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "position": {
        -      "description": "Roster position abbreviation when the sport has one (e.g. C, P, SS for MLB; QB, WR for NFL). Null for tennis and when not yet ingested.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "rankings": {
        -      "description": "Sport ranking block. Tennis: {singles, points} from ATP/WTA standings. Null for every other sport. Tennis /stats also exposes ranking / ranking_points on the tennis player block.",
        -      "properties": {
        -        "points": {
        -          "description": "ATP/WTA ranking points. Tennis only.",
        -          "type": [
        -            "integer",
        -            "null"
        -          ]
        -        },
        -        "singles": {
        -          "description": "ATP/WTA singles ranking. Tennis only.",
        -          "type": [
        -            "integer",
        -            "null"
        -          ]
        -        }
        -      },
        -      "type": [
        -        "object",
        -        "null"
        -      ]
        -    },
        -    "retired_at": {
        -      "description": "YYYY-MM-DD retirement date when known.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "slug": {
        -      "description": "URL-safe unique slug.",
        -      "type": "string"
        -    },
        -    "sport": {
        -      "description": "Sport slug, e.g. mlb, tennis, nfl.",
        -      "type": "string"
        -    },
        -    "weight_kg": {
        -      "description": "Weight in kilograms. Null when not ingested.",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Changedget_player_events5 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last event id from the previous page's next_after_id."New value: +"Cursor: last event id from previous page."
      • removedInput schema / properties / limit / description
        Removed value: -"Max events to return per page."
      • removedInput schema / properties / player_id / description
        Removed value: -"Player id, from search_players."
      • removedInput schema / properties / status / description
        Removed value: -"Filter to events in this status."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "data": {
        -      "description": "Events in the same shape as list_events' EventSummary.",
        -      "items": {
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "has_more": {
        -      "type": "boolean"
        -    },
        -    "next_after_id": {
        -      "description": "Pass as after_id to fetch the next page; null on the last page.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "player_id": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedget_player_props
    • Changedget_splits2 fields changed
      • removedInput schema / properties / event_id / description
        Removed value: -"Event id, from list_events, query_events, or search results."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "available": {
        -      "type": "boolean"
        -    },
        -    "bookmakers": {
        -      "description": "Per-bookmaker splits. Each item has bookmaker (odds slug), name, moneyline, spread, total.",
        -      "items": {
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "captured_at": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "consensus": {
        -      "description": "Aggregate bets%/handle% across bookmakers.",
        -      "type": [
        -        "object",
        -        "null"
        -      ]
        -    },
        -    "event_id": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedget_stats
    • Changedget_team2 fields changed
      • removedInput schema / properties / team_id / description
        Removed value: -"Team id, from list_teams."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "abbreviation": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "city": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "conference": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "division": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "id": {
        -      "type": "integer"
        -    },
        -    "image_url": {
        -      "description": "Lumify media URL for the team logo (https://lumify.ai/media/teams/{sport}/{id}.png). Null until ingest. Never a vendor CDN.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "is_active": {
        -      "type": "boolean"
        -    },
        -    "league": {
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "name": {
        -      "type": "string"
        -    },
        -    "slug": {
        -      "type": "string"
        -    },
        -    "sport": {
        -      "type": "string"
        -    },
        -    "venue": {
        -      "type": [
        -        "object",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedget_team_props
    • Removedlist_ev
    • Changedlist_events7 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: return events with id > after_id (from the previous page's next_after_id)."New value: +"Cursor: return events with id > after_id."
      • changedInput schema / properties / league / description
        Previous value: -"League slug, e.g. nfl, atp, mls."New value: +"League slug, e.g. nfl, atp, fifa_world_cup."
      • removedInput schema / properties / limit / description
        Removed value: -"Max events to return per page."
      • changedInput schema / properties / season_id / description
        Previous value: -"Filter by season ID (from list_seasons)."New value: +"Filter by season ID."
      • removedInput schema / properties / status / description
        Removed value: -"Filter to events in this status."
      • removedInput schema / properties / team_id
        Removed value: -{
        -  "description": "Filter to events where this team participates. Resolve ids via list_teams.",
        -  "type": "integer"
        -}
      • changedOutput schema / (root)
        Previous value: -{
        -  "$defs": {
        -    "EventSummary": {
        -      "properties": {
        -        "clock": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "id": {
        -          "type": "integer"
        -        },
        -        "inprogress_since": {
        -          "description": "ISO-8601 UTC when status first became inprogress (first live tick). Null until then; stays set after final.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "league": {
        -          "type": "string"
        -        },
        -        "name": {
        -          "type": "string"
        -        },
        -        "period": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "season_id": {
        -          "type": [
        -            "integer",
        -            "null"
        -          ]
        -        },
        -        "sport": {
        -          "type": "string"
        -        },
        -        "starts_at": {
        -          "description": "ISO-8601 UTC start time.",
        -          "type": "string"
        -        },
        -        "status": {
        -          "type": "string"
        -        },
        -        "venue": {
        -          "type": [
        -            "object",
        -            "null"
        -          ]
        -        }
        -      },
        -      "type": "object"
        -    }
        -  },
        -  "properties": {
        -    "events": {
        -      "items": {
        -        "$ref": "#/$defs/EventSummary"
        -      },
        -      "type": "array"
        -    },
        -    "next_after_id": {
        -      "description": "Pass as after_id to fetch the next page; null on the last page.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "total": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedlist_forecasts
    • Changedlist_seasons3 fields changed
      • changedInput schema / properties / current_only / default
        Previous value: -trueNew value: +false
      • changedInput schema / properties / current_only / description
        Previous value: -"Return only currently active seasons (default true). Pass false for historical seasons."New value: +"Return only currently active seasons."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "seasons": {
        -      "items": {
        -        "properties": {
        -          "end_date": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "id": {
        -            "type": "integer"
        -          },
        -          "is_current": {
        -            "type": "boolean"
        -          },
        -          "league": {
        -            "type": "object"
        -          },
        -          "name": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "phase": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "sport": {
        -            "type": "object"
        -          },
        -          "start_date": {
        -            "type": [
        -              "string",
        -              "null"
        -            ]
        -          },
        -          "year": {
        -            "type": [
        -              "integer",
        -              "null"
        -            ]
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "total": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Changedlist_sports2 fields changed
      • removedInput schema / properties / active_only / description
        Removed value: -"When true (default), omit sports with no active coverage."
      • changedOutput schema / (root)
        Previous value: -{
        -  "properties": {
        -    "sports": {
        -      "items": {
        -        "properties": {
        -          "id": {
        -            "type": "integer"
        -          },
        -          "is_team_sport": {
        -            "type": "boolean"
        -          },
        -          "leagues": {
        -            "items": {
        -              "properties": {
        -                "current_season": {
        -                  "type": [
        -                    "object",
        -                    "null"
        -                  ]
        -                },
        -                "id": {
        -                  "type": "integer"
        -                },
        -                "name": {
        -                  "type": "string"
        -                },
        -                "slug": {
        -                  "type": "string"
        -                }
        -              },
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "name": {
        -            "type": "string"
        -          },
        -          "slug": {
        -            "type": "string"
        -          }
        -        },
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "total": {
        -      "type": "integer"
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Changedlist_teams7 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last team id from the previous page's next_after_id."New value: +"Cursor: last team id from previous page."
      • removedInput schema / properties / conference / description
        Removed value: -"Conference name, e.g. AFC, Eastern."
      • removedInput schema / properties / division / description
        Removed value: -"Division name, e.g. AFC East."
      • removedInput schema / properties / league / description
        Removed value: -"League slug, e.g. nfl, mls."
      • removedInput schema / properties / limit / description
        Removed value: -"Max teams to return per page."
      • removedInput schema / properties / sport / description
        Removed value: -"Sport slug, e.g. nfl, nba, soccer."
      • changedOutput schema / (root)
        Previous value: -{
        -  "$defs": {
        -    "Team": {
        -      "properties": {
        -        "abbreviation": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "city": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "conference": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "country_code": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "division": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "id": {
        -          "type": "integer"
        -        },
        -        "image_url": {
        -          "description": "Lumify media URL for the team logo (https://lumify.ai/media/teams/{sport}/{id}.png). Null until ingest. Never a vendor CDN.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "is_active": {
        -          "type": "boolean"
        -        },
        -        "league": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "name": {
        -          "type": "string"
        -        },
        -        "short_name": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "slug": {
        -          "type": "string"
        -        },
        -        "sport": {
        -          "type": "string"
        -        },
        -        "state": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "venue": {
        -          "type": [
        -            "object",
        -            "null"
        -          ]
        -        }
        -      },
        -      "type": "object"
        -    }
        -  },
        -  "properties": {
        -    "data": {
        -      "items": {
        -        "$ref": "#/$defs/Team"
        -      },
        -      "type": "array"
        -    },
        -    "has_more": {
        -      "type": "boolean"
        -    },
        -    "next_after_id": {
        -      "description": "Pass as after_id to fetch the next page; null on the last page.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
    • Removedquery_events
    • Changedsearch_players5 fields changed
      • changedInput schema / properties / after_id / description
        Previous value: -"Cursor: last player id from the previous page's next_after_id."New value: +"Cursor: last player id from previous page."
      • removedInput schema / properties / limit / description
        Removed value: -"Max players to return per page."
      • changedInput schema / properties / ranked / description
        Previous value: -"If true, only tennis players with an ATP/WTA singles ranking (rankings.singles)."New value: +"If true, only players with a tennis ranking."
      • removedInput schema / properties / sport / description
        Removed value: -"Sport slug, e.g. tennis, nba."
      • changedOutput schema / (root)
        Previous value: -{
        -  "$defs": {
        -    "Player": {
        -      "properties": {
        -        "birthdate": {
        -          "description": "YYYY-MM-DD date of birth.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "country_code": {
        -          "description": "ISO 3166-1 alpha-3 country code.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "current_team_id": {
        -          "description": "Lumify team ID when the player is on a club roster. Null for tennis.",
        -          "type": [
        -            "integer",
        -            "null"
        -          ]
        -        },
        -        "current_team_name": {
        -          "description": "Current team display name. Null for tennis.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "first_name": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "full_name": {
        -          "description": "Display name.",
        -          "type": "string"
        -        },
        -        "handedness": {
        -          "description": "left | right | switch. Meaning is sport-specific (bats for MLB, shoots for NHL, playing hand for tennis). Null when unknown.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "height_cm": {
        -          "description": "Height in centimetres. Null when not ingested.",
        -          "type": [
        -            "integer",
        -            "null"
        -          ]
        -        },
        -        "id": {
        -          "description": "Lumify player ID.",
        -          "type": "integer"
        -        },
        -        "image_url": {
        -          "description": "Lumify media URL for the player headshot (https://lumify.ai/media/players/{sport}/{id}.{ext}). Null until the sport's headshot/enrichment job. Never a vendor CDN.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "is_active": {
        -          "description": "False when deactivated or retired.",
        -          "type": "boolean"
        -        },
        -        "last_name": {
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "position": {
        -          "description": "Roster position abbreviation when the sport has one (e.g. C, P, SS for MLB; QB, WR for NFL). Null for tennis and when not yet ingested.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "rankings": {
        -          "description": "Sport ranking block. Tennis: {singles, points} from ATP/WTA standings. Null for every other sport. Tennis /stats also exposes ranking / ranking_points on the tennis player block.",
        -          "properties": {
        -            "points": {
        -              "description": "ATP/WTA ranking points. Tennis only.",
        -              "type": [
        -                "integer",
        -                "null"
        -              ]
        -            },
        -            "singles": {
        -              "description": "ATP/WTA singles ranking. Tennis only.",
        -              "type": [
        -                "integer",
        -                "null"
        -              ]
        -            }
        -          },
        -          "type": [
        -            "object",
        -            "null"
        -          ]
        -        },
        -        "retired_at": {
        -          "description": "YYYY-MM-DD retirement date when known.",
        -          "type": [
        -            "string",
        -            "null"
        -          ]
        -        },
        -        "slug": {
        -          "description": "URL-safe unique slug.",
        -          "type": "string"
        -        },
        -        "sport": {
        -          "description": "Sport slug, e.g. mlb, tennis, nfl.",
        -          "type": "string"
        -        },
        -        "weight_kg": {
        -          "description": "Weight in kilograms. Null when not ingested.",
        -          "type": [
        -            "number",
        -            "null"
        -          ]
        -        }
        -      },
        -      "type": "object"
        -    }
        -  },
        -  "properties": {
        -    "data": {
        -      "items": {
        -        "$ref": "#/$defs/Player"
        -      },
        -      "type": "array"
        -    },
        -    "has_more": {
        -      "type": "boolean"
        -    },
        -    "next_after_id": {
        -      "description": "Pass as after_id to fetch the next page; null on the last page.",
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    }
        -  },
        -  "type": "object"
        -}New value: +null
  13. 2 tool updates
    • Changedget_intelligence1 field changed
      • changedOutput schema / properties / forecasts / items / properties / research / description
        Previous value: -"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 does the reverse. The chosen side stays. Null means read p_hit from the rate model alone."New value: +"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."
    • Changedlist_forecasts1 field changed
      • changedOutput schema / properties / wagers / items / properties / research / description
        Previous value: -"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 does the reverse. The chosen side stays. Null means read p_hit from the rate model alone."New value: +"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."
  14. 2 tool updates
    • Changedget_intelligence1 field changed
      • changedOutput schema / properties / forecasts / items / properties / market / description
        Previous value: -"Player-prop rows: prop category (1:1 counting stats). MLB: strikeouts_pitcher, hits, rbis, runs, strikeouts_batter, hits_allowed, earned_runs, outs_recorded. NFL/NCAAF: passing/rushing/receiving_yards, receptions. 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."New value: +"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."
    • Changedlist_forecasts1 field changed
      • changedOutput schema / properties / wagers / items / properties / market / description
        Previous value: -"Player-prop rows: prop category (1:1 counting stats). MLB: strikeouts_pitcher, hits, rbis, runs, strikeouts_batter, hits_allowed, earned_runs, outs_recorded. NFL/NCAAF: passing/rushing/receiving_yards, receptions. 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."New value: +"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."
  15. 1 tool update
    • Removedget_prediction_markets
  16. 6 tool updates
    • Changedbatch_get_events1 field changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, all."New value: +"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all."
    • Changedget_event1 field changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, all."New value: +"Bookmaker for inlined odds and intelligence market prices. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all."
    • Changedget_intelligence1 field changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Ignored. Intelligence always reports the book the assessment was priced against. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig."New value: +"Ignored. Intelligence always reports the book the assessment was priced against. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada."
    • Changedget_odds1 field changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, all, or a comma-separated list."New value: +"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
    • Changedget_odds_history1 field changed
      • changedInput schema / properties / bookmaker / description
        Previous value: -"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, all, or a comma-separated list."New value: +"Bookmaker slug. Defaults to pinnacle. Valid: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list."
    • Changedget_player_props1 field changed
      • changedOutput schema / properties / player_props / description
        Previous value: -"One row per (player, market, line). Fields: player, player_id (null if unmatched), market (prop category), line, current (this-event box count), pct_of_line, settleable, result (in_progress / over / under / push, or null), books ({book_slug: {over, under}} American prices)."New value: +"One row per (player, market, line). Fields: player, player_id (null if unmatched), market (prop category), line, current (this-event box count), pct_of_line, settleable, result (in_progress / over / under / push / dnp — box landed and this player has zero rows / no_stat — played but this slug never landed, unmatched, or box not landed yet; null when not settleable), books ({book_slug: {over, under}} American prices)."

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Provides AI assistants with sports model win probabilities and fair odds across nine sports without requiring an API key.
    3
    60 npm
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides comprehensive sports intelligence including live scores, standings, schedules, betting odds, news, highlights, and more via SSE transport.
    -
  • A
    license
    A
    quality
    A
    maintenance
    Live sports betting odds, cross-book +EV, and graded player-prop resolution across 13 books.
    11
    1,312 npm
    1
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Provides AI agents with live, grounded sports data including model probabilities, track records, and European soccer and tennis arbitrage opportunities, so they answer from real numbers instead of stale guesses.
    13
    47 npm
    1
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.