Skip to content
On this page

API Endpoints

This is the full customer-facing REST API reference for Scottfree Sports.

Production base URL:

text
https://sports-api.scottfreellc.com

All /api/v1/* endpoints require an API key unless explicitly marked public. The production OpenAPI schema is also available at:

text
https://sports-api.scottfreellc.com/openapi.json

Common Path Values

Sports:

CodeLeague
mlbMajor League Baseball
nbaNational Basketball Association
nflNational Football League
nhlNational Hockey League
ncaafNCAA Football
ncaabNCAA Basketball

Model types:

Model typeMarketPositive sideNegative side
over_underTotalOverUnder
won_on_pointsMoneylineHome teamAway team
won_on_spreadSpreadHome spreadAway spread

Prediction model columns:

ColumnMeaning
IMPLIEDMarket-implied no-vig probability for the positive side
AIAI model probability, when present in the prediction artifact
BLENDEnsemble blend probability
CATBCatBoost
RFRandom Forest
LGBLightGBM
LOGRLogistic Regression
XGBXGBoost
XTExtra Trees

For moneyline and spread, probabilities are home-team relative. For over/under, probabilities are over-relative.

Authentication

Use the X-API-Key header:

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/sports

Bearer auth also works:

bash
curl -H "Authorization: Bearer $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/sports

Query-string auth works but is not recommended for production because keys can appear in logs:

bash
curl "https://sports-api.scottfreellc.com/api/v1/sports?api_key=$SFS_API_KEY"

Root And Health

GET /

Unauthenticated service root. Useful only for a quick connectivity check.

bash
curl https://sports-api.scottfreellc.com/

Response shape:

json
{
  "message": "AlphaPy Sports API",
  "version": "1.0.0",
  "docs": "Contact support for documentation",
  "security_scan": "disabled",
  "deployment_test": "ready"
}

GET /api/v1/health

Unauthenticated health check for production monitoring. Includes dependency status for Firestore, Redis, and GCS.

bash
curl https://sports-api.scottfreellc.com/api/v1/health

GET /api/v1/readiness

Unauthenticated readiness check used by Cloud Run.

bash
curl https://sports-api.scottfreellc.com/api/v1/readiness

GET /api/v1/liveness

Unauthenticated liveness check used by Cloud Run.

bash
curl https://sports-api.scottfreellc.com/api/v1/liveness

Discovery

GET /api/v1/sports

Returns supported sports and model types.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/sports

Response:

json
{
  "sports": [
    {"code": "mlb", "name": "Major League Baseball"},
    {"code": "nba", "name": "National Basketball Association"},
    {"code": "ncaab", "name": "NCAA Basketball"},
    {"code": "ncaaf", "name": "NCAA Football"},
    {"code": "nfl", "name": "National Football League"},
    {"code": "nhl", "name": "National Hockey League"}
  ],
  "model_types": [
    {"code": "over_under", "name": "Over/Under"},
    {"code": "won_on_points", "name": "Moneyline"},
    {"code": "won_on_spread", "name": "Point Spread"}
  ]
}

Predictions

GET /api/v1/predictions/{sport}/{model_type}

Returns model probabilities and market line fields for the current slate. Games are sorted by date and ET game time.

Tier: Basic and Premium.

Query parameters:

NameTypeDefaultDescription
upcoming_onlybooleantrueWhen true, excludes games before today's ET slate. If today's model run has not completed yet, the endpoint keeps the latest valid slate visible instead of disappearing at midnight. Set false to include the whole prediction artifact.

Examples:

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  "https://sports-api.scottfreellc.com/api/v1/predictions/mlb/won_on_points"

curl -H "X-API-Key: $SFS_API_KEY" \
  "https://sports-api.scottfreellc.com/api/v1/predictions/nba/won_on_spread?upcoming_only=false"

Response shape:

json
{
  "sport": "mlb",
  "model_type": "won_on_points",
  "predictions_date": "2026-05-23T14:12:05.000000",
  "games": [
    {
      "date": "2026-05-23",
      "time": "19:10:00",
      "away_team": "new_york_yankees",
      "home_team": "colorado_rockies",
      "predictions": {
        "IMPLIED": 0.3741,
        "BLEND": 0.4112,
        "XGB": 0.3929,
        "RF": 0.4255
      },
      "away_money_line": -135,
      "home_money_line": 115,
      "open_away_money_line": -128,
      "open_home_money_line": 108,
      "ev_away_ml": -3.1,
      "ev_home_ml": 1.8
    }
  ],
  "models_used": ["IMPLIED", "AI", "BLEND", "CATB", "RF", "LGB", "LOGR", "XGB", "XT"]
}

Market-specific fields:

Model typeCurrent line fieldsOpening line fieldsEV fields
over_underover_under, over_line, under_lineopen_over_underev_pos, ev_neg
won_on_spreadaway_point_spread, home_point_spread, away_point_spread_line, home_point_spread_lineopen_away_point_spread, open_home_point_spreadev_away_spread, ev_home_spread
won_on_pointsaway_money_line, home_money_lineopen_away_money_line, open_home_money_lineev_away_ml, ev_home_ml

EV fields are informational calculations from model probability and market price. They are not a validated betting selector and should not be treated as a guaranteed edge.

Public ML Predictions

GET /api/v1/public/ml-picks/{sport}/{market}

Public, unauthenticated endpoint used by the free website ML Predictions page. This is intentionally limited: it shows free model probabilities and current market line context, but it excludes account tooling, API key data, MCP/CLI, and paid app workflows.

Markets:

Public marketBacking model type
over_underover_under
moneylinewon_on_points
spreadwon_on_spread

Query parameters:

NameTypeDefaultDescription
upcoming_onlybooleantrueSame current-slate behavior as the authenticated predictions endpoint.

Example:

bash
curl "https://sports-api.scottfreellc.com/api/v1/public/ml-picks/mlb/moneyline"

Response shape:

json
{
  "sport": "mlb",
  "market": "moneyline",
  "model_type": "won_on_points",
  "predictions_date": "2026-05-23T14:12:05.000000",
  "games": [
    {
      "date": "2026-05-23",
      "time": "19:10:00",
      "away_team": "New York Yankees",
      "home_team": "Colorado Rockies",
      "pick": "Colorado Rockies ML",
      "pick_side": "home",
      "blend_probability": 0.4112,
      "confidence": 0.1776,
      "market_line": "ML -135/+115",
      "implied_probability": 0.3741,
      "lines": {
        "away_money_line": -135,
        "home_money_line": 115
      },
      "models": {
        "BLEND": 0.4112,
        "XGB": 0.3929
      }
    }
  ],
  "models_used": ["BLEND", "XGB", "RF", "LGB", "CATB", "LOGR", "XT"],
  "note": "Free ML predictions only. App workflows, MCP/CLI tools, and account features require a paid Scottfree Sports plan."
}

Odds

GET /api/v1/odds/{sport}

Returns current game odds for a sport.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/odds/mlb

Response shape:

json
{
  "sport": "mlb",
  "date": "2026-05-23T16:00:00.000000",
  "games": [
    {
      "match_id": "abc123",
      "date": "2026-05-23",
      "time": "19:10:00",
      "away_team": "new_york_yankees",
      "home_team": "colorado_rockies",
      "away_point_spread": -1.5,
      "away_point_spread_line": 145,
      "home_point_spread": 1.5,
      "home_point_spread_line": -165,
      "away_money_line": -135,
      "home_money_line": 115,
      "over_under": 10.5,
      "over_line": -110,
      "under_line": -110,
      "last_updated": "2026-05-23 15:55:00"
    }
  ],
  "last_updated": "2026-05-23T16:00:00.000000"
}

Results

GET /api/v1/results/{sport}/{model_type}

Returns recent graded prediction results. The response is intentionally flexible because result rows come from the generated model artifacts and can include additional columns.

Tier: Basic and Premium.

Query parameters:

NameTypeDefaultDescription
limitinteger100Maximum result rows to return.

Example:

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  "https://sports-api.scottfreellc.com/api/v1/results/mlb/won_on_points?limit=25"

Response shape:

json
{
  "sport": "mlb",
  "model_type": "won_on_points",
  "results": [
    {
      "date": "2026-05-22",
      "time_est": "19:10:00",
      "away_team": "new_york_yankees",
      "home_team": "colorado_rockies",
      "away_score": 4.0,
      "home_score": 2.0,
      "won_on_points": 0.0,
      "BLEND": 0.4112,
      "IMPLIED": 0.3741,
      "open_home_money_line": 108.0,
      "home_money_line": 115.0
    }
  ],
  "last_updated": "2026-05-23T14:20:00.000000"
}

GET /api/v1/results/{sport}/{model_type}/rolling

Returns precomputed 4-week rolling result curves by season for the selected sport and market. Used by the Results page visualizations.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/results/nfl/won_on_spread/rolling

Response includes:

FieldDescription
sportSport code
model_typeModel type
seasonsSeason-level rolling curves
historical_averageAverage curve across included seasons, when generated
last_updatedArtifact timestamp

GET /api/v1/results/{sport}/{model_type}/density

Returns precomputed result-density or distribution data for the selected sport and market. Used by Results page charts.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/results/nba/over_under/density

Response includes the generated chart payload and last_updated.

GET /api/v1/results/{sport}/{model_type}/team-form

Returns current-season team form from the daily-refreshed game-score tape, not from the limited live-results file.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/results/mlb/won_on_points/team-form

Response shape:

json
{
  "sport": "mlb",
  "model_type": "won_on_points",
  "current_season": "2026",
  "season_end": "2026-05-23",
  "last_n": 20,
  "teams": [
    {
      "team": "new_york_yankees",
      "games": 20,
      "wins": 12,
      "losses": 8,
      "win_pct": 0.6,
      "last_10": [1, 0, 1, 1, 0, 1, 0, 1, 1, 0],
      "streak": "W1"
    }
  ],
  "last_updated": "2026-05-23T16:00:00.000000"
}

Summary

GET /api/v1/summary/{sport}/{model_type}

Returns model performance summaries for the selected sport and market.

Tier: Basic and Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/summary/mlb/won_on_points

Response shape:

json
{
  "sport": "mlb",
  "model_type": "won_on_points",
  "summaries": [
    {
      "model": "BLEND",
      "total_games": 420,
      "wins": 214,
      "losses": 206,
      "win %": 50.95,
      "win % 4W": 51.8,
      "fade %": 49.05,
      "home %": 52.1,
      "away %": 47.9,
      "home % 1W": 48.5,
      "away % 1W": 51.5,
      "ev roi": null,
      "bt bets": 0,
      "bt units": null
    }
  ],
  "generated_date": "2026-05-23T14:20:00.000000"
}

Summary labels are market-relative:

Model typePositive labelNegative label
over_underoverunder
won_on_pointshomeaway
won_on_spreadhomeaway

Customer Account

GET /api/v1/customers/me

Returns the current customer record for the API key.

Tier: Basic and Premium. Sports Data keys can call this too, but may have api_plan: null or a zero API quota if they do not have Basic/Premium.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/customers/me

Response shape:

json
{
  "customer_id": "cus_abc123",
  "email": "customer@example.com",
  "name": "Customer Name",
  "tier": "basic",
  "api_plan": "basic",
  "api_subscription_status": "active",
  "subscription_status": "active",
  "monthly_requests": 128,
  "monthly_limit": 50000,
  "created_at": "2026-05-20T17:11:00+00:00"
}

GET /api/v1/customers/me/usage

Returns current API quota state.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/customers/me/usage

Response shape:

json
{
  "monthly_requests": 128,
  "monthly_limit": 50000,
  "requests_remaining": 49872,
  "tier": "basic",
  "api_plan": "basic",
  "api_subscription_status": "active",
  "subscription_status": "active",
  "reset_date": "2026-06-01T00:00:00+00:00"
}

GET /api/v1/customers/me/api-keys

Lists the current customer's API keys. Keys are masked in list responses.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/customers/me/api-keys

Response shape:

json
[
  {
    "api_key": "sk_alphapysports_abcd*****",
    "name": "Default Key",
    "tier": "basic",
    "created_at": "2026-05-20T17:11:00+00:00",
    "is_active": true,
    "expires_at": null
  }
]

POST /api/v1/customers/me/api-keys

Creates a new API key for the current customer.

bash
curl -X POST \
  -H "X-API-Key: $SFS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Terminal"}' \
  https://sports-api.scottfreellc.com/api/v1/customers/me/api-keys

Response shape:

json
{
  "api_key": "sk_alphapysports_new_key_value",
  "message": "API key created successfully",
  "warning": "Store this key securely - it cannot be retrieved again"
}

PATCH /api/v1/customers/me/api-keys/rename

Renames one of the current customer's API keys. You may pass the full key or the masked value returned by GET /api/v1/customers/me/api-keys.

bash
curl -X PATCH \
  -H "X-API-Key: $SFS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api_key_to_rename":"sk_alphapysports_abcd*****","new_name":"Production App"}' \
  https://sports-api.scottfreellc.com/api/v1/customers/me/api-keys/rename

Response shape:

json
{
  "message": "API key renamed successfully"
}

DELETE /api/v1/customers/me/api-keys/{api_key}

Revokes an API key. The API refuses to revoke the key currently being used for the request.

bash
curl -X DELETE \
  -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/customers/me/api-keys/sk_alphapysports_abcd*****

Response shape:

json
{
  "message": "API key revoked successfully"
}

Scottfree Sports Data

These endpoints support the separate Scottfree Sports Data subscription. Sports Data lets a customer refresh historical datasets they previously purchased from the shop. It does not by itself grant Basic/Premium API access to predictions, results, summary, CLI, or MCP.

GET /api/v1/scottfree-sports-data/status

Returns the caller's Sports Data entitlement state. This does not consume a refresh.

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/scottfree-sports-data/status

Response shape:

json
{
  "has_scottfree_sports_data": true,
  "expires_at": "2026-06-13T00:00:00+00:00",
  "owned_products": ["nfl_historical"],
  "owned_sports": ["nfl"],
  "refreshes_used": 1,
  "refreshes_remaining": 7,
  "refresh_limit": 8,
  "next_reset_at": "2026-06-01T00:00:00+00:00"
}

POST /api/v1/scottfree-sports-data/refresh

Generates signed download URLs for every refreshable historical dataset the customer owns. This consumes one of the customer's 8 monthly Sports Data refreshes only after all URLs are successfully generated.

bash
curl -X POST \
  -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/scottfree-sports-data/refresh

Response shape:

json
{
  "refreshes_remaining": 7,
  "next_reset_at": "2026-06-01T00:00:00+00:00",
  "downloads": [
    {
      "sport": "nfl",
      "filename": "nfl_game_scores_1g.csv",
      "url": "https://storage.googleapis.com/...",
      "expires_at": "2026-05-23T16:15:00+00:00"
    }
  ]
}

The signed URLs expire after 15 minutes.

Compatibility Pick Endpoints

These endpoints exist so older clients do not break, but no validated betting selector is active. They return explicit empty payloads.

GET /api/v1/picks/today

bash
curl -H "X-API-Key: $SFS_API_KEY" \
  https://sports-api.scottfreellc.com/api/v1/picks/today

Response:

json
{
  "date": "2026-05-23",
  "picks": [],
  "summary": {"total_picks": 0, "by_sport": {}},
  "note": "No validated betting selector is active."
}

GET /api/v1/picks/{date}

Same empty payload shape as /picks/today, for a supplied YYYY-MM-DD date.

GET /api/v1/picks/performance

Optional query parameters:

NameValues
sportMLB, NBA, NFL, NHL, NCAAF, NCAAB
marketspread, total, moneyline

Returns zeroed performance windows with the note No validated betting selector is active.

GET /api/v1/edge-picks

Public-compatible endpoint for edge-pick experiments. It currently returns an empty payload.

Optional query parameters:

NameDescription
sportAccepted for compatibility; ignored while no selector is active.

GET /api/v1/edge-picks/{date_str}

Same empty edge-picks payload for a supplied date.

GET /api/v1/edge-picks/track-record

Returns an empty track record while no selector is active.

Errors

The API error handler returns this shape:

json
{
  "error": "HTTP_401",
  "detail": "Invalid or expired API key",
  "timestamp": "2026-05-23T16:00:00.000000"
}

Common statuses:

StatusMeaning
400Invalid request or invalid parameter
401Missing, invalid, expired, or revoked API key
403Valid key, but the plan does not allow that operation
404Data artifact not available for that sport/model/date
429Per-second or monthly quota exceeded
500Server error
503Dependency temporarily unavailable

Sports model data and research tools