Chapter 5
API
Every JSON answer is { success, data, timestamp }. Handlers live in server/api/ and server/routes/, and this table is the list in shared/endpoints.ts.
Endpoints
| Endpoint | Returns |
|---|---|
GET /api/daily-word?date=YYYY-MM-DD | One entry plus its prev and next days and sameDay, the open words of the same month and day in other years, oldest first. With no date: today in Japan; once the catalogue runs out the words start again from the first, and lap says which pass it is (1 until then, always 1 for an explicit date). A future or invalid date is a 400; a past date with no entry (or no word yet) is a 404. next stays null until that day has arrived. |
GET /api/word-calendar?month=YYYY-MM | { month, months, today, days, filters, total, count, monthCounts, facets }. An open day carries its term, kana, stratum and match (whether it passes the filters, always true with none); an upcoming day carries only its date and "upcoming", and is never matched. Once the catalogue has run out, an open day after the last entry shows the word of its lap and also carries wordDate (the day that word first opened) and lap, and months runs on to the current month. The filters are the /api/explore ones, with the same counts: count of total open words match across every month, monthCounts gives each month's matches and facets the options' counts. The month defaults to the current one if it has words, else the newest. A malformed month or an invalid filter is a 400, a month with no words a 404. |
GET /api/parts | The parts index, { parts: [{ text, count, readings }] }: every morpheme an open word's “Taken apart” row shows, most-used first. |
GET /api/part?text=日 | One part with the open words that show it, grouped by the reading it has in each: { text, count, readings, alsoIn }. Only days that have arrived count, so a part seen only in an upcoming word is a 404. A missing or over-long text is a 400. |
GET /api/kanji | The kanji index, { kanji: [{ char, count, grade? }] }: every kanji an open word is written with, most-used first, with KANJIDIC2's school grade. |
GET /api/kanji-detail?char=日 | KANJIDIC2's record of one kanji with the open words written with it: { char, strokeCount, grade?, freq?, on, kun, meanings, count, words, isPart, strokes?, components? }, where each of words carries its JLPT level and strokes is KanjiVG's stroke paths in drawing order on a 109 by 109 square, left out when KanjiVG and KANJIDIC2 count the strokes differently, and components is the shapes KRADFILE lists it as containing, each with a few other open kanji that contain it, left out where it lists none. Only days that have arrived count, so a kanji used only by an upcoming word is a 404. A missing value or more than one character is a 400. |
GET /api/explore?q= | The open words matching every filter, newest first: { filters, total, count, words, facets }. count is every match, but words holds only the newest 100 unless limit asks for more (a whole number of at least 1). Every filter is optional and an empty value means “no filter”; anything else invalid is a 400. level, stratum (which also takes unstated), process, pos (a group such as verb), frequency (common, less or unlisted, from JMdict's priority codes) and pitch (heiban, atamadaka, nakadaka, odaka or unstated, the patterns of the accents the entry shows) take several comma-joined choices; match=all makes a word carry every process, part of speech and accent pattern chosen instead of any. Each facet counts the words the other filters leave. |
GET /api/patterns | Counts across the open words: { total, withParts, withBase, strata, levels, processes, pairs, combinations, rendaku, pitch, lengths, soundAlikes }, the last three being the pitch accents split into patterns by layer, the mean length of the words by level, and the readings two or more words share ({ readings, words, withAccents, toldApart, groups }, the readings with the most words in groups). |
GET /api/related?date=YYYY-MM-DD | Up to six open words that resemble one entry (shared parts, processes or layer), closest first, each with what it shares; the words JMdict points the entry's sense at (antonyms, seeAlso), each with the open word it is where there is exactly one; and the open words with the same reading and another spelling, oldest first, each with its pitch accents (soundAlikes): { date, words, antonyms, seeAlso, soundAlikes }. date is required; a future or malformed one is a 400, a day with no entry a 404. |
GET /api/catalogue | { first, last, total, open, coverage }: the first and last day of the written catalogue, how many words it holds and how many have opened, and in coverage how many of the open words carry a layer, a pitch accent, example sentences, parts, processes and a quoted origin. The word range and the coverage table quoted in the docs come from this. |
GET /sitemap.xml | Server route, not under /api. Lists the static pages, every open word and each part or kanji seen in more than one open word, never an upcoming day. URLs use NUXT_PUBLIC_SITE_URL when set, else the request's own origin. |
GET /og.png?date=YYYY-MM-DD | Server route, not under /api (so robots.txt does not block link previews). The share image of one open word as a 1200 by 630 PNG: the word, its reading, meaning, level, layer and headline, in the palette of its day's season. A future, malformed or unknown date is a 404, so the image cannot reveal a word early. The page's Open Graph tags point here. |
GET /robots.txt | Server route, not under /api. Disallows /api/ and names the sitemap. |
A successful answer is cached until midnight in Japan (Caching). An address that asks an /api/ endpoint or the share image more than 120 times in 60 seconds gets a 429 with Retry-After. The count is kept in memory, never stored, so each server instance counts alone, and a client behind a proxy that does not set X-Forwarded-For is counted by the proxy's address. A day's words are served only once it is open (Daily words); what each failure looks like on a page is in Error and fallback states.
Example
GET /api/daily-word?date=2013-05-04, abridged
{
"success": true,
"data": {
"entry": {
"date": "2013-05-04",
"term": "サンキュー",
"kana": "サンキュー",
"meaning": "thank you",
"level": "N1",
"pos": ["interjection (kandoushi)"],
"priority": ["gai1"],
"register": ["colloquial"],
"pitch": [1],
"stratum": "gairaigo",
"processes": ["borrowing"],
"headline": "サンキュー is borrowed from English thank you.",
"morphemes": [
{ "text": "サンキュー", "reading": "サンキュー", "meaning": "English thank you" }
],
"sources": [{ "quote": "Borrowed from English thank you." }],
"wiktionaryDump": "2026-09-02"
},
"lap": 1,
"prev": { "date": "2013-05-03", "term": "免れる" },
"next": { "date": "2013-05-05", "term": "霞む" }
},
"timestamp": "2026-10-07T00:00:00.000Z"
}