# Lumify — OpenAPI-derived endpoint dump for AI Agents # https://lumify.ai/openapi-llms.txt # # Auto-generated from the OpenAPI schema by scripts/gen_llms_full.py — do not edit # by hand. Embedded in /docs/llms-full.txt. For GEO orientation see /llms-full.txt; # for the short overview see /llms.txt. > Lumify is an agent-ready sports intelligence API: schedules, live scores, odds, > public betting splits, and AI-powered bet intelligence (confidence scores, > signal breakdowns, and LLM-generated narratives) across MLB, tennis, soccer > (MLS, EPL, La Liga, Serie A, Bundesliga, Ligue 1, and UEFA > Champions League), NFL, NCAAF, NCAAB, NBA, and NHL. ## Base URL https://lumify.ai ## Authentication Every /v1/* request requires a Bearer API key: Authorization: Bearer lmfy-xxxxxx.yyyyyyyy... Create keys at https://lumify.ai/api-keys or programmatically via POST /api/agent/keys. ## Conventions - Timestamps: ISO-8601 UTC with trailing Z (2026-06-23T23:40:00Z). - Errors: {"error": {"code","message","status","doc_url"}, "detail": "..."} — switch on error.code. - Headers: X-RateLimit-{Limit,Remaining,Reset}, X-Credits-Used, X-Credits-Remaining. - Pagination: cursor-based ?after_id=&limit= (max 100); responses carry next_after_id. - Credits: one successful request = 1 credit. include_odds / include_intelligence do not add extra. Errors and available:false are free. ## Model Context Protocol (MCP) Connect an MCP client to https://lumify.ai/mcp (streamable HTTP), authenticating with your Lumify API key. Tools mirror the endpoints below. ## Endpoints ### GET /api/agent/credit-packs List purchasable credit packs Returns: CreditPackListResponse Fields: data: array, total: integer CreditPack fields: id: integer | null, name: string | null, credits: integer | null, price_cents: integer | null, bonus_credits: integer | null ### GET /api/agent/credits Get credit balance and usage Returns: AgentCreditsResponse Fields: tier: string | null, credits_used: integer | null, credit_limit: integer | null, bonus_credits: integer | null, total_remaining: integer | null, period_start: string | null, period_end: string | null, is_trial: boolean | null, is_trial_expired: boolean | null ### POST /api/agent/credits/topup Purchase a credit pack Request body: application/json object (see /openapi.json for schema). Returns: CreditTopupResponse Fields: success: boolean | null, credits_added: integer | null, bonus_credits: integer | null, pack_id: integer | null ### GET /api/agent/keys List API keys Returns: AgentApiKeyListResponse Fields: data: array, total: integer AgentApiKey fields: id: integer | null, name: string | null, key_prefix: string | null, scopes: array | null, created_at: string | null, last_used_at: string | null, expires_at: string | null, is_active: boolean | null, key: string | null ### POST /api/agent/keys Create an API key Request body: application/json object (see /openapi.json for schema). Returns: AgentApiKey Fields: id: integer | null, name: string | null, key_prefix: string | null, scopes: array | null, created_at: string | null, last_used_at: string | null, expires_at: string | null, is_active: boolean | null, key: string | null ### DELETE /api/agent/keys/{key_id} Revoke an API key Parameters: - key_id (integer, required, in=path): Returns: AgentApiKeyRevokeResponse Fields: revoked: boolean, id: integer | null ### POST /mcp MCP JSON-RPC endpoint (streamable HTTP) ### POST /v1/estimate Estimate the credit cost of a planned call (or batch of calls) Request body: application/json object (see /openapi.json for schema). Returns: EstimateResponse Fields: estimates: array, total_min_credits: integer, total_max_credits: integer EstimateResult fields: tool: string, min_credits: integer, max_credits: integer, note: string | null ### GET /v1/estimate/tools List the tools /v1/estimate understands Returns: object ### GET /v1/events List events Parameters: - sport (string | null, optional, in=query): Sport slug: nfl, nba, mlb, nhl, tennis, soccer… - league (string | null, optional, in=query): League slug: nfl, nba, atp, mls… - status (string | null, optional, in=query): Event status: scheduled|inprogress|final|… - date (string | null, optional, in=query): UTC date YYYY-MM-DD (single day) - from (string | null, optional, in=query): UTC start date YYYY-MM-DD - to (string | null, optional, in=query): UTC end date YYYY-MM-DD (inclusive) - season_id (integer | null, optional, in=query): Filter by season ID - team_id (integer | null, optional, in=query): Filter to events where this team participates. Resolve ids via GET /v1/teams?q=… - after_id (integer | null, optional, in=query): Cursor: return events with id > after_id - limit (integer, optional, in=query): - include_scores (boolean, optional, in=query): Inline participants + scores in each event. Intended for small result sets (≤ 200 events). Shares the 20/min score-poll budget with GET /events/{id}/score; prefer GET /events/{id}/stream for live boards. - has_recommend (boolean | null, optional, in=query): When true, return only events with at least one recommended bet (has_recommend=1 in intelligence). Requires intelligence pipeline to have run. - sort (string, optional, in=query): Sort order: 'time' (chronological, default) or 'status' (Live → Delayed/Upcoming → Final → Cancelled/Postponed). Cursor pagination (after_id) is not supported with sort=status. Returns: EventListResponse Fields: events: array, total: integer, next_after_id: integer | null EventSummary fields: id: integer, name: string | null, sport: string | null, league: string | null, season_id: integer | null, starts_at: string | null, inprogress_since: string | null, status: string | null, period: string | null, clock: string | null, venue: object | null ### POST /v1/events/batch Get multiple events in one call Fetch multiple events by id in a single round-trip — for agents that already have a list of ids (e.g. from GET /v1/events) and want full detail for each without issuing one GET per event. Body: {"event_ids": [1, 2, 3], "include_odds": bool, "include_intelligence": bool, "bookmaker": str} Max 25 ids per call. Duplicate ids are billed once. Credits are the sum of each event's normal GET /v1/events/{id} cost — billing fairness applies per event (unavailable odds/intelligence are free; ids that don't exist cost nothing and are returned under "not_found"). Request body: application/json object (see /openapi.json for schema). Returns: BatchEventsResponse Fields: events: array, not_found: array, total: integer EventDetail fields: id: integer, name: string | null, sport: string | null, league: string | null, season_id: integer | null, starts_at: string | null, inprogress_since: string | null, status: string | null, period: string | null, clock: string | null, venue: object | null, participants: array, updated_at: string | null ### GET /v1/events/{event_id} Get an event Parameters: - event_id (integer, required, in=path): Lumify event ID - include_odds (boolean, optional, in=query): Inline current odds into the response under the 'odds' key. Scoped by bookmaker (default: pinnacle). Does not add credits — the event call stays 1 credit. - include_intelligence (boolean, optional, in=query): Inline bet intelligence (signals, bets, narratives) into the response under the 'intelligence' key. Does not add credits — the event call stays 1 credit. - bookmaker (string | null, optional, in=query): Bookmaker filter for inlined odds (when include_odds=true) and for intelligence.bets[].market prices (when include_intelligence=true). Valid values: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all. Defaults to pinnacle. - include_alts (boolean, optional, in=query): When include_odds=true, include alternate spread/total rungs (is_main=false). Default is mains only. Returns: EventDetail Fields: id: integer, name: string | null, sport: string | null, league: string | null, season_id: integer | null, starts_at: string | null, inprogress_since: string | null, status: string | null, period: string | null, clock: string | null, venue: object | null, participants: array, updated_at: string | null Participant fields: participant_id: integer | null, role: string | null, team: object | null, player: object | null, score: string | null, is_winner: boolean | null ### GET /v1/events/{event_id}/injuries Get late-breaking injury / availability for an event (Beta) **Beta.** Structured player injury and availability status for an upcoming event, written by an automated monitoring pipeline that watches for late-breaking status changes. 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. Checks run on a hours-to-start cadence and also when a main-market line moves ≥20 American-odds points or ≥1.0 spread/total point, plus a guaranteed pre-kickoff confirmation per sport. Subscribe to webhook event_type=injury for material/critical status changes (info reconfirms never fire). available:false is free. No in-game feed. Parameters: - event_id (integer, required, in=path): Lumify event ID - exclude_status (string | null, optional, in=query): Comma-separated injury statuses to drop from the response, e.g. exclude_status=ir to hide injured-reserve/long-term-IL rows (long-standing roster designations, not late-breaking news — these rows are also the most likely to have body_part=null, since roster/depth-chart sources report a designation + return-eligibility date rather than injury details). Does not affect available or X-Credits-Used, which reflect whether the monitor has written any report at all. Valid values: available, day_to_day, doubtful, ir, out, probable, questionable, suspended. Returns: InjuriesResponse Fields: event_id: integer, available: boolean, last_checked_at: string | null, confirmed_at: string | null, next_check_at: string | null, injuries: array InjuryItem fields: player: string, player_id: integer | null, team: string | null, team_id: integer | null, status: string, previous_status: string | null, body_part: string | null, note: string | null, source_url: string | null, severity: string, last_changed_at: string | null ### GET /v1/events/{event_id}/intelligence Get bet intelligence for an event Parameters: - event_id (integer, required, in=path): Lumify event ID - bookmaker (string | null, optional, in=query): Ignored. Intelligence always reports the book the assessment was priced against. Accepted values (pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada) are kept for compatibility and do not change market.price or fair_price. Returns: IntelligenceResponse Fields: event_id: integer | null, available: boolean, odds_source: string | null, sport: string | null, league: string | null, players: object, has_recommend: boolean | null, match_overview: string | null, rationale: array | null, intelligence_updated_at: string | null, bets: array, forecasts: array, matchup: object | null BetIntelligence fields: bet_type: string | null, player_role: string | null, player_id: integer | null, team_id: integer | null, player_name: string | null, market: object | null, computed_at: string | null, tier: string | null, confidence_score: number | null, confidence_score_pre_validator: number | null, coverage: number | null, signals: object | null, validator: object | null, narrative: string | null, rationale: array, attribution: array, probability: number | null, interval: array | null, p_model: number | null, p_market: number | null, blend_w: number | null, fair_price: integer | null, edge: number | null, sufficiency: number | null, phase: string | null, model_version: string | null, drivers: array, alignment: object | null, fair: object | null, edges_by_book: object | null, best: object | null, ev: object | null ForecastWager fields: event_id: integer | null, sport: string | null, league: string | null, commence_time: string | null, home_team: string | null, away_team: string | null, player: string | null, player_id: integer | null, bet_type: string | null, player_role: string | null, market: string, line: number | null, side: string | null, p_hit: number, interval: array, sufficiency: number, reliability: string, conviction: number, model_version: string, selected: boolean, books: object, drivers: array, research: object | null ### GET /v1/events/{event_id}/odds Get current betting odds for an event Parameters: - event_id (integer, required, in=path): Lumify event ID - bookmaker (string | null, optional, in=query): Bookmaker filter. Default: pinnacle. Accepted values: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list (e.g. 'fanduel,betmgm'). One book or all = 1 credit. - include_alts (boolean, optional, in=query): Include alternate spread/total rungs (is_main=false). Default is mains only. Returns: OddsResponse Fields: event_id: integer | null, available: boolean, bookmakers: array, last_updated: string | null, requested_bookmaker: string | null, fallback_bookmaker: string | null ### GET /v1/events/{event_id}/odds/history Get line movement history for an event Parameters: - event_id (integer, required, in=path): Lumify event ID - bookmaker (string | null, optional, in=query): Bookmaker filter. Default: pinnacle. Accepted values: pinnacle, fanduel, draftkings, betmgm, caesars, bet365, circa, westgate, wynn, south_point, stations, hardrock, betonline, betr, betrivers, lowvig, bovada, all, or a comma-separated list. One book or all = 1 credit. - limit (integer, optional, in=query): Max movements to return Returns: OddsHistoryResponse Fields: event_id: integer, movements: array, total: integer ### GET /v1/events/{event_id}/period-odds Get first-half / first-five / first-set lines and live progress for an event NFL, NCAAF, NBA, NCAAB, MLB, Soccer, and Tennis only. 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 stays on h2h/spreads/totals. Other sports return HTTP 400. available:false is free. Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: PeriodOddsResponse Fields: event_id: integer, available: boolean, sport: string | null, status: string | null, period: string | null, clock: string | null, period_odds: array PeriodOddsLine fields: scope: string, market: string, line: number, home_score: number | null, away_score: number | null, current: number | null, current_margin: number | null, pct_of_line: number | null, settleable: boolean, scope_complete: boolean, result: string | null, home_result: string | null, away_result: string | null, books: object ### GET /v1/events/{event_id}/player-props Get player-prop lines and live progress for an event NFL, NCAAF, NBA, NCAAB, NHL, MLB, and Soccer only. Joins persisted player-prop mains to this-event player box rows and grades over/under/push (1:1 slugs, combo sums including rush+rec and pass+rush yards, weighted combos, and yes/no thresholds). GET /odds stays on h2h/spreads/totals. Other sports return HTTP 400. available:false is free. Market catalog: https://lumify.ai/docs/player-props Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: PlayerPropsResponse Fields: event_id: integer, available: boolean, sport: string | null, status: string | null, period: string | null, clock: string | null, player_props: array PlayerPropLine fields: player: string, player_id: integer | null, market: string, line: number, current: number | null, pct_of_line: number | null, settleable: boolean, result: string | null, books: object ### GET /v1/events/{event_id}/score Get an event's score Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: ScoreResponse Fields: event_id: integer, status: string | null, finished: boolean | null, period: string | null, clock: string | null, scores: array, updated_at: string | null ScoreEntry fields: role: string | null, name: string | null, abbreviation: string | null, score: string | null, is_winner: boolean | null, period_scores: array ### GET /v1/events/{event_id}/splits Get public betting splits for an event Public bets% and handle% per side (moneyline, spread, total), with a cross-book consensus and per-bookmaker breakdown. Bookmaker keys match /odds slugs (e.g. draftkings, fanduel) under bookmakers[].bookmaker. Available for MLB, NBA, NHL, NFL, NCAAF, and NCAAB. Not available for tennis or soccer (upstream 400). available:false is free. Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: SplitsResponse Fields: event_id: integer, available: boolean, captured_at: string | null, consensus: object, bookmakers: array ### GET /v1/events/{event_id}/stats Get raw team/match statistics for an event (Data layer) Soccer, MLB, tennis, NFL, NCAAF, NBA, NCAAB, and NHL. Deterministic aggregates from completed results — no odds (see /odds) and no scoring (see /intelligence). Payload shapes are sport-specific (team-keyed except tennis). Tennis: main-draw singles only (doubles/qualifying return available:false). Form/record/H2H exclude walkovers and NFL/NCAAF/NBA/NCAAB preseason. Other sports return HTTP 400. available:false is free. Field catalog: https://lumify.ai/docs/reference#event-stats Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: StatsResponse | MlbStatsResponse | TennisStatsResponse | NflStatsResponse | NbaStatsResponse | NhlStatsResponse | NcaafStatsResponse | NcaabStatsResponse ### GET /v1/events/{event_id}/stream Stream live score updates (SSE) Parameters: - event_id (integer, required, in=path): Lumify event ID ### GET /v1/events/{event_id}/team-props Get team-total lines and live progress for an event NFL, NCAAF, MLB, and Soccer only. Joins persisted team-total mains to this-event participant scores and grades over/under/push. GET /odds stays on h2h/spreads/totals. Other sports return HTTP 400. available:false is free. Parameters: - event_id (integer, required, in=path): Lumify event ID Returns: TeamPropsResponse Fields: event_id: integer, available: boolean, sport: string | null, status: string | null, period: string | null, clock: string | null, team_props: array TeamPropLine fields: team: string, team_id: integer | null, side: string, market: string, line: number, current: number | null, pct_of_line: number | null, settleable: boolean, result: string | null, books: object ### POST /v1/grade/slip Grade settleable player-prop and game-market legs Grade settleable player-prop legs (over/under/push/in_progress/dnp/no_stat) on nfl/nba/ncaaf/ncaab/nhl/mlb/soccer, plus structured game markets (h2h/spreads/totals) on any sport GET /odds already settles. Structured event_id preferred; player_id is required on props and forbidden on game keys. Free-text player props are graded only when player and event resolve uniquely — ambiguous names stay unmapped with candidates. Call this endpoint or MCP grade_slip with an API key to grade from an app or agent. 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. Request body: application/json object (see /openapi.json for schema). Returns: GradeSlipResponse Fields: status: string, legs: array, summary: GradeSlipSummary, branding: GradeSlipBranding, honesty: GradeSlipHonesty, slip_id: string | null GradeSlipLeg fields: input: object | null, resolve: GradeSlipResolve | null, team_resolve: GradeSlipTeamResolve | null, event_resolve: GradeSlipEventResolve | null, market: GradeSlipMarket | null, current: number | null, result: string | null, message: string | null GradeSlipSummary fields: graded: integer, pending: integer, unmapped: integer, hits: integer, misses: integer, pushes: integer, voids: integer GradeSlipBranding fields: attribution: string, links: object GradeSlipHonesty fields: notes: array ### GET /v1/health Health ### GET /v1/intelligence/ev List main-line EV (Beta) opportunities Parameters: - sport (string, required, in=query): Sport slug. Predictive-framework sports only: soccer, mlb, tennis, nfl, ncaaf. - league (string | null, optional, in=query): Optional league slug (e.g. mls, epl, atp). Soccer without a league scans every published soccer league (MLS + big-five). - market (string, optional, in=query): Main-line family: h2h (default, moneyline), spreads, or totals. Tennis totals return 400 — Stage 1 does not publish a games-total sharp. - min_ev (number, optional, in=query): Minimum EV% to include. Clamped to 0–25. Default 0 (all positive). - book (string | null, optional, in=query): Restrict opportunities to one sportsbook slug (e.g. fanduel). - limit (integer, optional, in=query): Max opportunities to return (1–200). Returns: IntelligenceEvResponse Fields: sport: string, league: string | null, market: string, min_ev: number, max_ev: number, book: string | null, beta: boolean, opportunities: array, total: integer IntelligenceEvOpportunity fields: event_id: integer, sport: string, league: string | null, commence_time: string | null, home_team: string | null, away_team: string | null, side: string, team: string | null, bet_type: string, line: number | null, fair_probability: number, ev: object ### GET /v1/intelligence/forecasts List forecasted wagers (player props; main-line rows ship sport-by-sport) Parameters: - sport (string, required, in=query): Sport slug. Prop-forecast sports: mlb, ncaaf, nfl, nba, ncaab, nhl. Main-line forecast sports: tennis, nfl, ncaaf, mlb, soccer (high-confidence moneyline, spread, and total). - date (string | null, optional, in=query): UTC slate date YYYY-MM-DD. Defaults to today UTC. - market (string | null, optional, in=query): 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). - limit (integer, optional, in=query): Max wagers to return (1–100). Default 25. Returns: ForecastsResponse Fields: sport: string, date: string, model_version: string, reliability: string, wagers: array, total: integer ForecastWager fields: event_id: integer | null, sport: string | null, league: string | null, commence_time: string | null, home_team: string | null, away_team: string | null, player: string | null, player_id: integer | null, bet_type: string | null, player_role: string | null, market: string, line: number | null, side: string | null, p_hit: number, interval: array, sufficiency: number, reliability: string, conviction: number, model_version: string, selected: boolean, books: object, drivers: array, research: object | null ### GET /v1/players List players Parameters: - sport (string | null, optional, in=query): Sport slug, e.g. 'tennis' or 'mlb' - q (string | null, optional, in=query): Name search (partial match) - country (string | null, optional, in=query): ISO 3166-1 alpha-3 country code, e.g. 'USA' - active (boolean | null, optional, in=query): Filter by active status - ranked (boolean | null, optional, in=query): If true, only tennis players with an ATP/WTA singles ranking (rankings.singles). - after_id (integer, optional, in=query): Cursor: last player id from previous page - limit (integer, optional, in=query): Returns: PlayersListResponse Fields: data: array, has_more: boolean, next_after_id: integer | null Player fields: id: integer | null, slug: string | null, full_name: string | null, first_name: string | null, last_name: string | null, sport: string | null, country_code: string | null, birthdate: string | null, position: string | null, handedness: string | null, height_cm: integer | null, weight_kg: number | null, rankings: PlayerRankings | null, current_team_id: integer | null, current_team_name: string | null, is_active: boolean | null, retired_at: string | null, image_url: string | null ### GET /v1/players/{player_id} Get a player Parameters: - player_id (integer, required, in=path): Returns: Player Fields: id: integer | null, slug: string | null, full_name: string | null, first_name: string | null, last_name: string | null, sport: string | null, country_code: string | null, birthdate: string | null, position: string | null, handedness: string | null, height_cm: integer | null, weight_kg: number | null, rankings: PlayerRankings | null, current_team_id: integer | null, current_team_name: string | null, is_active: boolean | null, retired_at: string | null, image_url: string | null PlayerRankings fields: singles: integer | null, points: integer | null ### GET /v1/players/{player_id}/events List a player's events Parameters: - player_id (integer, required, in=path): - status (string | null, optional, in=query): Event status filter - from (string | null, optional, in=query): Start date YYYY-MM-DD - to (string | null, optional, in=query): End date YYYY-MM-DD - after_id (integer, optional, in=query): Cursor: last event id from previous page - limit (integer, optional, in=query): Returns: PlayerEventsResponse Fields: player_id: integer, data: array, has_more: boolean, next_after_id: integer | null ### POST /v1/query Natural-language event search Map a natural-language query to the same filters GET /v1/events accepts, then run that exact list query — results are identical to, and as fresh as, calling /v1/events directly. This is a small rule-based mapper, not an LLM call — see the module-level `_parse_nl_query` docstring for exactly what it recognizes. Body: {"query": "live nfl games today", "limit": 25} An explicit top-level "limit" overrides one parsed from the text. Costs 1 credit, same as GET /v1/events — interpreting the query text is free. Request body: application/json object (see /openapi.json for schema). Returns: NLQueryResponse Fields: query: string, interpreted: NLQueryFilters, unrecognized_terms: array, equivalent_request: string, events: array, total: integer, next_after_id: integer | null NLQueryFilters fields: sport: string | null, status: string | null, date: string | null, from: string | null, to: string | null, limit: integer | null EventSummary fields: id: integer, name: string | null, sport: string | null, league: string | null, season_id: integer | null, starts_at: string | null, inprogress_since: string | null, status: string | null, period: string | null, clock: string | null, venue: object | null ### POST /v1/resolve/event Resolve event identity from an id, player, or team clue Resolve event_id, or player_id/team_id + date window, to a Lumify event_id. Never guesses. Request body: application/json object (see /openapi.json for schema). Returns: ResolveEventResponse Fields: status: string, event_id: integer | null, sport: string | null, league: string | null, event_status: string | null, starts_at: string | null, home_team: string | null, away_team: string | null, confidence: number | null, match_reasons: array, clues_used: array, method: string | null, participant_conflict: boolean, candidates: array, message: string | null ResolveEventCandidate fields: event_id: integer | null, sport: string | null, league: string | null, event_status: string | null, starts_at: string | null, home_team: string | null, away_team: string | null, confidence: number | null, match_reasons: array ### POST /v1/resolve/player Resolve a messy player name to a Lumify player id Resolve messy sports player names to a Lumify player_id using sport, team, or event clues. Prefer before grade_slip. Returns ambiguous instead of guessing. Request body: application/json object (see /openapi.json for schema). Returns: ResolvePlayerResponse Fields: status: string, player_id: integer | null, display_name: string | null, sport: string | null, team_id: integer | null, confidence: number | null, match_reasons: array, clues_used: array, candidates: array, message: string | null ResolvePlayerCandidate fields: player_id: integer | null, display_name: string | null, sport: string | null, team_id: integer | null, confidence: number | null, match_reasons: array ### POST /v1/resolve/team Resolve a messy team string to a Lumify team id Resolve messy team names, abbreviations, metros, or aliases to a Lumify team_id using sport, league, event, or player clues. Returns ambiguous instead of guessing. Request body: application/json object (see /openapi.json for schema). Returns: ResolveTeamResponse Fields: status: string, team_id: integer | null, display_name: string | null, sport: string | null, league: string | null, abbreviation: string | null, confidence: number | null, match_reasons: array, clues_used: array, method: string | null, sport_conflict: boolean, candidates: array, message: string | null ResolveTeamCandidate fields: team_id: integer | null, display_name: string | null, sport: string | null, league: string | null, abbreviation: string | null, confidence: number | null, match_reasons: array ### GET /v1/seasons List seasons Parameters: - sport (string | null, optional, in=query): Filter by sport slug (e.g. nhl, nba, soccer) - current_only (boolean, optional, in=query): Return only currently active seasons (default true). Pass false to include historical/past seasons. Returns: SeasonsListResponse Fields: seasons: array, total: integer Season fields: id: integer | null, year: integer | null, name: string | null, phase: string | null, start_date: string | null, end_date: string | null, is_current: boolean | null, sport: object | null, league: object | null ### GET /v1/sports List sports Parameters: - active_only (boolean, optional, in=query): Return only active sports (default true) Returns: SportsListResponse Fields: sports: array, total: integer Sport fields: id: integer | null, slug: string | null, name: string | null, is_team_sport: boolean | null, leagues: array ### GET /v1/teams List teams Parameters: - sport (string | null, optional, in=query): Sport slug, e.g. 'nba' or 'nhl' - league (string | null, optional, in=query): League slug, e.g. 'nba' - conference (string | null, optional, in=query): Conference filter - division (string | null, optional, in=query): Division filter - country (string | null, optional, in=query): ISO country code, e.g. 'USA' - q (string | null, optional, in=query): Team name search (partial match) - active (boolean | null, optional, in=query): Filter by active status - after_id (integer, optional, in=query): Cursor: last team id from previous page - limit (integer, optional, in=query): Returns: TeamsListResponse Fields: data: array, has_more: boolean, next_after_id: integer | null Team fields: id: integer | null, slug: string | null, name: string | null, short_name: string | null, abbreviation: string | null, image_url: string | null, sport: string | null, league: string | null, city: string | null, state: string | null, country_code: string | null, conference: string | null, division: string | null, venue: object | null, is_active: boolean | null ### GET /v1/teams/{team_id} Get a team Parameters: - team_id (integer, required, in=path): Lumify team ID Returns: Team Fields: id: integer | null, slug: string | null, name: string | null, short_name: string | null, abbreviation: string | null, image_url: string | null, sport: string | null, league: string | null, city: string | null, state: string | null, country_code: string | null, conference: string | null, division: string | null, venue: object | null, is_active: boolean | null ### POST /v1/trial-key Issue an instant, unauthenticated trial API key Issues a throwaway API key with no signup or email verification — 100 lifetime credits, 14-day expiry, one per network per 7 days. Requires a valid Cloudflare Turnstile token. Intended for the 'Get instant trial key' button on /docs/ai, not for building a persistent integration — use /register for that. Request body: application/json object (see /openapi.json for schema). ### GET /v1/webhooks List webhook subscriptions Returns: WebhookListResponse Fields: data: array, total: integer WebhookSubscription fields: id: integer | null, url: string | null, event_types: array, sport: string | null, event_id: integer | null, is_active: boolean | null, created_at: string | null, signing_secret: string | null ### POST /v1/webhooks Create a webhook subscription Request body: application/json object (see /openapi.json for schema). Returns: WebhookCreateResponse Fields: id: integer | null, url: string | null, event_types: array, sport: string | null, event_id: integer | null, is_active: boolean | null, created_at: string | null, signing_secret: string | null ### DELETE /v1/webhooks/{subscription_id} Delete a webhook subscription Parameters: - subscription_id (integer, required, in=path): Returns: WebhookDeleteResponse Fields: deleted: boolean, id: integer | null ### GET /v1/webhooks/{subscription_id}/deliveries List delivery history for a webhook subscription Parameters: - subscription_id (integer, required, in=path): - after_id (integer | null, optional, in=query): Cursor: return deliveries with id < after_id (list is newest-first) - limit (integer, optional, in=query): - success (boolean | null, optional, in=query): Filter to successful (2xx) or failed deliveries - given_up (boolean | null, optional, in=query): Filter to deliveries that exhausted retries (or not) - event_type (string | null, optional, in=query): Filter by event type (score, status, line_move, injury) Returns: WebhookDeliveryListResponse Fields: data: array, next_after_id: integer | null WebhookDeliveryItem fields: id: integer | null, event_type: string | null, event_id: integer | null, attempt: integer | null, parent_delivery_id: integer | null, status_code: integer | null, success: boolean | null, error: string | null, given_up: boolean | null, next_retry_at: string | null, delivered_at: string | null ## Error codes - bad_request (400): malformed request or conflicting parameters - unauthorized (401): missing or invalid API key - payment_required (402): insufficient_credits, daily_credit_cap_exceeded, payment_failed (see error.code; upgrade_url / topup_url / billing_url / hosted_invoice_url; daily cap includes resets_at) - forbidden (403): API key lacks scope for the requested sport (see error.upgrade_url) - not_found (404): resource does not exist - validation_error (422): parameter failed validation (see error.errors[]) - rate_limit_exceeded (429): slow down; see Retry-After and error.retry_after - internal_error (500) / service_unavailable (503): transient server error — retry with backoff ## SDKs - Python: pip install lumify-sdk (import lumify) pip install 'lumify-sdk[asyncio]' (from lumify.aio import AsyncLumify) - TypeScript: npm install @lumifyai/sdk ## Support - Docs: https://lumify.ai/docs - Contact: https://lumify.ai/contact-us