Skip to content

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

  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, salary, trades, and round info
  7. Call modelling API for trade recommendations
  8. Translate recommended FoxSports IDs back to internal ParticipantIds
  9. Enrich recommendations with player details (logos, positions, stats, projections)
  10. Copy roster slot fields (AssignedPosition, SelectionStatus, PositionSort) from PlayerOut to PlayerIn
  11. 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