IodidDOCUMENTATION

reference/dtos.mdx

/doc/reference/dtos

PUBLIC DOCUMENTATION

Reference — DTOs

All canonical DTOs — SummonerView, Summoner, Rank, Mastery, Match, Participant, RankProgress, MatchResult, MatchPage, RankHistory, LiveGame, ProfileActivity, ProfileMatchups, ProfileStatistics, LeaderboardPage, SummonerLeaderboard, ProfileRecord, ChampionView, ChampionStatistics, Build and ResponseMetadata.

All DTOs are in com.safjnest.lol.model — no second Spring DTO, controllers return canonical models directly (ADR). Only LolApiError is a Spring DTO.

SummonerView — complete profile

SummonerView (src/main/java/com/safjnest/lol/model/summoner/SummonerView.java:13):

java
public record SummonerView(
    Summoner summoner,
    Map<GameQueueType, Rank> ranks,
    SummonerOverview overview,
    @JsonInclude(NON_NULL) ResponseMetadata metadata
) {}
json
{
  "summoner": { "puuid": "abc", "riotId": "Faker#KR1", "region": "KR", "level": 512, "icon": 4567 },
  "ranks": {
    "RANKED_SOLO_5X5": { "tier": "CHALLENGER_I", "lp": 1280, "wins": 342, "losses": 298, "globalRanking": 42, "regionRanking": 5 },
    "RANKED_FLEX_SR": { "tier": "MASTER_I", "lp": 45, "wins": 12, "losses": 8 }
  },
  "overview": {
    "statistics": { "games": 320, "wins": 180, "losses": 140, "winrate": 0.562, "kda": 3.2, "csPerMinute": 7.1 },
    "masteries": [{ "championId": 157, "level": 7, "points": 1234567 }],
    "champions": { "157": { "games": 80, "wins": 45, "kda": 4.1 } }
  },
  "metadata": { "lastUpdate": 1715434800000, "refresh": false }
}

Summoner

Summoner (src/main/java/com/safjnest/lol/model/summoner/Summoner.java:18):

java
public class Summoner extends AbstractEntity<Summoner> {
    @JsonProperty("puuid") String puuid; // PK, _id
    @JsonProperty("riotId") String riotId; // "gameName#tagLine", String not a record
    @JsonProperty("region") LeagueShard region;
    @JsonProperty("level") int level;
    @JsonProperty("icon") int icon;
    @JsonIgnore String userId; @JsonIgnore boolean tracking;
    @JsonIgnore Map<GameQueueType, Rank> ranks; @JsonIgnore List<Mastery> masteries;
    protected String collectionName() { return "summoner"; } // :180
    protected String entityId() { return puuid; } // :185
}

riotId stays String — name()/tag() do split("#",2) (:171).

Rank

Rank (src/main/java/com/safjnest/lol/model/summoner/Rank.java:6):

java
@JsonInclude(NON_NULL)
public record Rank(TierDivisionType tier, int lp, int wins, int losses, Long globalRanking, Long regionRanking) {
    public Rank { tier = tier == null ? TierDivisionType.UNRANKED : tier; }
    public int games() { return wins+losses; }
    public double winrate() { return games()==0?0: (double)wins*100/games(); }
}
json
{ "tier": "CHALLENGER_I", "lp": 1280, "wins": 342, "losses": 298, "globalRanking": 42, "regionRanking": 5 }

CHALLENGER_I etc are TierDivisionType (41 values). UNRANKED → lp=0.

Mastery

Mastery (src/main/java/com/safjnest/lol/model/summoner/Mastery.java:5):

java
public record Mastery(int championId, int level, int points) {}
json
{ "championId": 157, "level": 7, "points": 1234567 }

SummonerOverview

SummonerOverview (src/main/java/com/safjnest/lol/model/summoner/SummonerOverview.java):

java
public record SummonerOverview(ProfileStatistics statistics, List<Mastery> masteries, Map<Integer, Champion> champions) {
    public record Champion(String name, String image) {}
}

Match — complete

Match (src/main/java/com/safjnest/lol/model/match/Match.java:24) — extends AbstractEntity:

