Skip to content

Game records

Game records are snapshots of the official game, collected by Haneoka’s own account pool. Every read is public and needs no key.

Requests use a region, because each one is a separate game server:

RegionServer
jpJP
twTW/HK/MO
enEN Regions
krKR

Regions are different from the jp and intl catalog servers: tw, en and kr all share the Global catalog.

Data is read from stored snapshots, so a request never waits on the game. When something has not been collected yet, the API queues it and answers 503:

{ "error": { "kind": "pending", "retryAfter": 30 } }

Wait retryAfter seconds, then repeat the same request. Most reads complete within a few minutes.

The running event, its dates and which boards it has. event is null between events.

GET /api/v1/game/records/{region}/events/current
Not sent yet

The total board, or one challenge song’s board, with the top 100 players and their decks.

GET /api/v1/game/records/{region}/events/{eventId}/total/latest
Not sent yet
GET /api/v1/game/records/{region}/events/{eventId}/challenges/{challengeId}/latest
FieldMeaning
rows[].rank, tiedPosition, and whether another row shares it
rows[].scoreExactScore as a decimal string. Use it for totals past 2^53
rows[].profileIdPass to the player endpoint
rows[].profileCardName card, or null
rows[].cardsThe five deck slots: member and Snapshot IDs with growth
observedAtMs, staleWhen it was collected, and whether it is overdue

Events that rank points have a third board. Rows carry point and no deck; other events answer 404.

GET /api/v1/game/records/{region}/events/{eventId}/latest
Not sent yet

Read the board 100 ranks at a time. start falls back to its window, maxRank is null until the last rank is seen, and search looks through the top 2000 by player ID. Windows are collected only while an event has a point board.

GET /api/v1/game/records/{region}/events/{eventId}/points/ranking
Not sent yet
GET /api/v1/game/records/{region}/events/{eventId}/points/search
Not sent yet

The top 100 for one song.

GET /api/v1/game/records/{region}/songs/{musicId}/ranking
Not sent yet

One league’s board, 100 rows at a time. bandId is the league’s band, and start is a rank.

GET /api/v1/game/records/{region}/arena/seasons/{seasonId}/leagues/{bandId}/ranking
Not sent yet

Rows match event boards, with point in place of a score.

How many players hold at least each threshold. A cold count answers 202; repeat after Retry-After.

GET /api/v1/game/records/{region}/arena/seasons/{seasonId}/leagues/{bandId}/population
Not sent yet

Looks for an in-game ID among the top searchedTo ranks. row is null when they are further down.

GET /api/v1/game/records/{region}/arena/seasons/{seasonId}/leagues/{bandId}/search
Not sent yet

A public profile by the ID shown in the game.

GET /api/v1/game/records/{region}/players/{profileId}
Not sent yet

The first read of a player may answer pending. Records refresh after six hours.

profileCard.pages[].downloadUrl gives a PNG download for each page of the card.

import { createGameClient } from "https://haneoka.org/tools/api-client.js";
const game = createGameClient({ region: "jp" });
const { event } = await game.currentEvent();
const board = await game.eventRanking(event.id);
for (const row of board.rows.slice(0, 3)) console.log(row.rank, row.name, row.scoreExact);

The client also has profile, songRanking, challengeRanking and arenaRanking.