Kotowa

Pack format

A pack is a folder of JSON files, usually sent as a .zip. This page lists every file and field Kotowa reads. To have an AI agent write the pack for you, see Make your own pack. The format is also available as JSON Schema for the manifest and a unit file, and a checker script tests a pack folder.

Files

FileMeaning
manifest.jsonRequired. The pack's title, languages, license and the list of its units.
units/<id>.jsonRequired for every unit the manifest lists: the unit's items. The path is whatever the manifest's path says.
media/…The images that items point to with image.
search-index.json, jmdict.json, characters.jsonWritten by the pack tool. Kotowa reads them for search, for dictionary entries and for speaker pages. A pack without them is still accepted when you add it.

In the .zip, manifest.json sits at the top, or inside one folder that holds everything. File paths may not start with /, contain \ or contain ... A pack's id becomes a folder name on the device: it uses letters, digits, ., _ and -, and starts with a letter or digit.

When you add a .zip, Kotowa unpacks it in memory and checks the manifest and every unit before it writes anything. A pack with a problem is refused and nothing is changed.

Version

The current format version is 1. A manifest may carry schemaVersion; without it the pack counts as version 1. A pack with a higher number is refused with a message that it needs a newer Kotowa.

Languages

Language codes are short text like ja, en and es. A translation is always an object that maps a code to text, such as {"en": "Hello"}. The pack tool writes Japanese packs; sourceLanguage is ja for them.

Manifest

FieldTypeMeaning
idtextThe pack's name on the device, as described above.
titletextShown in the Library.
sourceLanguagelanguage codeThe language of the lines you read.
targetLanguageslist of language codesThe languages the pack's translations and glosses are in. The list must be present; it may be empty.
licensetextThe license the content is offered under, such as cc-by-4.0 or public-domain, or private when the content is for your own use only. Shown in Settings.
attributiontextThe credit line, when the license asks for one.
creditstextWho made the content and where it came from. Shown in Settings under the license, and on the About screen.
unitslist of unit entriesEvery unit of the pack, see Unit entry below. Kotowa draws the folder tree from this list alone.
videoslist of videosThe videos that items' timing points into, see Video below. Leave it out when the pack has no video.
schemaVersionnumberThe format version the pack was made for, see Version above.
contentHashtextAn identifier that changes whenever the pack's content changes. The pack tool writes one; Kotowa only carries it.

Unit entry

A unit is a section of the pack: a scene, a chapter, a page. A folder is a unit with children, at any depth, and units point to their parent with parentId. Each manifest entry repeats the unit's own details so that Kotowa can draw the tree without opening the unit files. Every field that the unit file also has (id to kind) must have the same value in both.

FieldTypeMeaning
idtextThe unit's identifier, unique in the pack.
titletextShown in the tree.
ordertextSort key among units with the same parent. Text, compared character by character, so use zero-padded numbers like 0001.
parentIdtext or nullThe id of the folder this unit is in. Null or absent at the top level.
daytextA day, if the source has one. The format is yours.
momenttextA time of day within day. The format is yours.
labeltextA short label printed in a box before the title, such as a day of the month or an episode number.
labelNotetextA note under the label.
kindtextWhat the unit is, as a singular noun that Kotowa makes plural in counts: day gives "23 days".
pathtextWhere the unit's file is, from the pack's top, for example units/morning.json.
itemCountnumberHow many items the unit file holds. 0 marks a folder that only groups other units.
partnumberWhich part of a long source the unit first appears in. The downloads screen groups by it.
bytesnumberSize of the unit's file in bytes.
contentVersiontextAn identifier of this export of the unit. It changes when the unit or its images change, which lets Kotowa tell a downloaded copy from a newer one.
mediaBytesnumberTotal size in bytes of the images this unit's items use, 0 if none.
imageobjectThe picture that stands for the unit in previews: {"path": "media/page1.png", "unitId": "page-1"}, where unitId is the unit whose files include the image.
videoslist of video spansThe videos this unit's own items are timed in, see Video span below.

Video

A pack made from a video says where each line is in it. The pack never holds the video: the learner links their own copy.

FieldTypeMeaning
idtextWhat items' timing.video refers to.
titletextShown when Kotowa asks the learner to link the video.
sourceIdtextAn identifier of the video where it comes from, such as a video site's id.
sourceUrltextAn http or https address where the learner can get a copy. The link dialog offers it.
durationSecondsnumberThe video's length. Kotowa compares a chosen file to it and asks before linking one that differs by more than 5 seconds.

Video span

One entry of a unit entry's videos list: where the unit's own items sit in one video.

FieldTypeMeaning
videotextThe id of a video in the manifest.
startnumberThe earliest start among the unit's items, in seconds.
endnumberThe latest end, in seconds. An item without an end counts as ending where it starts.
itemCountnumberHow many of the unit's items are in this video.

Unit file

The file a unit entry's path points to.

