Public changelog website for
The History tab on a profile lets you browse and filter every match in that profile’s match history.
Standard Filters is the default mode. Set up any rules you want, then press Apply filters. Every active rule must match. Comma-separated names within one rule match any of those names.
Ahri, Jinx (means Ahri or Jinx).For anything the standard filters can’t express, switch to AI and Advanced Filtering. Only the visible mode is used: switching modes keeps the other mode’s settings, but they have no effect on results until you switch back.
The code box is for advanced users. Filters are JavaScript that runs in your own browser (not on rewind.lol’s servers) against your own match data. Do not paste code or prompts from unknown or untrusted sources.
The full reference, including every field and helper, is the same set of system instructions the AI uses: rewind.lol/nlp_code_gen.txt. The rest of this section is a practical summary.
(match) => boolean function. It is called once for every match in your history, and matches where it returns true are shown.(match) => summaryObject. Called once for every match. Return a small, flat object. It must include mid: match.mid.(summaries) => an array or Set of mid values to show. summaries is ordered newest first, so use [...summaries].reverse() when you need chronological order.(match) => a value to sort by. It must be JSON-safe (numbers, strings, booleans, null, arrays, or plain objects) and no larger than 1 KB.(left, right) => number, like a normal JavaScript sort comparator. It receives only the sort values, not the matches.async. Ties keep the normal newest-first order.Each match describes the game from the profile owner’s point of view. Any field can be missing on older matches, so use optional chaining (?.) and defaults (??).
| Field | Type | Meaning |
|---|---|---|
match.mid |
number | Match ID |
match.qid |
number | Queue ID, e.g. 420 ranked solo/duo, 440 ranked flex, 450 ARAM, 1700 and 1710 Arena. See Riot’s queue list |
match.win |
true / false / null | Win, loss, or remake/other |
match.timestamp |
number | Game end time, in milliseconds since 1970 |
match.duration |
number | Game length in seconds |
match.patch |
string | e.g. "14.3" |
match.cid |
number | Your champion ID |
match.K, match.D, match.A |
number | Your kills, deaths, and assists |
match.kp |
number / null | Your kill participation percent, rounded. null if your team had no kills |
match.side |
string | "-1" blue, "1" red, "0" not Summoner’s Rift |
match.nsr_side |
number | -1 blue, 1 red, in every mode except Arena (including ARAM). Note this is a number, unlike side |
match.ff |
true / false / null | Only set for your losses on Summoner’s Rift and ARAM: true if your team surrendered, otherwise false. null for wins, remakes, and other modes |
match.ttmga |
number | Gold difference at the turning point of the game, from your team’s side (sampled once per minute). In a win, it’s the biggest deficit you came back from (0 or negative). In a loss, it’s the biggest lead you lost (0 or positive) |
match.ttmga_t |
string | The minute ttmga happened, e.g. "14" |
match.teams["-1"], match.teams["1"] |
array | Blue and red team participants |
Each participant p in a team has:
| Field | Type | Meaning |
|---|---|---|
p.ign |
string | Name in this match: either "Name" or "Name#TAG" |
p.target |
boolean | true for the profile owner |
p.cid |
number | Champion ID |
p.lane |
number | 1 top, 2 jungle, 3 mid, 4 support, 5 bottom |
p.K, p.D, p.A |
number | Kills, deaths, assists |
p.cs |
number | Lane and jungle minions killed |
p.lv |
number | Champion level |
p.fb |
boolean | Got first blood |
p.items |
array | 8 item IDs: slots 0-5 inventory, 6 trinket, 7 role quest item (Patch 26.01+) |
p.spells |
array | 2 summoner spell IDs |
p.multi_kills |
object | Counts keyed "2", "3", "4", "5" (double to penta), and "L" for kills beyond a pentakill |
Arena matches (match.mode === "ARENA") are different:
match.placement is your final placement.match.teams is an array of subteams, ordered by placement, instead of "-1"/"1".p.placement and p.augments, but no lane, cs, fb, or multi_kills.side, nsr_side, ff, ttmga, or ttmga_t, and kp is always null.Runes, damage, vision, timelines, and item purchase times are not available.
These functions are available in your code. They handle Arena and older data correctly, so prefer them over reading match.teams yourself.
| Helper | Use |
|---|---|
getAllParticipants(match) |
Every participant in the match, in both normal and Arena matches |
fuzzyChampionSearch("kaisa") |
Champion name to champion ID, tolerating typos and renamed champions |
getChampionNameFromId(cid) |
Champion ID to name |
isPlayingChampion(match, cid) |
You played this champion |
teamHasChampion / enemyTeamHasChampion / blueTeamHasChampion / redTeamHasChampion / matchHasChampion (match, cid) |
Champion is on that team |
teamHasPlayer / enemyTeamHasPlayer / blueTeamHasPlayer / redTeamHasPlayer / matchHasPlayer (match, p => ...) |
Some participant on that team passes your check |
isBotParticipant(p) |
Participant is a bot |
parseRiotId(ign) |
Splits "Name#TAG" into {base, tag} |
cleanUsername(name) |
Lowercases and removes spaces, for comparing names |
getPlayerIdentity(p) |
An ID that stays the same when a player changes their name |
player_index_map |
Every name each player identity has used in your history, for following name changes |
Games where you got a pentakill:
match => {
const me = getAllParticipants(match).find(p => p.target);
return (me?.multi_kills?.["5"] ?? 0) > 0;
}
Games longer than 40 minutes on red side, since 2024:
(function () {
const since = new Date("2024-01-01").getTime();
return match => match.nsr_side === 1 && match.timestamp >= since && match.duration > 40 * 60;
})()
Games where you had 10+ CS per minute:
match => {
const me = getAllParticipants(match).find(p => p.target);
return me?.cs != null && me.cs / (match.duration / 60) >= 10;
}
Wins where you came back from 5,000 or more gold behind:
match => match.win === true && match.ttmga <= -5000
Games against a player, by name (without the tagline):
(function () {
const wanted = cleanUsername("faker");
return match => enemyTeamHasPlayer(match, p =>
!isBotParticipant(p) && cleanUsername(parseRiotId(p.ign).base) === wanted);
})()
Your 10 highest-KDA games, highest first (Cross-match, with Custom sort):
match => ({ mid: match.mid, kda: (match.K + match.A) / Math.max(1, match.D) })summaries => [...summaries].sort((a, b) => b.kda - a.kda).slice(0, 10).map(s => s.mid)match => (match.K + match.A) / Math.max(1, match.D)(left, right) => right - leftfuzzyChampionSearch, building a Set, or parsing dates in an outer function, as in the examples above, and return the per-match function from it.{"title": ..., "predicate": ...}) into the code box. The page splits it into the right fields and switches to Cross-match if needed.https://ddragon.leagueoflegends.com/ during setup (the URL must be written out in full; other websites are blocked). See the system instructions for an example.console.log output appears in your browser’s developer console. Remove it once your filter works, because it runs once per match.