java
public class Match extends AbstractEntity<Match> {
    public int id; public String gameId; public LeagueShard leagueShard; public GameQueueType queue; public TierType rank;
    public long lastUpdate; public ResponseMetadata metadata; public Map<TeamType, List<Integer>> bans;
    @JsonIgnore JSONObject events; @JsonProperty("events") Map<String,Object> eventData;
    public long timeStart; public long timeEnd; public String patch; public List<Participant> participants;
    protected String collectionName() { return "match"; } // :133
    protected String entityId() { return gameId; } // :138
}
json
{
  "gameId": "EUW1_1234567890",
  "leagueShard": "EUW1",
  "queue": "RANKED_SOLO_5X5",
  "rank": "EMERALD",
  "timeStart": 1715000000000,
  "timeEnd": 1715001800000,
  "patch": "15.6.1",
  "lastUpdate": 1715434800000,
  "bans": { "BLUE": [157, 64], "RED": [238, 122] },
  "participants": [{ "puuid": "abc", "champion": 157, "lane": "MID", "team": "BLUE", "win": true, "kda": "8/2/6", "rankProgress": { "rank": "EMERALD_I", "lp": 45, "gain": 18 } }],
  "events": { "events": [] },
  "metadata": { "lastUpdate": 1715434800000 }
}

Participant

Participant (src/main/java/com/safjnest/lol/model/match/Participant.java:8):

java
public class Participant {
    public int id; public int summonerId; public int matchId; public boolean win; public String kda;
    public int kills, deaths, assists; public int champion; public LaneType lane; public TeamType team;
    public RankProgress rankProgress; public int damage, damageTaken, damageBuilding, healing, cs, goldEarned, visionScore;
    public int doubles, triples, quadruples, pentas; public int item0..item6, turretKills;
    public List<Integer> primaryRunes, secondaryRunes, statsRunes, skillOrder, augments, starterItems, buildPath;
    public int boots, supportItem; public String puuid, riotId, riotTag;
}

Key fields: champion (int ID), lane (5 playables), win, kda (String "K/D/A"), rankProgress, cs, goldEarned, visionScore, damage, starterItems/boots/supportItem/item0..5/skillOrder/augments/primaryRunes/secondaryRunes.

RankProgress

RankProgress (src/main/java/com/safjnest/lol/model/match/RankProgress.java:5):

java
public final class RankProgress {
    public TierDivisionType rank; public Integer lp; public Integer gain;
    public TierDivisionType previousRank; public Integer previousLp;
}
json
{ "rank": "EMERALD_I", "lp": 45, "gain": 18, "previousRank": "EMERALD_I", "previousLp": 27 }

gain may be null (OP.GG best-effort source, never full history then).

MatchResult — lightweight projection

MatchResult (src/main/java/com/safjnest/lol/model/match/MatchResult.java:11):

java
public class MatchResult {
    public final String gameId; public final GameQueueType queue; public final long timeStart, timeEnd;
    public final boolean win; public final String kda; public final int championId; public final LaneType lane;
    public final int damage, cs, gold, vision, teamKills;
    public final List<Integer> items, summonerSpells, primaryRunes, secondaryRunes, statsRunes;
    public final List<Participant> participants;
}

Used in MatchPage. Truncated: only championId, win, kda essentials, not full Participant with rankProgress.

json
{ "gameId": "EUW1_123", "queue": "RANKED_SOLO_5X5", "timeStart": 1715000000000, "win": true, "championId": 157, "lane": "MID", "kda": "8/2/6", "cs": 245, "damage": 28000, "gold": 14200, "vision": 23, "items": [6672,3031], "participants": [{ "...": "..." }] }

MatchPage

MatchPage (src/main/java/com/safjnest/lol/model/match/MatchPage.java):

java
public record MatchPage(List<MatchResult> matches, int limit, int offset, long total, boolean hasMore, ResponseMetadata metadata) {
    public MatchPage withMetadata(ResponseMetadata value) { return new MatchPage(matches, limit, offset, total, hasMore, value); }
}

total = MongoDB.countMatches, hasMore = offset+matches.size() < total.

json
{ "matches": [{ "...": "..." }], "limit": 20, "offset": 0, "total": 320, "hasMore": true, "metadata": { "pagination": { "limit": 20, "offset": 0, "total": 320, "hasMore": true } } }

RankHistory

RankHistory (src/main/java/com/safjnest/lol/model/match/RankHistory.java):

