get api key →

Predictions

Win-probability and margin predictions for AFL fixtures, computed by an Elo rating model trained on the last five seasons of results, with situational adjustments (home ground, recent scoring form, venue record, interstate travel). The model is independent of the Squiggle tipster panel — squiggleConsensus is stored alongside each prediction purely as a benchmark. Predictions are versioned — model_version tags each row so historical predictions are preserved when the algorithm changes; the current model is v2, and rows tagged v1 carry the legacy factor-score payloads instead of the shapes below. Probabilities are floats (72.5 = 72.5%); margins are points, positive toward the home side.

GET /predictions

Returns predictions ordered by year desc, round desc, then chronologically by match start time within each round. Filter by round, team, or settlement status.

Query Parameters

NameTypeRequiredDescription
yearintegerNoFilter by season year
roundintegerNoFilter by round
fixture_idintegerNoFilter by Squiggle fixture ID
team_idstringNoPredictions involving this team (home or away)
model_versionstringNoAlgorithm version, e.g. v2
settledbooleanNotrue = outcome known, false = pending
limitintegerNoDefault 50, max 200
offsetintegerNoDefault 0

Examples

# Predictions for round 9, 2026
GET /predictions?year=2026&round=9

# All settled predictions for a team
GET /predictions?team_id=sydney&settled=true

Response

{
  "data": [
    {
      "id": 214, "fixtureId": 38566, "year": 2026, "round": 9,
      "homeTeamId": "fremantle", "homeTeam": "Fremantle", "homeShortName": "FRE",
      "awayTeamId": "hawthorn", "awayTeam": "Hawthorn", "awayShortName": "HAW",
      "venue": "Optus Stadium", "date": "2026-05-09 19:40:00",
      "homeProbability": 58.3, "awayProbability": 41.7,
      "predictedMargin": 5,
      "squiggleConsensus": 61,
      "factors": {
        "totalEdge": 33.9,
        "contributions": [
          { "key": "rating", "label": "rating edge", "value": 11.2 },
          { "key": "homeGround", "label": "home ground advantage", "value": 38 },
          { "key": "form", "label": "recent scoring form", "value": -6.4 },
          { "key": "venueRecord", "label": "venue record", "value": 4.1 },
          { "key": "travel", "label": "travel (Hawthorn interstate)", "value": 40 },
          { "key": "rest", "label": "rest (7 vs 8 days)", "value": 0 },
          { "key": "h2h", "label": "head-to-head (last 6)", "value": 0 }
        ],
        "h2h": { "homeWins": 3, "awayWins": 3, "draws": 0 }
      },
      "homeBreakdown": {
        "elo": 1541, "eloHistory": [1512, 1528, 1541],
        "form": ["W", "W", "L", "W", "L"],
        "attack": 88.4, "defence": 82.1,
        "venueRecord": { "wins": 9, "played": 12 }, "restDays": 7
      },
      "awayBreakdown": { "...same shape for the away side...": "" },
      "modelVersion": "v2",
      "actualWinner": null, "actualMargin": null,
      "computedAt": "2026-05-06T08:00:00.000Z", "settledAt": null
    }
  ],
  "meta": { "limit": 50, "offset": 0, "count": 9, "total": 9 }
}

factors.contributions values are rating points, positive toward the home side; they sum to totalEdge, which converts to the probability via P(home) = 1 / (1 + 10^(-edge/400)). Once a game completes, actualWinner and actualMargin (home-positive points) are populated.

GET /predictions/:id

Returns a single prediction by numeric ID. Response is the same shape wrapped in { "data": { ... } }.