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
- Validate authenticated user from JWT token
- Validate roster is not empty
- Translate internal player IDs to FoxSports IDs via AggregateRelations
- Determine current round from the NRL Premiership season using
Team.Season
- Fetch player stats for the last completed round
- Build modelling API input with FoxSports IDs and round info
- Call modelling API for optimised positions
- If optimisation succeeds, apply optimised positions back to the roster with validation
- If optimisation fails (
OptimiserSuccess = false), fall back to the original roster
- Enrich roster with logos, projected points/rating, and current round score from player stats
- Build response from team contract with enriched roster applied
- 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 |