java
public record RankHistory(List<RankHistoryMatch> matches, RankHistoryMetadata metadata) {}
public record RankHistoryMatch(String gameId, long timeStart, GameQueueType queue, RankProgress rankProgress) {
    public static RankHistoryMatch from(Match match, String puuid) { ... }
}
public record RankHistoryMetadata(long start, long end, int total) {}
public record RankHistoryQuery(GameQueueType queue, RankHistoryView view, Integer season, String patch, long timeStart, long timeEnd, MatchOrder order) {}
public enum RankHistoryView { profile }
public enum MatchOrder { ASC, DESC }
json
{
  "matches": [{ "gameId": "EUW1_123", "timeStart": 1715000000000, "queue": "RANKED_SOLO_5X5", "rankProgress": { "rank": "DIAMOND_II", "lp": 67, "gain": 22, "previousRank": "DIAMOND_II", "previousLp": 45 } }],
  "metadata": { "start": 1700000000000, "end": 1716000000000, "total": 45 }
}

LiveGame

LiveGame (src/main/java/com/safjnest/lol/model/match/LiveGame.java):

java
public record LiveGame(long gameId, GameQueueType queue, long gameStartTime, List<LiveParticipant> participants) {
    public record LiveParticipant(String puuid, String riotId, int championId, LaneType lane, TeamType team) {}
}
json
{ "gameId": 1234567890, "queue": "RANKED_SOLO_5X5", "gameStartTime": 1715434800000, "participants": [{ "puuid": "abc", "riotId": "Faker#KR1", "championId": 157, "lane": "MID", "team": "BLUE" }] }

ProfileActivity

ProfileActivity (src/main/java/com/safjnest/lol/model/statistics/ProfileActivity.java):

java
public class ProfileActivity {
    public Filter filter; public Overview overview; public List<ChampionActivity> champions; public List<LaneActivity> lanes; public ResponseMetadata metadata;
    public record Overview(int games, int wins, double winrate, double kda) {}
    public record ChampionActivity(int champion, int games, int wins, double winrate, double kda) {}
    public record LaneActivity(LaneType lane, int games, int wins, double winrate) {}
}
json
{
  "filter": { "champion": 157, "queue": "RANKED_SOLO_5X5", "timeStart": 0, "timeEnd": 0 },
  "overview": { "games": 120, "wins": 68, "winrate": 0.566, "kda": 3.1 },
  "champions": [{ "champion": 157, "games": 40, "wins": 24, "winrate": 0.6, "kda": 3.5 }],
  "lanes": [{ "lane": "MID", "games": 80, "wins": 45, "winrate": 0.562 }],
  "metadata": { "lastUpdate": 1715434800000 }
}

ProfileMatchups

ProfileMatchups (src/main/java/com/safjnest/lol/model/statistics/ProfileMatchups.java):

java
public class ProfileMatchups {
    public Filter filter; public Map<Integer, List<MatchupLeaf>> matchups; public ResponseMetadata metadata;
    public record MatchupLeaf(int opponent, int games, int wins, int losses, double winrate) {}
}
json
{
  "filter": { "queue": "RANKED_SOLO_5X5", "lane": "MID", "minGames": 5 },
  "matchups": {
    "238": [{ "opponent": 238, "games": 12, "wins": 5, "losses": 7, "winrate": 0.416 }],
    "64": [{ "opponent": 64, "games": 8, "wins": 6, "winrate": 0.75 }]
  },
  "metadata": { "lastUpdate": 1715434800000 }
}

ProfileStatistics

ProfileStatistics (src/main/java/com/safjnest/lol/model/statistics/ProfileStatistics.java):

java
public class ProfileStatistics {
    public Filter filter; public Overview overview; public List<ProfileStatisticsRow> rows; public ResponseMetadata metadata;
    public static boolean matchesFilter(Match match, String puuid, Filter filter) { ... }
    public record Overview(int games, int wins, double winrate) {}
}
public record ProfileStatisticsRow(int champion, LaneType lane, int games, int wins, double winrate, double kda) {}

LeaderboardPage / SummonerLeaderboard

LeaderboardPage (src/main/java/com/safjnest/lol/model/leaderboard/LeaderboardPage.java:7):

java
public record LeaderboardPage(int page, int pageSize, long total, long pages, List<SummonerLeaderboard> summoners, ResponseMetadata metadata) {}

