TradeAssist by Roster
Query Handler: GetTradeAssistByRosterQueryHandler
QueryType: GetTradeAssistByRoster
Endpoint: POST /api/readmodel
Authentication: Bearer JWT, requires Member role
Summary
Returns AI-powered trade recommendations 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 trades to maximise projected points.
Request
{
"QueryType": "GetTradeAssistByRoster",
"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
}
]
},
"SalaryLeft": 50000,
"TradesLeft": 5,
"NumbersOfTradesToSuggest": [1, 2, 3],
"FinalRound": 27
}
| Field |
Type |
Required |
Description |
Team |
SupercoachTeamContract |
Yes |
Full team contract (see below) |
SalaryLeft |
int |
Yes |
Remaining salary cap in dollars |
TradesLeft |
int |
Yes |
Number of trades remaining |
NumbersOfTradesToSuggest |
int[] |
No |
How many trades per scenario (default: [1, 2, 3]) |
FinalRound |
int |
No |
Final round of the season (default: 27) |
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 |
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
{
"Recommendations": {
"1": {
"PlayerOut": {
"PlayerId": "a1b2c3d4-...",
"TeamId": "e5f6a7b8-...",
"PlayerName": "John Smith",
"TeamName": "Broncos",
"TeamLogoUrl": "/e5f6a7b8-.../broncos.png",
"ParticipantLogoUrl": "/a1b2c3d4-.../john-smith.png",
"Position": ["HOK"],
"PositionLong": ["Hooker"],
"AssignedPosition": "HOK-1",
"SelectionStatus": "Selected",
"PositionSort": 7,
"CurrentPrice": 450000,
"ProjectedPoints": 45.2,
"ProjectedRating": 7.8,
"LiveScore": 55
},
"PlayerIn": {
"PlayerId": "d4c3b2a1-...",
"TeamId": "b8a7f6e5-...",
"PlayerName": "Jane Doe",
"TeamName": "Storm",
"TeamLogoUrl": "/b8a7f6e5-.../storm.png",
"ParticipantLogoUrl": "/d4c3b2a1-.../jane-doe.png",
"Position": ["HOK", "FRF"],
"PositionLong": ["Hooker", "Front Row Forward"],
"AssignedPosition": "HOK-1",
"SelectionStatus": "Selected",
"PositionSort": 7,
"CurrentPrice": 520000,
"ProjectedPoints": 52.8,
"ProjectedRating": 8.1,
"LiveScore": 62
}
}
}
}
Response Fields
| Field |
Type |
Description |
Recommendations |
Dictionary<int, Recommendation> |
Trade recommendations keyed by sequential index (1, 2, 3...) |
Recommendation
| Field |
Type |
Description |
PlayerOut |
EnrichedTradePlayer |
Player to trade out |
PlayerIn |
EnrichedTradePlayer |
Player to trade in (inherits AssignedPosition, SelectionStatus, PositionSort from PlayerOut) |
EnrichedTradePlayer
| Field |
Type |
Description |
PlayerId |
GUID |
SuperCoach player (participant) ID |
TeamId |
GUID |
Player's NRL team ID |
PlayerName |
string |
Player display name |
TeamName |
string |
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 (e.g., ["HOK"], ["2RF", "FRF"]) |
PositionLong |
string[] |
Full position names (e.g., ["Hooker"], ["Second Row Forward"]) |
AssignedPosition |
string |
Roster slot from the outgoing player (e.g., HOK-1, Bench-HOK-1) |
SelectionStatus |
string |
Selection status from the outgoing player |
PositionSort |
int |
Display sort order from the outgoing player |
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, salary, trades, and round info
- Call modelling API for trade recommendations
- Translate recommended FoxSports IDs back to internal ParticipantIds
- Enrich recommendations with player details (logos, positions, stats, projections)
- Copy roster slot fields (
AssignedPosition, SelectionStatus, PositionSort) from PlayerOut to PlayerIn
- Return enriched recommendations
Error Handling
| Scenario |
Behaviour |
| Empty or null roster |
Returns empty result set |
| Missing player stats |
Graceful fallback to "Unknown" values |
| Modelling API failure |
Propagates error to caller |