IodidDOCUMENTATION

index.mdx

/doc

PUBLIC DOCUMENTATION

Iodid

Open platform for League of Legends data — profile, MMR, leaderboards, records, tier lists and OTP.

Normalized LoL data, ready for dashboards, bots and research.

Iodid transforms raw Riot APIs into stable canonical models (SummonerView, Match, LeaderboardPage, ChampionTierList) with read-through caching and async update queues. No scraping, no duplicate DTOs, a single source of truth in Mongo.

bash
# Quick start — search by Riot ID across all shards
curl "https://api.safjnest.com/api/lol/search?q=Player%23EUW"

# Profile by puuid (ready or 202 pending)
curl "https://api.safjnest.com/api/lol/EUW1/profile/abc123-puuid"

# Paginated leaderboard
curl "https://api.safjnest.com/api/lol/EUW1/leaderboard?queue=RANKED_SOLO_5X5&page=1&limit=20"

BaseUrl: https://api.safjnest.com/api/lol — platform-scoped routes use /{shard}; search uses /search globally or ?shard=<shard> to limit results (src/main/java/com/safjnest/spring/controller/LolController.java:36). No auth.

Why Iodid

  • Canonical — Summoner as single identity (src/main/java/com/safjnest/lol/model/summoner/Summoner.java:18), Rank for ranked, complete Match/Participant.
  • Consistent — centralized validation LolApiParameters (src/main/java/com/safjnest/spring/controller/LolApiParameters.java:27), uniform error envelope LolApiError (src/main/java/com/safjnest/spring/dto/LolApiError.java:5).
  • Async yet transparent — ApiResult with states READY/PARTIAL/PENDING/NOT_FOUND (src/main/java/com/safjnest/lol/model/ApiResult.java:9), mapped to 200/202/404 by LolApiResponses (src/main/java/com/safjnest/spring/controller/LolApiResponses.java:14).
  • Performant — Mongo as sole runtime store, Redis cache only (src/main/java/com/safjnest/lol/service/MatchService.java:68).

Features

MMR — transparent estimate

Conversion TierDivisionType + LP to MMR score via TierDivisionUtils.getMmr (src/main/java/com/safjnest/lol/utils/TierDivisionUtils.java:78). Tier ranges with getMmrRange (src/main/java/com/safjnest/lol/utils/TierDivisionUtils.java:119), profile average with getAverageRank (src/main/java/com/safjnest/lol/utils/TierDivisionUtils.java:49). Leaderboard distribution available on LeaderboardDistribution.

Leaderboard — paginated and filtered

LeaderboardService with filters rank, queue, region, role, otpChampion validated in LolApiParameters (src/main/java/com/safjnest/spring/controller/LeaderboardController.java:34). Pagination page/limit (LolApiParameters.page :198, limit :203), limits 1..50. Each entry wraps SummonerView with position.

Records — global and per-profile

RecordsOverview and ProfileRecordPage via ProfileRecordService (src/main/java/com/safjnest/lol/service/ProfileRecordService.java). Required metric RecordMetric (LolApiParameters.recordMetric :193). Canonical filter Filter.canonical() (src/main/java/com/safjnest/lol/model/Filter.java:44) for seasonal aggregations.

Tier List — per patch and queue

ChampionTierList generated by ChampionService (src/main/java/com/safjnest/lol/service/ChampionService.java). Parameters patch (LolApiParameters.patch :103), rank, region, queue. Patch validated as major.minor and normalized via PatchUtils.patchMajor (src/main/java/com/safjnest/lol/utils/PatchUtils.java:53).

OTP — one-trick pony

otp filter as champion ID >0 (LolApiParameters.otpChampion :183) on leaderboards and champion statistics. Identification via ChampionUtils (src/main/java/com/safjnest/lol/utils/ChampionUtils.java:31).

Next steps

  • Read getting-started.mdx for baseUrl, validation, error envelope and pagination.
  • Check concepts.mdx for puuid, riotId, shard vs RegionShard, Filter and staleness.
  • Dive into runtime in architecture.mdx (Mongo, Redis, schedulers).
  • Verify stack and licenses in libraries.mdx (pom.xml:15).
js
// JS example — fetch profile handling 202
const res = await fetch("https://api.safjnest.com/api/lol/EUW1/profile/abc-puuid");
if (res.status === 202) {
  const { code, message, metadata } = await res.json();
  console.log("pending:", code, metadata);
} else if (res.ok) {
  const view = await res.json();
  console.log(view.summoner.riotId, view.ranks);
}