Skip to content

Quickstart

The API is public and needs no key. Every example here runs on this page.

GET /api/v1/songs/{id}
Not sent yet

server chooses the catalog: jp, or intl for Global, which is the default. Text fields are arrays in the order Japanese, English, Traditional Chinese, Simplified Chinese, Korean. An empty string means that language has no text yet.

GET /api/v1/songs
Not sent yet

Lists return items, plus nextCursor while there is more. Pass it back as cursor for the next page:

const base = "https://haneoka.org/api/v1/songs?server=jp&limit=100";
const songs = [];
let cursor = null;
do {
const url = cursor ? `${base}&cursor=${encodeURIComponent(cursor)}` : base;
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const page = await response.json();
songs.push(...page.items);
cursor = page.nextCursor;
} while (cursor);
console.log(songs.length);

Image fields are paths on haneoka.org. Add the origin to use them, and set referrerpolicy="no-referrer": files refuse requests that name another site as the referrer.

<img id="jacket" alt="" width="240" height="240" referrerpolicy="no-referrer">
<h1 id="title"></h1>
<script type="module">
const origin = "https://haneoka.org";
const song = await (await fetch(`${origin}/api/v1/songs/100091?server=jp`)).json();
document.querySelector("#title").textContent = song.musicTitle[0];
document.querySelector("#jacket").src = origin + song.jacketUrl;
</script>