SummonerLeaderboard (src/main/java/com/safjnest/lol/model/summoner/SummonerLeaderboard.java:5):

java
public record SummonerLeaderboard(long position, SummonerView summoner) {}
json
{ "page": 1, "pageSize": 20, "total": 15420, "pages": 771, "summoners": [{ "position": 1, "summoner": { "summoner": { "puuid": "abc", "riotId": "Player#EUW" }, "ranks": { "...": "..." } } }], "metadata": { "pagination": { "page": 1, "pageSize": 20, "total": 15420, "pages": 771 } } }

ProfileRecord

ProfileRecord (src/main/java/com/safjnest/lol/model/record/ProfileRecord.java):

java
public record ProfileRecord(String puuid, String riotId, LeagueShard region, int champion, GameQueueType queue, long timeStart, String gameId, Object metricValue, ResponseMetadata metadata) {}

RecordPage (:RecordPage.java): metric, records, limit, offset, total, hasMore, metadata. RecordsOverview: Map<RecordMetric, List<ProfileRecord>>.

ChampionView / ChampionStatistics / Build

ChampionView (src/main/java/com/safjnest/lol/model/ChampionView.java:5):

java
public record ChampionView(Champion champion, ChampionStatistics stats, Build build, ResponseMetadata metadata) {
    public record Champion(int id, String name, String image) {}
}

ChampionStatistics (src/main/java/com/safjnest/lol/model/ChampionStatistics.java:11):

java
public record ChampionStatistics(Filter filter, Overview overview, List<LaneStat> laneStats, Map<Integer, Matchup> matchups, List<LaneSynergy> laneSynergies, List<PowerCurvePoint> powerCurve, Trend trend) {
    public record Overview(int games, int picks, int bans, int wins, double winrate, double pickrate, Double banrate, Double kda, Double csPerMinute, Double goldPerMinute, DamageProfile damageProfile) {}
    public record LaneStat(LaneType lane, int games, double winrate) {}
    public record Matchup(int matches, int wins, double winrate, Double deltaWinrate, Integer goldDiffAt15, Double csDiffAt15, Double soloKillRate, Double killParticipation, Double opponentBanRate, Integer metricGames) {}
    public record LaneSynergy(int allyChampion, LaneType allyLane, int matches, int wins, double winrate, double pickrate) {}
    public record PowerCurvePoint(String durationBucket, int games, int wins, double winrate) {}
    public record Trend(String previousPatch, Integer games, Double winrate, Double deltaWinrate) {}
}

Build (src/main/java/com/safjnest/lol/model/Build.java): starter, boots, supportItem, build (List<Integer> 6), skillOrder, augments, summonerSpells, runes (primary/secondary/stats).

ChampionTierList (src/main/java/com/safjnest/lol/model/ChampionTierList.java:11): List<Role> roles with Role(LaneType role, List<Champion> champions) and Champion with tier, tierScore, stats, counters, strongAgainst.

All with ResponseMetadata metadata and withMetadata.

ResponseMetadata

ResponseMetadata (src/main/java/com/safjnest/lol/model/ResponseMetadata.java:3):

java
public record ResponseMetadata(Pagination pagination, Long lastUpdate, Boolean refresh, Filter filter) {
    public record Pagination(Integer page, Integer pageSize, Integer limit, Integer offset, Long total, Long pages, Boolean hasMore) {}
    public static ResponseMetadata of(long lastUpdate, boolean refresh, Filter filter) { return new ResponseMetadata(null, lastUpdate>0?lastUpdate:null, refresh, filter); }
    public static ResponseMetadata ready(Long lastUpdate, Filter filter) { return of(lastUpdate==null?0:lastUpdate, false, filter); }
    public static ResponseMetadata pending(Long lastUpdate, Filter filter) { return of(lastUpdate==null?0:lastUpdate, true, filter); }
}

Included in every response with computed data; pagination populated only for LeaderboardPage/MatchPage/RecordPage.

Common notes

  • All lists are List.copyOf immutable.
  • Filter in ChampionStatistics/Build is @JsonIgnoreProperties("filter") via LolApiConfig.FilterApiMixin (src/main/java/com/safjnest/spring/config/LolApiConfig.java:30).
  • SummonerView.metadata is @JsonInclude(NON_NULL).