The Lexipair wordset format

Version 1 · for your own words, phrases, pictures and sounds

A Lexipair wordset is one JSON file. Everything an item needs travels inside it: the text, its pronunciation, its translation and, if you like, a picture and a sound, written as data URLs (the binary file encoded as text). One file is all you share, back up or import: open Lexipair, tap Import, and choose the file or paste its text.

Prefer a spreadsheet? Lexipair also imports a simple CSV table. Want to start from something that works? Download the example wordset (nine words for a TV episode, with pictures).

The file at a glance

{
  "format": "lexipair-wordset",
  "version": 1,
  "wordset": {
    "id": "my-first-set",
    "name": "My first set",
    "language": "zh-CN",
    "items": [
      { "id": "w1", "text": "你好", "phonetic": "nǐ hǎo", "translation": "hello" }
    ]
  }
}

Wordset fields

Field Required Rules
id yes 1 to 64 characters, only letters, digits, ., _ and - (the pattern ^[A-Za-z0-9._-]{1,64}$). It identifies the wordset: importing a file with an id you already have asks whether to replace it (its records stay) or keep both.
name yes Not empty, at most 80 characters. Shown in the library.
language yes The language of text as a language tag: a lowercase code of 2 or 3 letters, optionally followed by - parts of 2 to 8 letters or digits, at most 35 characters. Examples: zh-CN (Mandarin, simplified), zh-TW, ja-JP, en-GB, fr. It chooses the text-to-speech voice, so be precise.
translationLanguage no The language of the translations, a language tag like language. Without it, English (en-US).
collection no At most 80 characters. Wordsets with the same collection are grouped together in the library, for example one collection per TV series.
items yes An array of 1 to 2000 items.

Item fields

Field Required Rules
id yes Not empty, at most 64 characters, unique within the wordset. Your records follow it, so keep it when you fix a typo in the text.
text yes The word or phrase being learnt, for example 咖啡. Not empty, at most 200 characters.
phonetic no How to say it, for example pinyin with tone marks kāfēi. At most 200 characters. Shown under the text when “Pinyin in word lists” is on in Settings.
translation yes The meaning in your language, for example coffee. At most 200 characters.
picture no A data URL of an image: image/svg+xml, image/png, image/jpeg or image/webp; the whole data URL at most 5 MB (5,242,880 characters). See Pictures.
sound no A data URL of a recording with any audio/… type; the whole data URL at most 10 MB (10,485,760 characters). See Sounds.
extra no An object for your own notes. Lexipair checks that it is an object, keeps it with the word and writes it back when you export. One key has a meaning: picturePrompt, a string that says what the picture shows, for example "a steaming cup of black coffee on a café table". The word's edit form shows it under the picture, ready to paste into an image AI to draw the picture again. Two more keys show on the word card, under the meaning: note, a short explanation of the word, and example, an example sentence with its own play button: { "text": …, "phonetic": …, "translation": …, "sound": … }, only text required. The example’s sound is { "dataUrl": "data:audio/…" }, a recording of the sentence; without one the sentence is spoken by the device’s voice. See Sounds.

A whole file may be up to 200 MB; above 20 MB Lexipair asks before importing, because it can be slow. Fields Lexipair does not know are ignored.

Pictures and sounds inside the JSON: data URLs

A data URL is a whole file written as text: data:, the file type, and the content. For a binary file (PNG, JPEG, WebP, MP3…) the content is base64:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA…
data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4…

Make one from a file with a single command and paste the result into the JSON:

Windows (PowerShell)

"data:image/png;base64," + [Convert]::ToBase64String([IO.File]::ReadAllBytes("$PWD\cat.png")) | Set-Clipboard

Linux

echo "data:audio/mpeg;base64,$(base64 -w0 cat.mp3)" > cat.txt

macOS

echo "data:audio/mpeg;base64,$(base64 -i cat.mp3)" | pbcopy

Or skip the commands: add pictures and recordings in Lexipair’s own editor and use Export. The exported file is this format, with every picture and sound already inside.

Pictures

"picture": "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><circle cx='32' cy='36' r='20' fill='%23e4573d' stroke='currentColor' stroke-width='3'/><path d='M32 16c0-6 4-8 8-8' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round'/></svg>"