FieldTypeMeaning
idtextSame as in the manifest.
titletextSame as in the manifest.
ordertextSame as in the manifest.
parentIdtext or nullSame as in the manifest.
daytextSame as in the manifest.
momenttextSame as in the manifest.
labeltextSame as in the manifest.
labelNotetextSame as in the manifest.
kindtextSame as in the manifest.
itemslist of itemsWhat the unit says, in reading order. Empty for a folder.

Item

An item is what the reader shows at once: one line, or several that belong together, such as a speech balloon or a subtitle cue, with one translation.

FieldTypeMeaning
idtextUnique within the unit.
speakerspeakerWho says it, see Speaker below.
lineslist of linesAt least one line, see Line below.
translationsobjectThe whole item translated: a language code mapped to text. It may be empty {} when a pack has no sentence translations.
imagetextPath of an image, from the pack's top, shown with the item. The file must be in the pack.
timingtimingWhere the item is in a video, see Timing below.

Timing

FieldTypeMeaning
videotextThe id of a video in the manifest's videos.
startnumberSeconds from the start of the video.
endnumberSeconds from the start, only when the source recorded a real end. Without it an item lasts until the next one starts.

Line

FieldTypeMeaning
sourcetextThe line in the source language. It may not be empty.
transliterationtextA reading aid in the source language's usual form, such as romaji for Japanese.
glosslist of gloss piecesThe line cut into words, each with its meaning, see Gloss piece below. Punctuation may be left out of the pieces.
furiganalist of furigana tokensThe line cut into pieces with their readings. Putting every token's text together gives source exactly.
translationsobjectThis line's own translation, for items whose lines are translated one by one, such as the options of a choice. Ordinary items are translated as a whole on the item.

Furigana token

FieldTypeMeaning
texttextA piece of the line.
readingtextIts reading, drawn above it. Only on pieces that contain kanji.

Speaker

FieldTypeMeaning
texttextThe speaker's name as the source gives it.
furiganalist of furigana tokensReadings for the name, as for a line.
tier"minor"Marks a background or one-off speaker. Kotowa treats all speakers alike.
romajitextThe name in Latin letters.
translationsobjectWhat the name means, when it is a role rather than a name.
charactertextThe id of this speaker's page in characters.json.
characterNameobjectThe character's name when text describes them instead: {"text": "…", "furigana": […]}.

Gloss piece

A gloss cuts a line into words. Only raw is needed by the app, but Kotowa draws a piece from its japanese text, so give every piece one: a line whose pieces have none is shown as plain text without the word-by-word view. The pack tool fills in the rest from the JMdict dictionary. You do not have to write these by hand: an AI agent can, see the agent guide. The facts at the end are optional and absent where they don't apply; each is an object or list whose exact shape is in the format's schema file.

FieldTypeMeaning
rawtextA label for the piece. The pack tool writes meaning (word), such as umbrella (傘). Kotowa shows it only when the piece has no japanese.
japanesetextThe piece's text in the source language.
postextPart of speech.
lemmatextThe dictionary form, when the word conjugates.
readingtextThe reading in kana.
translationsobjectThe piece's meaning per language: {"es": "regresar"}.
notetextA remark about the piece.
confidencetextconfident, uncertain or unsupported: how sure the draft is of the meaning.
lemma_kanjitextThe kanji spelling of a lemma written in kana.
word_classobjectWord class, conjugation class and transitivity.
stepslistThe conjugation steps from the dictionary form to the form in the line.
expandedtextA contraction written out in full.
attachobjectWhat the piece attaches to within its line.
registerlist of textUsage tags such as colloquial or honorific.
loanobjectThe origin of a loanword.
kanjilistOne entry for each kanji in the piece: meaning, school grade and JLPT level.
pitchlistPitch accent of the dictionary form.
freqobjectHow common the word is.
patternobjectA named grammar pattern the piece belongs to.
seenobjectHow often the word came up earlier in a long source. Only in packs that were made from one.
sourcesobjectWhere each stored fact came from and how well supported a gloss is.

A smallest pack

This is a whole pack: one unit with one line. Put the two files in a folder, with the second one at units/morning.json, and zip them.

manifest.json

{
  "id": "my-first-pack",
  "title": "My first pack",
  "sourceLanguage": "ja",
  "targetLanguages": ["en"],
  "license": "private",
  "units": [
    {
      "id": "morning",
      "title": "朝",
      "order": "0001",
      "path": "units/morning.json",
      "itemCount": 1,
      "bytes": 262,
      "mediaBytes": 0
    }
  ]
}

units/morning.json

{
  "id": "morning",
  "title": "朝",
  "order": "0001",
  "items": [
    {
      "id": "m1",
      "lines": [{ "source": "今日は雨だ。" }],
      "translations": { "en": "It is raining today." }
    }
  ]
}

Kotowa shows this pack with the line and its translation. It has no furigana or word breakdown, because those are what the pack tool adds.