Kindred
Kindred is a Node.js wrapper with built-in rate-limiting (enforced per region), caching (Redis), and parameter checking on top of Riot's League of Legends API.
Table of Contents
Core Features
- All standard endpoints covered but one (get summoner by accountIDs).
- Supports both callbacks and promises.
- Rate limiter that is enforced per region.
- Retries on 429 and >= 500.
- Promise-based requests retry up to three times.
- Built-in parameter checks so you can hopefully refer to documentation less! :)
- Built-in, flexible caching (in-memory and Redis).
- Customized expiration timers. You can set a timer for each endpoint type. Refer to Caching for more info.
- Designed to be simple but convenient. For example, you can call an exclusively by-id endpoint (such as grabbing the runes of a player) with just the name.
Philosophy
My goal is to make a wrapper that is simple, sensible, and consistent. This project is heavily inspired by psuedonym117's Python wrapper. Look at the Quickstart Section to see what I mean.
Installation
yarn add kindred-api
// or npm install kindred-api
Endpoints Covered
All examples here should be able to be run alone individually.
Make sure to check the official Riot Documentation to see what query parameters you can pass in to each endpoint (through the options parameter)!
Note: All region
parameters are OPTIONAL. All options
parameters are OPTIONAL unless stated otherwise.
Champion Mastery
docs
- /lol/champion-mastery/v3/champion-masteries/by-summoner/{summonerId}
- Get all champion mastery entries sorted by number of champion points descending. (RPC)
- getChampMasteries({ region = this.defaultRegion, id/summonerID/playerID (int), name (string), options (object) }, cb)
- Namespaced Functions: ChampionMastery.getChampionMasteries, ChampionMastery.getAll, ChampionMastery.all
- Example 1:
k.ChampionMastery.all({ id: 20026563 }, KindredAPI.print)
- Example 2:
k.ChampionMastery.all({ id: 20026563 }).then(data => console.log(data))
- /lol/champion-mastery/v3/champion-masteries/by-summoner/{summonerId}/by-champion/{championId}
- Get a champion mastery by player id and champion id.(RPC)
- getChampMastery({ region = this.defaultRegion, playerID (int), championID (int), options (object) }, cb)
- Namespaced Functions: ChampionMastery.getChampionMastery, ChampionMastery.get
- Example 1:
k.ChampionMastery.get({ playerID: 20026563, championID: 203 }, KindredAPI.print)
- Example 2:
k.ChampionMastery.get({ playerID: 20026563, championID: 203 }).then(data => console.log(data))
- /lol/champion-mastery/v3/scores/by-summoner/{summonerId}
- Get a player's total champion mastery score, which is sum of individual champion mastery levels (RPC)
- getTotalChampMasteryScore({ region = this.defaultRegion, id/summonerID/playerID (int), name (string), options (object) }, cb)
- Namespaced Functions: ChampionMastery.getTotalChampMasteryScore, ChampionMastery.getTotalScore, ChampionMastery.totalScore, ChampionMastery.total, ChampionMastery.score
- Example 1:
k.ChampionMastery.score({ id: 20026563 }, KindredAPI.print)
Champion
docs
- /lol/platform/v3/champions
- Retrieve all champions.
- getChamps({ region, id (int), options (object) }, cb)
- Namespaced Functions: Champion.getChampions, Champion.getAll, Champion.all
- Example 1:
k.Champion.all({ region: REGIONS.KOREA }, KindredAPI.print)
- /lol/platform/v3/champions/{id}
- Retrieve champion by ID.
- getChamp({ region, id/championID (int) }, cb)
- Namespaced Functions: Champion.getChampion, Champion.get
- Example 1:
k.Champion.get({ championID: 67 }, KindredAPI.print)
- Example 2:
k.Champion.get({ championID: 67 }).then(data => console.log(data))
- Example 3:
k.Champion.get({ championID: 67, region: 'kr' }, KindredAPI.print)
Game
docs
- /api/lol/{region}/v1.3/game/by-summoner/{summonerId}/recent
- Get recent games by summoner ID. (REST)
- getRecentGames({ region, id (int), name (str) }, cb)
- Namespaced Functions: Game.getRecentGames, Game.getRecent, Game.get
- Example 1:
k.Game.get({ summonerID: 20026563 }, KindredAPI.print)
League
docs
- /api/lol/{region}/v2.5/league/by-summoner/{summonerIds}
- Get leagues mapped by summoner ID for a given list of summoner IDs. (REST)
- getLeagues({ region, id/summonerID/player/ID (int), name (str) }, cb)
- Namespaced Functions: League.getLeagues, League.get
- Example 1:
k.League.getLeagues({ summonerID: 20026563 }, KindredAPI.print)
- Example 2:
k.League.get({ summonerID: 20026563 }, KindredAPI.print)
- /api/lol/{region}/v2.5/league/by-summoner/{summonerIds}/entry
- Get league entries mapped by summoner ID for a given list of summoner IDs. (REST)
- getLeagueEntries({ region, id/summonerID/playerID (int), name (str) }, cb)
- Namespaced Functions: League.getLeagueEntries, League.getEntries, League.entries
- Example 1:
k.League.entries({ summonerID: 20026563 }, KindredAPI.print)
- /api/lol/{region}/v2.5/league/challenger
- Get challenger tier leagues. (REST)
- getChallengers({ region, options: { type: 'RANKED_SOLO_5x5' } }, cb)
- Namespaced Functions: League.getChallengers, League.challengers
- Example 1:
k.League.challengers(KindredAPI.print)
- Example 2:
k.League.challengers({ region: 'na' }, KindredAPI.print)
- Example 3:
k.League.challengers({ options: { type: 'RANKED_FLEX_SR' } }, KindredAPI.print)
- /api/lol/{region}/v2.5/league/master
- Get master tier leagues. (REST)
- getMasters({ region, options: { type: 'RANKED_SOLO_5x5' } }, cb)
- Namespaced Functions: League.getMasters, League.masters
- Example 1:
k.League.masters().then(data => console.log(data))
LoL Status
docs
- /lol/status/v3/shard-data
- Get League of Legends status for the given shard.
- getShardStatus({ region }, cb)
- Namespaced Functions: Status.getShardStatus, Status.getStatus, Status.get
- Example 1:
k.Status.get().then(data => console.log(data))
Masteries
docs
- /api/lol/{region}/v1.4/summoner/{summonerIds}/masteries
- Get mastery pages for a given summoner ID.
- getMasteries({ region, id/summonerID/playerID (int), name (str)}, cb)
- Namespaced Functions: RunesMasteries.getMasteries, RunesMasteries.masteries, Masteries.get
- Example 1:
k.Masteries.get({ id: 20026563 }, KindredAPI.print)
Match
docs
- /api/lol/{region}/v2.2/match/{matchId}
- Retrieve match by match ID. (REST)
- getMatch({ region, id/matchID (int), options: { includeTimeline: true } }, cb)
- Namespaced Functions: Match.getMatch, Match.get
- Example 1:
k.Match.get({ id: 1912829920 }, KindredAPI.print)
- Example 2:
k.Match.get({ id: 1912829920, options: { includeTimeline: false } }, rprKindredAPI.printint)
MatchList
docs
- /api/lol/{region}/v2.2/matchlist/by-summoner/{summonerId}
- Retrieve match list by match ID. (REST)
- getMatchList({ region, id/summonerID/playerID (int), name (str), options: { rankedQueues: 'RANKED_SOLO_5x5' } }, cb)
- Namespaced Functions: MatchList.getMatchList, MatchList.get
- Example 1:
k.MatchList.get({ id: 20026563 }, KindredAPI.print)
- Example 2:
k.MatchList.get({ id: 20026563, options: { rankedQueues: 'RANKED_FLEX_SR' } }, KindredAPI.print)
- Example 3:
k.MatchList.get({ name: 'Contractz' }, KindredAPI.print)
Runes
docs
- /api/lol/{region}/v1.4/summoner/{summonerIds}/runes
- Get rune pages for a given summoner ID.
- getRunes({ region, id/summonerID/playerID (int), name (str) }, cb)
- Namespaced Functions: RunesMasteries.getRunes, RunesMasteries.runes, Runes.get
- Example 1:
k.Runes.get({ id: 20026563 }, KindredAPI.print)
- Example 2:
k.Runes.get({ name: 'Contractz' }, KindredAPI.print)
Spectator
docs
- /lol/spectator/v3/active-games/by-summoner/{summonerId}
- Get current game information for the given summoner ID. (REST)
- getCurrentGame({ region = this.defaultRegion, id/summonerID/playerID (int), name (str) }, cb)
- Namespaced Functions: CurrentGame.getCurrentGame, CurrentGame.get
- Example 1:
k.CurrentGame.get({ name: 'Contractz' }, KindredAPI.print)
- Example 2:
k.CurrentGame.get({ id: 32932398 }, KindredAPI.print)
- /lol/spectator/v3/featured-games
- Get list of featured games. (REST)
- getFeaturedGames({ region }, cb)
- Namespaced Functions: FeaturedGames.getFeaturedGames, FeaturedGames.get
- Example 1:
k.FeaturedGames.get().then(data => console.log(data))
- Example 2:
k.FeaturedGames.get({ region: 'na' }, KindredAPI.print)
Static Data
docs
- /lol/static-data/v3/champions
- Retrieves champion list. (REST)
- getChampionList({ region, options (object) }, cb)
- Namespaced Functions: Static.getChampions, Static.champions
- Example 1:
k.Static.champions(KindredAPI.print)
- Example 2:
k.Static.champions({ options: { champData: 'all' } }).then(data => console.log(data))
- /lol/static-data/v3/champions/{id}
- Retrieves a champion by its id. (REST)
- getChampion({ region, id/championID (int), options (object) }, cb)
- Namespaced Functions: Static.getChampion, Static.champion
- Example 1:
k.Static.champion({ id: 131 }, KindredAPI.print)
- Example 2:
k.Static.champion({ id: 131, options: { champData: 'enemytips', version: '7.7.1' } }, KindredAPI.print)
- /lol/static-data/v3/items
- Retrieves item list. (REST)
- getItems({ region, options (object) }, cb)
- Namespaced Functions: Static.getItems, Static.items
- Example 1:
k.Static.items({ options: { itemListData: all } }, KindredAPI.print)
- /lol/static-data/v3/items/{id}
- Get master tier leagues. (REST)
- getItem({ region, id/itemID (int), options (object) }, cb)
- Namespaced Functions: Static.getItem, Static.item
- Example 1:
k.Static.item({ id: 3901, options: { itemData: ['image', 'gold'] } }, KindredAPI.print)
- Example 2:
k.Static.items(KindredAPI.print)
- /lol/static-data/v3/language-strings
- Retrieve language strings data. (REST)
- getLanguageStrings({ region, options (object) }, cb)
- Namespaced Functions: Static.getLanguageStrings, Static.languageStrings
- Example 1:
k.Static.languageStrings(KindredAPI.print)
- /lol/static-data/v3/languages
- Retrieve supported languages data. (REST)
- getLanguages({ region }, cb)
- Namespaced Functions: Static.getLanguages, Static.languages
- Example 1:
k.Static.languages().then(data => console.log(data)).catch(err => console.log(err))
- /lol/static-data/v3/maps
- Retrieve map data. (REST)
- getMapData({ region, options (object) }, cb)
- Namespaced Functions: Static.getMapData, Static.mapData, Static.map, Static.maps
- Example 1:
k.Static.mapData().then(data => console.log(data))
- /lol/static-data/v3/masteries
- Retrieve mastery list. (REST)
- getMasteryList({ region, options (object) }, cb)
- Namespaced Functions: Static.getMasteries, Static.masteries
- Example 1:
k.Static.masteries({ options: { masteryListData: 'image' } }, KindredAPI.print)
- Example 2:
k.Static.masteries(KindredAPI.print)
- /lol/static-data/v3/masteries/{id}
- Retrieves mastery item by its unique id. (REST)
- getMastery({ region, id/masteryID (int), options (object) }, cb)
- Namespaced Functions: Static.getMastery, Static.mastery
- Example 1:
k.Static.mastery({ id: 6361 }, KindredAPI.print)
- Example 2:
k.Static.mastery({ id: 6361, options: { masteryData: ['image', 'masteryTree'] } }, KindredAPI.print)
- Example 3:
k.Static.mastery({ id: 6361, options: { masteryData: 'image' } }, KindredAPI.print)
- /lol/static-data/v3/profile-icons
- Retrieve profile icons. (REST)
- getProfileIcons({ region, options (object) }, cb)
- Namespaced Functions: Static.getProfileIcons, Static.profileIcons
- Example 1:
k.Static.profileIcons(KindredAPI.print)
- /lol/static-data/v3/realms
- Retrieve realm data. (REST)
- getRealmData({ region }, cb)
- Namespaced Functions: Static.getRealmData, Static.realmData, Static.realm, Static.realms
- Example 1:
k.Static.realmData().then(data => console.log(data))
- /lol/static-data/v3/runes
- Retrieves rune list. (REST)
- getRuneList({ region, options (object) }, cb)
- Namespaced Functions: Static.getRunes, Static.runes
- Example 1:
k.Static.runes().then(data => console.log(data))
- Example 2:
k.Static.runes({ options: { runeListData: 'basic' } }, KindredAPI.print)
- /lol/static-data/v3/runes/{id}
- Retrieves rune by its unique id. (REST)
- getRune({ region, id/runeID (int), options (object) }, cb)
- Namespaced Functions: Static.getRune, Static.rune
- Example 1:
k.Static.rune({ id: 10002 }, KindredAPI.print)
- Example 2:
k.Static.rune({ id: 10001, options: { runeData: 'image' } }, KindredAPI.print)
- /lol/static-data/v3/summoner-spells
- Retrieves summoner spell list. (REST)
- getSummonerSpells({ region, options (object) }, cb)
- Namespaced Functions: Static.getSummonerSpells, Static.summonerSpells, Static.spells
- Example 1:
k.Static.spells(KindredAPI.print)
- Example 2:
k.Static.spells({ options: { spellData: 'cost', dataById: true } }, KindredAPI.print)
- /lol/static-data/v3/summoner-spells/{id}
- Retrieves summoner spell by its unique id. (REST)
- getSummonerSpell({ region, id/spellID/summonerSpellID (int), options (object) }, cb)
- Namespaced Functions: Static.getSummonerSpell, Static.summonerSpell, Static.spell
- Example 1:
k.Static.spell({ id: 31 }, KindredAPI.print)
- Example 2:
k.Static.spell({ id: 31, options: { spellData: 'cooldown' } }, KindredAPI.print)
- /lol/static-data/v3/versions
- Retrieve version data. (REST)
- getVersionData({ region }, cb)
- Namespaced Functions: Static.getVersionData, Static.versionData, Static.version, Static.versions
- Example 1:
k.Static.versions(rprint)
Stats
docs
- /api/lol/{region}/v1.3/stats/by-summoner/{summonerId}/ranked
- Get ranked stats by summoner ID. (REST)
- getRankedStats({ region, id/summonerID/playerID (int), name (str), options (object) }, cb)
- Namespaced Functions: Stats.getRankedStats, Stats.ranked
- Example 1:
k.Stats.ranked({ id: 20026563 }, KindredAPI.print)
- Example 2:
k.Stats.ranked({ id: 20026563, options: { season: 'SEASON2016' } }, KindredAPI.print)
- /api/lol/{region}/v1.3/stats/by-summoner/{summonerId}/summary
- Get player stats summaries by summoner ID. (REST)
- getStatsSummary({ region, id/summonerID/playerID (int), name (str), options (object) }, cb)
- Namespaced Functions: Stats.getStatsSummary, Stats.summary
- Example 1:
k.Stats.summary({ id: 20026563 }, KindredAPI.print)
Summoner
docs
- /lol/summoner/v3/summoners/by-account/{accountId}
- Get a summoner by account id
- getSummoner({ region, accountID (int), name (str) }, cb)
- Namespaced Functions: Summoner.getSummoner, Summoner.get
- Example 1:
k.Summoner.get({ accountID: 123123 }, KindredAPI.print)
- /lol/summoner/v3/summoners/by-name/{summonerName}
- Get a summoner by summoner name
- getSummoner({ region, id/summonerID/playerID (int) }, cb)
- Namespaced Functions: Summoner.getSummoner, Summoner.get
- Example 1:
k.Summoner.get({ name: 'Contractz' }, KindredAPI.print)
- /lol/summoner/v3/summoners/{summonerId}
- Get a summoner by summoner id
- getSummoner({ region, id/summonerID/playerID (int) }, cb)
- Namespaced Functions: Summoner.getSummoner, Summoner.get
- Example 1:
k.Summoner.get({ id: 20026563 }, KindredAPI.print)
Quickstart
Debug on, dev key rate limiting per region, in-memory cache with default settings on for quick scripts
var KindredAPI = require('kindred-api')
var REGIONS = KindredAPI.REGIONS
var debug = true
var k = KindredAPI.QuickStart('YOUR_KEY', REGIONS.NORTH_AMERICA, debug)
k.Summoner.get({ id: 32932398 }, KindredAPI.print)
k.Summoner.get({ name: 'Contractz' }, KindredAPI.print)
var name = 'caaaaaaaaaria'
var opts = {
region: REGIONS.NORTH_AMERICA,
options: {
rankedQueues: ['RANKED_SOLO_5x5', 'RANKED_FLEX_SR'],
championIds: '67'
}
}
k.Summoner.get({ name: name, region: opts.region })
.then(data => k.MatchList.get(
Object.assign({ id: data.id }, opts)
))
.then(data => console.log(data))
.catch(err => console.err(error))
k.MatchList.get({ name: name, options: opts.options })
.then(data => console.log(data))
.catch(err => console.error(err))
Detailed Usage
var KindredAPI = require('kindred-api')
require('dotenv').config()
var RIOT_API_KEY = process.env.RIOT_API_KEY
var REGIONS = KindredAPI.REGIONS
var LIMITS = KindredAPI.LIMITS
var CACHE_TYPES = KindredAPI.CACHE_TYPES
var k = new KindredAPI.Kindred({
key: RIOT_API_KEY,
defaultRegion: REGIONS.NORTH_AMERICA,
debug: true,
limits: [ [10, 10], [500, 600] ],
cacheOptions: CACHE_TYPES[0]
})
console.log(CACHE_TYPES)
function rprint(err, data) { console.log(data) }
k.Summoner.get({ id: 354959 }, rprint)
k.Summoner.get({ id: 354959 }).then(data => console.log(data))
k.Match.get({ id: 2459973154, options: {
includeTimeline: false
}}, rprint)
k.League.challengers({ region: 'na', options: {
type: 'RANKED_FLEX_SR'
}}, rprint)
k.Summoner.get(rprint)
k.ChampionMastery.get(rprint)
k.League.challengers(rprint)
k.Static.runes(rprint)
k.Summoner.get({ name: 'Contractz' }, rprint)
k.Summoner.get({ id: 354959 }, rprint)
k.Summoner.get({ summonerID: 354959 }, rprint)
k.Summoner.get({ summonerID: 354959 })
.then(json => console.log(json))
.catch(err => console.log(err))
k.Match.get({ id: 2459973154 }, rprint)
k.Match.get({ matchID: 2459973154 })
.then(data => console.log(data))
.catch(err => console.error(err))
var params = { name: 'sktt1peanut', region: REGIONS.KOREA }
k.Summoner.get(params, rprint)
k.setRegion(REGIONS.KOREA)
var fakerIgn = { name: 'hide on bush' }
var fakerId
k.Summoner.get(fakerIgn, function (err, data) {
fakerId = data.id
console.log('fakerId:', fakerId)
})
k.setRegion(REGIONS.NORTH_AMERICA)
k.Runes.get({ id: 354959 }, rprint)
k.Runes.get({ id: 354959 })
.then(json => console.log(json))
.catch(err => console.error(err))
var name = 'Richelle'
k.Summoner.get({ name }, function (err, data) {
if (data) k.Runes.get({ id: data.id }, rprint)
else console.err(err)
})
k.Summoner.get({ name })
.then(data => k.Runes.get({ id: data.id }))
.then(data => console.log(data))
.catch(err => console.log(err))
k.Runes.get({ name: 'Richelle' }, rprint)
k.Game.get({ name: 'Richelle' }, rprint)
k.League.get({ name: '5tunt' }, rprint)
k.CurrentGame.get({ name: 'Fràe', region: REGIONS.OCEANIA }, rprint)
k.League.get({ name: '5tunt' })
.then(data => console.log(data))
var name = 'Grigne'
k.Runes.get({ name })
.then(data => console.log(data))
k.Masteries.get({ name })
.then(data => console.log(data))
k.League.challengers({ region: 'na' }, rprint)
k.League.challengers({ region: 'na', options: {
type: 'RANKED_FLEX_SR'
}}, rprint)
k.Match.get({ id: 2459973154 }, rprint)
k.Match.get({ id: 2459973154, options: { includeTimeline: false } }, rprint)
var name = 'caaaaaaaaaria'
k.MatchList.get({ name, region: 'na', options: {
rankedQueues: ['RANKED_SOLO_5x5', 'RANKED_FLEX_SR'],
championIds: [67, 62, '61']
} }, rprint)
var opts = {
name: 'caaaaaaaaaria',
region: 'na',
options: {
rankedQueues: ['RANKED_SOLO_5x5', 'RANKED_FLEX_SR'],
championIds: '67'
}
}
k.MatchList.get({ name: opts.name, region: opts.region, options: opts.options })
.then(data => console.log(data))
.catch(err => console.err(error))
var furyMasteryId = 6111
k.Static.mastery({ id: furyMasteryId }, rprint)
var msRuneId = 10002
k.Static.rune({ id: msRuneId }, rprint)
Caching
April 2
I have added caching support. Right now, the library supports in-memory caching as well as
caching with Redis. These are the default timers that made sense to me.
const endpointCacheTimers = {
CHAMPION: cacheTimers.MONTH,
CHAMPION_MASTERY: cacheTimers.SIX_HOURS,
CURRENT_GAME: cacheTimers.NONE,
FEATURED_GAMES: cacheTimers.NONE,
GAME: cacheTimers.HOUR,
LEAGUE: cacheTimers.SIX_HOURS,
STATIC: cacheTimers.MONTH,
STATUS: cacheTimers.NONE,
MATCH: cacheTimers.MONTH,
MATCH_LIST: cacheTimers.ONE_HOUR,
RUNES_MASTERIES: cacheTimers.WEEK,
STATS: cacheTimers.HOUR,
SUMMONER: cacheTimers.DAY
}
If you pass in cacheOptions, but not how long you want each type of request
to be cached (cacheTTL object), then by default you'll use the above timers.
To pass in your own custom timers, initialize Kindred like this:
import TIME_CONSTANTS from KindredAPI.TIME_CONSTANTS
var k = new KindredAPI.Kindred({
key: RIOT_API_KEY,
defaultRegion: REGIONS.NORTH_AMERICA,
debug: true,
limits: [ [10, 10], [500, 600] ],
cacheOptions: CACHE_TYPES[0],
cacheTTL: {
CHAMPION: whatever,
CHAMPION_MASTERY: whatever,
CURRENT_GAME: whatever,
FEATURED_GAMES: whatever,
GAME: whatever,
LEAGUE: whatever,
STATIC: TIME_CONSTANTS.MONTH,
STATUS: whatever,
MATCH: whatever,
MATCH_LIST: whatever,
RUNES_MASTERIES: whatever,
STATS: whatever,
SUMMONER: TIME_CONSTANTS.DAY
}
})
Contributing and Issues
Feel free to make a PR regarding anything (even the smallest typo or inconsistency).
There are a few inconsistencies and weird things within this libary that I don't know how to address since this is my first API wrapper and I'm still quite a big newbie.
For example, the two methods getChamp() and getChampion() are actually different.
getChamp() targets the champ endpoint
getChampion() targets the static endpoint
I didn't want to attach getChampion() with 'static' in any way or form since I thought it looked kind of annoying because then I would want to attach static to the other static methods as well (maybe that's better?).
March 31: I decided to combat the above by just namespacing the functions
(k.Static.getChampion vs k.Champion.getChampion/get). The original functions are still usable though.
Right now, the code is also quite messy and there is a lot of repeated code. Function definitions are quite long because I include many aliases as well. I haven't thought of an elegant way to make a magic function that manages to work for every single endpoint request yet.
Any help and/or advice is appreciated!