The same idea in base64 (a water drop):

"picture": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+PHBhdGggZD0iTTMyIDhDMjIgMjQgMTYgMzIgMTYgNDBhMTYgMTYgMCAwIDAgMzIgMGMwLTgtNi0xNi0xNi0zMnoiIGZpbGw9IiMzYTg2ZDQiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4="

The picture games need enough pictures to choose from: at least 4 items with different pictures for Choose, as many as the pairs (2–4) for Pairs, and 7 for Rush.

Sounds (optional)

A complete example

Two pictured items and one without a picture. Copy it, paste it into the box on Lexipair’s Import page, tap Check pasted text, and it imports as it is. The example file is a longer one.

{
  "format": "lexipair-wordset",
  "version": 1,
  "wordset": {
    "id": "fruit-and-water",
    "name": "Fruit and water",
    "language": "zh-CN",
    "collection": "My first sets",
    "items": [
      {
        "id": "pingguo",
        "text": "苹果",
        "phonetic": "píngguǒ",
        "translation": "apple",
        "picture": "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><circle cx='32' cy='36' r='20' fill='%23e4573d' stroke='currentColor' stroke-width='3'/><path d='M32 16c0-6 4-8 8-8' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round'/></svg>"
      },
      {
        "id": "shui",
        "text": "水",
        "phonetic": "shuǐ",
        "translation": "water",
        "picture": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+PHBhdGggZD0iTTMyIDhDMjIgMjQgMTYgMzIgMTYgNDBhMTYgMTYgMCAwIDAgMzIgMGMwLTgtNi0xNi0xNi0zMnoiIGZpbGw9IiMzYTg2ZDQiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4="
      },
      {
        "id": "ni-hao",
        "text": "你好",
        "phonetic": "nǐ hǎo",
        "translation": "hello",
        "extra": { "note": "the first word of every series" }
      }
    ]
  }
}

An item with its own recording looks the same, with one more field (shortened here):

{ "id": "xie-xie", "text": "谢谢", "phonetic": "xièxie", "translation": "thank you",
  "sound": "data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4…" }

The CSV alternative

A table saved as CSV from a spreadsheet works too, one item per row. The first row names the columns:

text,phonetic,translation
咖啡,kāfēi,coffee
手机,shǒujī,mobile phone
"没关系",méi guānxi,"it's fine, no problem"

When the import says “The file is not valid”

Lexipair checks the whole file before it saves anything and lists the first ten problems, each with where it is: wordset.items[3].text is the text of the fourth item (counting from 0).

Message What it means
(file): not valid JSON (…) The text is not JSON: a missing comma or bracket, a comma after the last item, comments, curly “smart” quotes, or a sentence of an AI chat before or after the JSON. Paste only the part from { to the last }; a surrounding ```json code block is removed for you.
format: must be "lexipair-wordset" The format field is missing or misspelt.
version: must be 1 Missing, or written as a string "1".
(file): must hold either "wordset" or "wordsets" Neither or both of them are there.
wordset.id: may contain only letters, digits, ".", "_" and "-" Spaces, Chinese characters or other symbols in the wordset id.
wordset.language: must be a language tag such as zh-CN A name such as "Chinese", or an uppercase code "ZH".
….text: must be a non-empty string An item without text, or with an empty one.
….translation: is required An item without a translation.
….id: duplicates the id "w3" Two items share an id; give each its own.
….picture: must be a data URL of an SVG, PNG, JPEG or WebP image A link instead of a data URL, a missing data:image/… start, or another type such as GIF.
….sound: must be a data URL of an audio file A link, or a type that does not start with audio/.
….extra.example.sound: must be { "dataUrl": … } with a data URL of an audio file The example’s recording is a link ("url"), a bare string, or not audio/….
…: must be at most 200 characters A text, phonetic or translation that is too long (80 for names, 64 for ids).
wordset.items: must hold at least one item An empty list.
header: needs a "translation" column A CSV whose first row lacks a required column name.

Making a list for a TV series with an AI chat? The blog post Learn Chinese with the TV series you love has a ready-to-copy prompt that asks for exactly this format.