> For AI agents: the complete documentation index is available at https://docs.flashnerd.com/llms.txt, the full documentation bundle is available at https://docs.flashnerd.com/llms-full.txt.

# Card records

A card belongs to a deck and stores values for that deck's fields. It may also name tags. New hand-authored cards can omit their own IDs. Ordinary packages include that deck; [cards-only imports](https://docs.flashnerd.com/reference/flashnerd-format/cards-only.md) use the selected destination's template instead.

## Location and basic example

Put one card object per physical line in any `content/cards/*.jsonl` file, such as `content/cards/notes.jsonl` or `content/cards/chapter-1.jsonl`. Filenames are arbitrary; files must be directly inside that canonical directory. Omit the collection when there are no cards.

These two complete JSONL records use the [basic Tokyo deck](https://docs.flashnerd.com/reference/flashnerd-format/decks.md#location-and-basic-example). The second also requires [the `tag-beginner` record](https://docs.flashnerd.com/reference/flashnerd-format/folders-and-tags.md#tags) and your own files at `media/cat.png` and `media/example.wav`:

```jsonl
{"deckId":"deck-tokyo","values":{"field-front":{"type":"text","value":"Sumimasen"},"field-back":{"type":"text","value":"Excuse me"}}}
{"id":"card-konichiwa","deckId":"deck-tokyo","createdAt":"2026-01-01T00:00:00Z","updatedAt":"2026-01-01T00:00:00Z","tagIds":["tag-beginner"],"values":{"field-front":{"type":"text","value":"Konnichiwa"},"field-back":{"type":"text","value":"Hello"},"field-image":{"type":"image","mediaPath":"media/cat.png"},"field-audio":{"type":"audio","mediaPath":"media/example.wav"}}}
```

The first card intentionally omits `id`, timestamps, `tagIds`, and values for the media fields. It imports as a new card with no tags and empty media fields. The second card keeps explicit dates for backup-style preservation.

### Cards-only example for Add Card

When using a selected deck's **Add Card** import, omit deck files and omit every card's `deckId`. This line assumes the selected deck already has text fields with IDs `field-front` and `field-back`:

```jsonl
{"values":{"field-front":{"type":"text","value":"Hello"},"field-back":{"type":"text","value":"Bonjour"}}}
```

Keep the destination field IDs and types from the downloaded starter. Duplicate this anonymous line for another new card; no ID editing is needed. Tags and media remain optional, but referenced tags must still be in this archive. Only cards, tags, and media are supported. A full archive with deck shards still uses the ordinary examples above. See the [cards-only contract](https://docs.flashnerd.com/reference/flashnerd-format/cards-only.md) for the starter-file workflow and validation requirements.

## Full example

Copy the runnable <a href="https://docs.flashnerd.com/examples/flashnerd-format/full/content/cards/00000.jsonl" download>content/cards/00000.jsonl</a>, or read its expanded records below. Each object occupies one physical line in the file; the formatting here is for reading.

Use these records with both [full decks](https://docs.flashnerd.com/reference/flashnerd-format/decks.md), the linked package tags, and the [image/audio files](https://docs.flashnerd.com/reference/flashnerd-format/media.md). The inherited records omit display overrides; the override records include every applicable settings property. Chinese and Japanese can retain content-specific pronunciation corrections while inheriting display settings. The linked card file also includes `card-read-line`, used by the initial-learning schedule.

### Language card inheriting its template

```json
{
  "id": "card-station",
  "deckId": "deck-japanese-travel",
  "createdAt": "2026-03-01T09:00:00.000000Z",
  "updatedAt": "2026-03-02T09:00:00.000000Z",
  "tagIds": [
    "tag-beginner",
    "tag-travel"
  ],
  "values": {
    "field-ja-word": {
      "type": "japanese",
      "value": "駅",
      "useTemplateSettings": true,
      "settings": {
        "furiganaOverrides": [
          {
            "sourceIndex": 0,
            "expectedKanji": "駅",
            "rubyOverride": "えき"
          }
        ],
        "romajiOverride": "eki",
        "pitchOverridePattern": [
          "H",
          "L"
        ]
      }
    },
    "field-ja-meaning": {
      "type": "text",
      "value": "station",
      "useTemplateSettings": true
    },
    "field-ja-audio": {
      "type": "audio",
      "mediaPath": "media/pronunciation.wav",
      "useTemplateSettings": true
    },
    "field-ja-photo": {
      "type": "image",
      "mediaPath": "media/station.png",
      "useTemplateSettings": true
    },
    "field-ja-speak": {
      "type": "tts",
      "useTemplateSettings": true
    },
    "field-zh-word": {
      "type": "chinese",
      "value": "站",
      "useTemplateSettings": true,
      "settings": {
        "pinyinOverrides": [
          {
            "tokenIndex": 0,
            "pinyin": "zhan4"
          }
        ]
      }
    },
    "field-ja-map": {
      "type": "image_occlusion",
      "mediaPath": "media/station.png",
      "occlusionRects": [
        {
          "x": 0.1,
          "y": 0.2,
          "width": 0.3,
          "height": 0.25
        },
        {
          "x": 0.6,
          "y": 0.1,
          "width": 0.2,
          "height": 0.3
        }
      ],
      "useTemplateSettings": true
    }
  }
}
```

### Language card with complete overrides

```json
{
  "id": "card-ticket",
  "deckId": "deck-japanese-travel",
  "createdAt": "2026-03-01T09:00:00.000000Z",
  "updatedAt": "2026-03-02T09:00:00.000000Z",
  "tagIds": [
    "tag-travel"
  ],
  "values": {
    "field-ja-word": {
      "type": "japanese",
      "value": "切符",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "showPitchAccent": true,
        "showFurigana": true,
        "showRomaji": true,
        "annotationSetting": "hint",
        "furiganaOverrides": [
          {
            "sourceIndex": 0,
            "expectedKanji": "切符",
            "rubyOverride": "きっぷ"
          }
        ],
        "romajiOverride": "kippu",
        "romajiType": "ascii",
        "pitchOverridePattern": [
          "L",
          "H",
          "H"
        ]
      }
    },
    "field-ja-meaning": {
      "type": "text",
      "value": "ticket",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {}
    },
    "field-ja-audio": {
      "type": "audio",
      "mediaPath": "media/pronunciation.wav",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "autoplay": true
      }
    },
    "field-ja-photo": {
      "type": "image",
      "mediaPath": "media/station.png",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": true
      },
      "settings": {}
    },
    "field-ja-speak": {
      "type": "tts",
      "value": "切符",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "autoplay": true,
        "sourceType": "manual",
        "contentSourceId": "",
        "locale": "ja-JP"
      }
    },
    "field-zh-word": {
      "type": "chinese",
      "value": "票",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "chineseType": "simplified",
        "showPinyin": true,
        "annotationSetting": "hint",
        "pinyinOverrides": [
          {
            "tokenIndex": 0,
            "pinyin": "piao4"
          }
        ]
      }
    },
    "field-ja-map": {
      "type": "image_occlusion",
      "mediaPath": "media/station.png",
      "occlusionRects": [
        {
          "x": 0.1,
          "y": 0.2,
          "width": 0.3,
          "height": 0.25
        },
        {
          "x": 0.6,
          "y": 0.1,
          "width": 0.2,
          "height": 0.3
        }
      ],
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {}
    }
  }
}
```

### Programming card inheriting its template

```json
{
  "id": "card-list-literal",
  "deckId": "deck-dart-fundamentals",
  "createdAt": "2026-03-01T09:00:00.000000Z",
  "updatedAt": "2026-03-02T09:00:00.000000Z",
  "tagIds": [
    "tag-beginner",
    "tag-programming"
  ],
  "values": {
    "field-dart-prompt": {
      "type": "text",
      "value": "Growable list literal",
      "useTemplateSettings": true
    },
    "field-dart-code": {
      "type": "code",
      "value": "final items = <String>[];",
      "useTemplateSettings": true
    },
    "field-dart-cloze": {
      "type": "cloze",
      "value": "Dart has null safety.",
      "clozeRanges": [
        {
          "start": 9,
          "end": 13
        }
      ],
      "useTemplateSettings": true
    },
    "field-dart-notes": {
      "type": "rich_text",
      "value": [
        {
          "insert": "List literal",
          "attributes": {
            "bold": true
          }
        },
        {
          "insert": " creates a growable list.\n"
        }
      ],
      "useTemplateSettings": true
    },
    "field-dart-formula": {
      "type": "tex",
      "value": "\\sum_{i=1}^{n} i = \\frac{n(n+1)}{2}",
      "useTemplateSettings": true
    }
  }
}
```

### Programming card with complete overrides

```json
{
  "id": "card-null-safety",
  "deckId": "deck-dart-fundamentals",
  "createdAt": "2026-03-01T09:00:00.000000Z",
  "updatedAt": "2026-03-02T09:00:00.000000Z",
  "tagIds": [
    "tag-programming"
  ],
  "values": {
    "field-dart-prompt": {
      "type": "text",
      "value": "Null safety",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {}
    },
    "field-dart-code": {
      "type": "code",
      "value": "String? name;",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "selectedLanguage": "dart",
        "showLineNumbers": true,
        "wrapLines": true,
        "forceDarkMode": true,
        "showLanguageHeader": true,
        "fitToContent": false,
        "minLines": 3,
        "maxLines": 12
      }
    },
    "field-dart-cloze": {
      "type": "cloze",
      "value": "Dart has null safety.",
      "clozeRanges": [
        {
          "start": 9,
          "end": 13
        }
      ],
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {}
    },
    "field-dart-notes": {
      "type": "rich_text",
      "value": [
        {
          "insert": "Nullable",
          "attributes": {
            "bold": true
          }
        },
        {
          "insert": " types use the ? suffix.\n"
        }
      ],
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {}
    },
    "field-dart-formula": {
      "type": "tex",
      "value": "\\sum_{i=1}^{n} i = \\frac{n(n+1)}{2}",
      "useTemplateSettings": false,
      "generalSettings": {
        "isHidden": false
      },
      "settings": {
        "autoSize": false
      }
    }
  }
}
```

## Record properties

| Property    | Required               | Values and default                                                                                                                                                               | Explicit `null`   |
| ----------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `id`        | No                     | Nonempty string when supplied. Omission creates a temporary source identity and always imports as a new card. See identity rules below.                                          | Invalid           |
| `deckId`    | Ordinary packages only | ID of an existing record in `content/decks/`. Must be omitted in scoped cards-only files; the selected deck supplies the destination template.                                   | Invalid           |
| `createdAt` | No                     | Timestamp with a timezone when supplied. Omission and null mean unavailable metadata.                                                                                            | Unavailable       |
| `updatedAt` | No                     | Timestamp with a timezone when supplied. Omission and null mean unavailable metadata.                                                                                            | Unavailable       |
| `tagIds`    | No                     | Array of existing tag ID strings; omission means `[]`. The default schema limit is five entries; the app keeps at most five distinct imported tags per card.                     | Invalid; use `[]` |
| `values`    | No                     | Map from this deck's field IDs to typed [card value objects](https://docs.flashnerd.com/reference/flashnerd-format/fields.md). Omission means `{}` and leaves every field empty. | Invalid           |

Extra record and nested value properties are ignored. Duplicate JSON keys remain invalid, and entries in `values` must still name actual deck field IDs. Optional timestamps have no generated default; see [timestamp syntax](https://docs.flashnerd.com/reference/flashnerd-format/package.md#timestamps-and-calendar-dates).

### Card identity

Readable IDs such as `card-konichiwa` are allowed and must be unique across all card files. Field IDs remain required even when a card omits its own `id`. Ordinary cards also require `deckId`; scoped cards-only records must omit it.

Only an **omitted** `id` requests a generated identity. `"id":null`, `"id":""`, or a non-string ID is invalid. The reader assigns a temporary source identity. It is not an ID to copy into another record's references.

That temporary identity does not enable later updates. Cards with omitted IDs always become new records, even with override-existing import. To update an existing card, keep its persisted ID from an app export. Ordinary imports remap source IDs to destination IDs.

Cards referenced by [schedules](https://docs.flashnerd.com/reference/flashnerd-format/progress-and-history.md#schedules) or [normal review history](https://docs.flashnerd.com/reference/flashnerd-format/progress-and-history.md#normal-reviews) must supply explicit IDs. Do not attempt to reconstruct a generated identity for those references. Generated source-identity metadata is not an extra JSON property.

## Values and settings

Each key in `values` is a **field ID**, not its display name. The value must be an object containing `type`, and that type must match the deck definition. There are 11 exact wire strings: `text`, `rich_text`, `image`, `cloze`, `tts`, `audio`, `image_occlusion`, `chinese`, `japanese`, `code`, and `tex`.

| Field family                                        | Value shape                                                                      | Empty form                                                                                      |
| --------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `text`, `tts`, `chinese`, `japanese`, `code`, `tex` | `{"type":"…","value":"text"}`                                                    | Omit the field, omit `value`, or set `value` to `""` or `null`.                                 |
| `rich_text`                                         | `{"type":"rich_text","value":[{"insert":"text\n"}]}`                             | Omit the field/value, or use `""`, `[]`, or `null`.                                             |
| `image`, `audio`                                    | `{"type":"…","mediaPath":"media/filename.ext"}`                                  | Omit the field/path, or set the path to `""` or `null`.                                         |
| `cloze`                                             | String `value` plus `clozeRanges:[{"start":0,"end":5}]`.                         | Omit the field, or use `value:""` and no ranges. A present cloze field requires a string value. |
| `image_occlusion`                                   | `mediaPath` plus `occlusionRects:[{"x":0.1,"y":0.2,"width":0.3,"height":0.15}]`. | Omit the field, or omit the media path and use no rectangles.                                   |

Do not put nested values, settings, Delta arrays, or masks inside a serialized JSON string. Strings containing line breaks use escaped `\n`, so the whole card remains one physical JSONL line.

Each field value inherits its template's settings by default. Set `useTemplateSettings:false` to provide card-specific general/type settings. While inheriting, only Chinese pronunciation corrections and Japanese furigana/romaji/pitch corrections are allowed. The [complete field reference](https://docs.flashnerd.com/reference/flashnerd-format/fields.md) documents every setting, default, null behavior, and override rule.

## Relationships and missing media

- In ordinary packages, `deckId` must resolve to a [deck](https://docs.flashnerd.com/reference/flashnerd-format/decks.md) in the same package. Cards-only files omit it and use the selected destination deck's template.
- Every key in `values` must resolve to a field defined by that deck, or by the supplied destination in cards-only mode. Unknown field IDs and mismatched types fail validation; omitting unused fields is valid.
- Every `tagIds` entry must resolve to a [tag](https://docs.flashnerd.com/reference/flashnerd-format/folders-and-tags.md#tags). Omit `tagIds` or use `[]` when the tags collection is absent.
- A media value points directly at an exact [media path](https://docs.flashnerd.com/reference/flashnerd-format/media.md), such as `media/cat.png`. No asset ID, hash, MIME declaration, or size declaration is needed in a card.
- If the media directory or referenced file is missing, import retains the card/field/settings with an empty media value and reports missing media. Missing image-occlusion media also clears its rectangles. Unsafe paths and present but corrupt or oversized media still fail.
- Schedules/history can refer to an explicitly identified card. Content-only imports do not require schedules or review history.

## Additional examples

This card uses the one-field `deck-cloze` shown in the [deck examples](https://docs.flashnerd.com/reference/flashnerd-format/decks.md). It hides `Tokyo` and `Japan` using sorted UTF-16 offsets. This is a complete JSONL record:

```jsonl
{"id":"card-geography","deckId":"deck-cloze","createdAt":"2026-01-01T00:00:00Z","updatedAt":"2026-01-01T00:00:00Z","values":{"field-sentence":{"type":"cloze","value":"Tokyo is in Japan.","clozeRanges":[{"start":0,"end":5},{"start":12,"end":17}]}}}
```

This complete record uses the Tokyo deck and changes audio autoplay for this card only. Other fields stay empty:

```jsonl
{"id":"card-audio-practice","deckId":"deck-tokyo","createdAt":"2026-01-01T00:00:00Z","updatedAt":"2026-01-01T00:00:00Z","values":{"field-audio":{"type":"audio","mediaPath":"media/example.wav","useTemplateSettings":false,"settings":{"autoplay":true}}}}
```

For an intentionally blank card, an empty values map is valid. Its deck still needs a valid template:

```jsonl
{"deckId":"deck-tokyo"}
```

Schemas: <a href="https://docs.flashnerd.com/examples/flashnerd-format/schemas/card.schema.json" download>ordinary card record</a>, <a href="https://docs.flashnerd.com/examples/flashnerd-format/schemas/field_value.schema.json" download>field values</a>, <a href="https://docs.flashnerd.com/examples/flashnerd-format/schemas/general_settings.schema.json" download>general settings</a>, and <a href="https://docs.flashnerd.com/examples/flashnerd-format/schemas/field_settings.schema.json" download>type settings</a>. The ordinary card schema requires `deckId` and does not describe cards-only records; those require validation against the selected destination template. Cross-record relationships and type-specific constraints are also checked by the reader.
