Skip to content

Optimise Lineup by Roster

Query Handler: GetOptimiseLineupByRosterQueryHandler QueryType: GetOptimiseLineupByRoster Endpoint: POST /api/readmodel Authentication: Bearer JWT, requires Member role


Summary

Returns an optimised lineup for a team provided directly in the request. Use this when you have the team data in memory and don't need to load a saved team from the database. The modelling API determines the best player positions and selection statuses to maximise projected points.


Request

{
  "QueryType": "GetOptimiseLineupByRoster",
  "Team": {
    "Id": "123e4567-e89b-12d3-a456-426614174000",
    "BallrUserId": "a1b2c3d4-...",
    "SupercoachUserId": 12345,
    "SupercoachTeamExternalId": 67890,
    "Sport": "RugbyLeague",
    "Season": 2026,
    "GameType": "classic",
    "TeamName": "My SuperCoach Team",
    "CurrentRound": 10,
    "TeamRating": 85.5,
    "TeamRatingRound": 9,
    "Roster": [
      {
        "PlayerId": "a1b2c3d4-...",
        "TeamId": "e5f6a7b8-...",
        "PlayerName": "John Smith",
        "TeamName": "Broncos",
        "Position": ["HOK"],
        "PositionLong": ["Hooker"],
        "AssignedPosition": "HOK-1",
        "SelectionStatus": "Selected",
        "PositionSort": 1,
        "CurrentPrice": 450000,
        "ProjectedPoints": 45.2
      }
    ]
  }
}
Field Type Required Description
Team SupercoachTeamContract Yes Full team contract (see below)

SupercoachTeamContract

Field Type Required Description
Id GUID No SuperCoach team ID
BallrUserId GUID No Ballr user ID who owns this team
SupercoachUserId long No External SuperCoach user ID
SupercoachTeamExternalId long No External SuperCoach team ID
Sport string No Sport code (e.g., "RugbyLeague")
Season int Yes Season year (e.g., 2026) — used to determine current round
GameType string No Game type: classic, draft, or finals
TeamName string No Team display name
CurrentRound int No Current round number
TeamRating decimal? No Latest team rating value
TeamRatingRound int? No Round number for team rating
Roster RosterPlayer[] Yes Full roster of players (see below)

Roster Player

Field Type Required Description
PlayerId GUID Yes SuperCoach player (participant) ID
TeamId GUID No Player's NRL team ID
PlayerName string No Player display name
TeamName string No Player's NRL team name
Position string[] No Position codes player is eligible for
PositionLong string[] No Full position names
AssignedPosition string No Current roster slot (e.g., HOK-1, Bench-HOK-1)
SelectionStatus string No Selection status (see below)
PositionSort int No Display sort order
CurrentPrice int No Current SuperCoach salary price
ProjectedPoints decimal No Projected fantasy points
ProjectedRating decimal No Projected player rating

Position Codes

Code Full Name
FLB Fullback
CTW Centre/Wing
5/8 Five-Eighth
HFB Halfback
2RF Second Row Forward
FRF Front Row Forward
HOK Hooker
INT Interchange/Flex

Selection Statuses

Status Description
Selected Player is selected to play (on field)
Bench Player is on the bench
capt Team captain (earns double points)
vice Vice-captain (earns double if captain doesn't play)
reserve Reserve player (auto-sub eligible)
emerg Emergency player (auto-sub eligible)

Response

Returns a SupercoachTeamResponse with the optimised roster positions applied. Team metadata is passed through from the request; the roster reflects the optimised positions.

{
  "Id": "123e4567-...",
  "BallrUserId": "a1b2c3d4-...",
  "SupercoachUserId": 12345,
  "SupercoachTeamExternalId": 67890,
  "Sport": "RugbyLeague",
  "Season": 2026,
  "GameType": "classic",
  "TeamName": "My SuperCoach Team",
  "CurrentRound": 10,
  "Roster": [
    {
      "PlayerId": "a1b2c3d4-...",
      "TeamId": "e5f6a7b8-...",
      "PlayerName": "John Smith",
      "TeamName": "Broncos",
      "Position": ["HOK"],
      "PositionLong": ["Hooker"],
      "AssignedPosition": "HOK-1",
      "SelectionStatus": "Selected",
      "PositionSort": 1,
      "CurrentPrice": 450000,
      "ProjectedPoints": 45.2,
      "ProjectedRating": 7.8,
      "LiveScore": 55
    }
  ],
  "TeamRating": 85.5,
  "TeamRatingRound": 9,
  "CreatedAt": "2026-03-27T12:00:00+00:00",
  "LastUpdatedAt": "2026-03-27T12:00:00+00:00",
  "Version": 42
}

Response Fields

Field Type Description
Id GUID SuperCoach team ID (from request)
BallrUserId GUID Owning Ballr user ID (from request)
SupercoachUserId long External SuperCoach user ID (from request)
SupercoachTeamExternalId long External SuperCoach team ID (from request)
Sport string Sport code (from request)
Season int Season year (from request)
GameType string Game type (from request)
TeamName string Team name (from request)
CurrentRound int Current round determined from Foundry DB
Roster RosterPlayerResponse[] Roster with optimised positions applied
TeamRating decimal? Team rating (from request)
TeamRatingRound int? Team rating round (from request)
CreatedAt DateTimeOffset Timestamp (from request)
LastUpdatedAt DateTimeOffset Timestamp (from request)
Version long Event version (from request)

Roster Player Response

Field Type Description
PlayerId GUID SuperCoach player (participant) ID
TeamId GUID Player's NRL team ID
PlayerName string Player display name
TeamName string Player's NRL team name
TeamLogoUrl string? URL for team logo (enriched from player stats)
ParticipantLogoUrl string? URL for participant logo (enriched from player stats)
Position string[] Position codes
PositionLong string[] Full position names
AssignedPosition string Optimised roster slot
SelectionStatus string Optimised selection status
PositionSort int Display sort order
CurrentPrice int Current SuperCoach salary price
ProjectedPoints decimal? Projected fantasy points (enriched from player stats)
ProjectedRating decimal? Projected player rating (enriched from player stats)
LiveScore int? Current round fantasy score (enriched from player stats)

How It Works

  1. Validate authenticated user from JWT token
  2. Validate roster is not empty
  3. Translate internal player IDs to FoxSports IDs via AggregateRelations
  4. Determine current round from the NRL Premiership season using Team.Season
  5. Fetch player stats for the last completed round
  6. Build modelling API input with FoxSports IDs and round info
  7. Call modelling API for optimised positions
  8. If optimisation succeeds, apply optimised positions back to the roster with validation
  9. If optimisation fails (OptimiserSuccess = false), fall back to the original roster
  10. Enrich roster with logos, projected points/rating, and current round score from player stats
  11. Build response from team contract with enriched roster applied
  12. Return response

Error Handling

Scenario Behaviour
Empty or null roster Returns empty result set
Optimisation fails Falls back to original roster positions
Modelling API failure Propagates error to caller