Deck package

A deck package is a ZIP file containing all the data related to a deck: its structure, cards, review history, and media files. Use it to back up a deck, import it somewhere else, or share it with others.

JSON files in the package mirror the corresponding API objects, with small differences detailed below.

Export a deck from its actions menu, and import a package from the import page. Importing always creates a new deck, and a package built by another tool works the same way as one exported from Recall as long as it follows this specification.

Package structure

The deck package is made of three JSON files and a folder for media files.

deck-package.zip
├── deck.json
├── cards.json
├── reviews.json
└── media/
└── ...
deck.json required

The deck's name, settings, deck fields, and card layouts.

cards.json required

The content of every card in the deck.

reviews.json optional

The review history of every card. Omit it to export a deck without its learning progress, for example when sharing it with someone else.

media optional

The audio and image files referenced from cards.json. Only required if the deck has fields of type audio or image with content, or images embedded in rich_content fields.


deck.json

The deck.json file contains the deck object, deck fields, and card layouts.

{
"format_version": 1,
"exported_at": "2025-11-30T12:34:56Z",
"name": "My deck",
"settings": {
"max_new_reviews_per_day": 10,
"target_retention": 90
},
"deck_fields": [
{ "id": "field_5gvuzRdHW2ac", "key": "french_word", "name": "French word", "type": "plain_text" },
{ "id": "field_uYS9PpONoqTP", "key": "translation", "name": "Translation", "type": "plain_text" },
{
"id": "field_pX8sR2bTq1Lm",
"key": "pronunciation",
"name": "Pronunciation",
"type": "audio",
"is_autofill_enabled": true,
"autofill_type": "text_to_speech",
"autofill_language_to": "fr-FR",
"autofill_generate_from_deck_fields": ["field_5gvuzRdHW2ac"]
}
],
"card_layouts": [
{
"id": "layout_yT9ktMcdzg4e",
"is_primary": true,
"is_active": true,
"prompt": "Say it out loud",
"card_layout_fields": [
{ "id": "layout_field_7h8j9k0l1m2n", "deck_field": "field_5gvuzRdHW2ac", "is_front": true, "order": 1 },
{ "id": "layout_field_2sdInOpM83eo", "deck_field": "field_pX8sR2bTq1Lm", "is_front": true, "order": 2, "next_to_card_layout_field": "layout_field_7h8j9k0l1m2n" },
{ "id": "layout_field_4mFq8HtNc2XZ", "deck_field": "field_uYS9PpONoqTP", "is_front": false, "order": 1 }
]
}
]
}
format_version integer required

The version of the deck package format used to write this file. Currently always 1.

exported_at string, optional

The date and time the package was generated. RFC 3339–formatted UTC datetime.

name string required

The name of the deck. Must be between 1 and 60 characters.

settings object, optional

The study settings of the deck. Default values are used for the attributes that are omitted.

max_new_reviews_per_day integer, default is 10
The maximum number of new reviews added each day. Fewer are added if many are already due.
target_retention integer, default is 90
The minimum percentage of cards of the deck the user aims to remember at any given time. Must be between 70 and 99.
deck_fields array of objects required

The fields structuring the content of the cards, like the columns of a database table. A deck must have between 2 and 30 fields.

id string required

Identifier of the field, referenced from card_layouts and from the autofill attributes of the other fields. Must be unique within the package.

key string required

Readable identifier derived from name, used as the key of the field's value in the content of the cards in cards.json. Must be unique within the package.

name string required

The name of the field. Must be between 1 and 35 characters.

type enum required

The type of the field, which determines the values it accepts in cards.json.

rich_content

Text whose values are HTML. Allowed tags: <p>, <br>, <strong>, <em>, <a>, and <img>. Embedded images are referenced with the path of their file in media.

plain_text

Text without any formatting. Formatting can be applied uniformly to the field in the card layouts.

number

Whole number (integer). Only digits are accepted.

audio

Audio that can be played in the card. Its value is a path to a file in media.

image

Image displayed in the card. Its value is a path to a file in media.

url

URL to a web page. Only valid URLs are accepted.

is_autofill_enabled boolean, default is false

Whether the AI Autofill is enabled for the field. If true, autofill_type and the attributes related to that type are required.

autofill_type nullable enum, default is null

The type of AI Autofill applied to the field.

translation

Translate the value of another field to autofill_language_to.

answer

Generate a short answer to a question contained in another field.

custom_instruction

Generate any text from one or several other fields, following the prompt set in autofill_prompt.

text_to_speech

Generate an audio from another field value, in autofill_language_to.

image_generation

Generate an image from another field value, following the prompt set in autofill_prompt.

autofill_generate_from_deck_fields array of strings, default is []

The IDs of the fields the AI Autofill generates the value from. Each ID must belong to a field of deck_fields.

autofill_language_from nullable enum, default is null

The language the text is translated from when autofill_type is translation.

af
Afrikaans
ar
Arabic
hy
Armenian
az
Azerbaijani
be
Belarusian
bs
Bosnian
bg
Bulgarian
ca
Catalan
zh
Chinese
hr
Croatian
cs
Czech
da
Danish
nl
Dutch
en
English
et
Estonian
fi
Finnish
fr
French
gl
Galician
de
German
el
Greek
he
Hebrew
hi
Hindi
hu
Hungarian
is
Icelandic
id
Indonesian
it
Italian
ja
Japanese
kn
Kannada
kk
Kazakh
ko
Korean
lv
Latvian
lt
Lithuanian
mk
Macedonian
ms
Malay
mr
Marathi
mi
Maori
ne
Nepali
no
Norwegian
fa
Persian
pl
Polish
pt
Portuguese
ro
Romanian
ru
Russian
sr
Serbian
sk
Slovak
sl
Slovenian
es
Spanish
sw
Swahili
sv
Swedish
tl
Tagalog
ta
Tamil
th
Thai
tr
Turkish
uk
Ukrainian
ur
Urdu
vi
Vietnamese
cy
Welsh
autofill_language_to nullable enum, default is null

The language the text is translated to, or the audio is generated in, when autofill_type is translation or text_to_speech.

af
Afrikaans
ar
Arabic
hy
Armenian
az
Azerbaijani
be
Belarusian
bs
Bosnian
bg
Bulgarian
ca
Catalan
zh
Chinese
hr
Croatian
cs
Czech
da
Danish
nl
Dutch
en
English
et
Estonian
fi
Finnish
fr
French
gl
Galician
de
German
el
Greek
he
Hebrew
hi
Hindi
hu
Hungarian
is
Icelandic
id
Indonesian
it
Italian
ja
Japanese
kn
Kannada
kk
Kazakh
ko
Korean
lv
Latvian
lt
Lithuanian
mk
Macedonian
ms
Malay
mr
Marathi
mi
Maori
ne
Nepali
no
Norwegian
fa
Persian
pl
Polish
pt
Portuguese
ro
Romanian
ru
Russian
sr
Serbian
sk
Slovak
sl
Slovenian
es
Spanish
sw
Swahili
sv
Swedish
tl
Tagalog
ta
Tamil
th
Thai
tr
Turkish
uk
Ukrainian
ur
Urdu
vi
Vietnamese
cy
Welsh
ar-AE
Arabic (Gulf)
ca-ES
Catalan
yue-CN
Chinese (Cantonese)
cmn-CN
Chinese (Mandarin)
cs-CZ
Czech
da-DK
Danish
nl-BE
Dutch (Belgian)
nl-NL
Dutch
en-AU
English (Australian)
en-GB
English (British)
en-IN
English (Indian)
en-IE
English (Ireland)
en-NZ
English (New Zealand)
en-SG
English (Singaporean)
en-ZA
English (South African)
en-US
English (US)
fi-FI
Finnish
fr-FR
French
fr-BE
French (Belgian)
fr-CA
French (Canadian)
hi-IN
Hindi
de-DE
German
de-AT
German (Austrian)
de-CH
German (Swiss)
it-IT
Italian
ja-JP
Japanese
ko-KR
Korean
nb-NO
Norwegian
pl-PL
Polish
pt-BR
Portuguese (Brazilian)
pt-PT
Portuguese (European)
es-ES
Spanish (Spain)
es-MX
Spanish (Mexican)
es-US
Spanish (US)
sv-SE
Swedish
tr-TR
Turkish
autofill_prompt nullable string, default is null

The prompt giving instructions to generate the value when autofill_type is custom_instruction or image_generation. Other fields are referenced by their ID, formatted as {{field_id}}.

card_layouts array of objects required

The layouts defining how the deck fields are displayed in the cards. A deck can have up to 6 layouts, and exactly one of them is primary.

id string required

Identifier of the layout, referenced from reviews.json. Must be unique within the package.

is_primary boolean, default is false

Whether the layout is the primary layout of the deck, the default one used to display its cards. Exactly one layout must be primary.

is_active boolean, default is true

Whether the layout is used to display cards in reviews. The primary layout is always active.

prompt nullable string, default is null

A short instruction displayed above the front of the card in reviews, up to 25 characters. Useful when the layout tests a non-obvious task, for example "Say it out loud".

card_layout_fields array of objects required

The fields of the layout, each displaying one deck field. A layout must have between 1 and 5 fields on its front and between 1 and 12 fields on its back. A deck field can appear at most once per layout, and all the deck fields don't have to be included.

id string required

Identifier of the layout field, referenced from next_to_card_layout_field. Must be unique within the package.

deck_field string required

The ID of the field of deck_fields to display.

is_front boolean, default is true

Whether the field is displayed on the front of the card.

order integer, optional

The position of the field within its side of the card. If omitted, it is inferred from the field's position in the array within its side.

next_to_card_layout_field nullable string, default is null

Places this field next to another field of the same layout, referenced by its ID. Only valid for an audio field placed next to a plain_text or rich_content field.

color enum, default is primary

The color of the text.

primary
Primary (highest contrast)
secondary
Secondary
tertiary
Tertiary
font_size enum, default is md

The font size of the text.

sm
Small
md
Normal
lg
Large
xl
Huge
font_weight enum, default is regular

The font weight of the text.

regular
Regular
bold
Bold

The deck object in a deck package does not contain certain attributes that are present in the API: cards_count, due_cards_count, is_paused, last_reviewed_at, next_review_at, progress, and url.


cards.json

An array of card objects.

[
{
"id": "card_lBsPlNZe4356",
"content": {
"french_word": "Bonjour",
"translation": "Hello",
"pronunciation": "media/audio_33a878e6.mp3"
}
},
{
"id": "card_2sdInOpM83eo",
"content": {
"french_word": "Merci",
"translation": "Thank you",
"pronunciation": "media/audio_e6bceb35.mp3"
}
}
]
id string required

Identifier of the card, referenced from reviews.json. Must be unique within the package.

content object required

The content of the card, as an object whose keys are the key of the fields declared in deck_fields. Each value must match the type of its field.

The values of audio and image fields are the path of their file in the media folder, relative to the root of the package. Images embedded in a rich_content field reference their file the same way, in the src attribute of their <img> tag.

The card object in a deck package differs from the API in two ways:

  • The scheduling information that lived at the card variant level is not included in the deck package (but can be recomputed from reviews.json using a spaced repetition algorithm);
  • The autofill attribute that only reflects a transient generation status is not included either.

reviews.json

An array mirroring the card review object.

Since the deck package doesn't contain explicit card variant objects, the review objects reference directly a card ID and a card layout ID.

[
{ "id": "review_8sK2mPqW3xYz", "card": "card_lBsPlNZe4356", "card_layout": "layout_yT9ktMcdzg4e", "grade": 3, "created_at": "2025-12-01T15:03:22Z" },
{ "id": "review_3xKp9QsWz4mT", "card": "card_lBsPlNZe4356", "card_layout": "layout_yT9ktMcdzg4e", "grade": 4, "created_at": "2025-12-05T09:04:00Z" }
]
id string required

Identifier of the review. Must be unique within the package.

card string required

The ID of the reviewed card, from cards.json.

card_layout string required

The ID of the card layout the card was reviewed in, from deck.json.

grade enum required

The grade given during the review, as an integer between 1 and 4.

1
Forgot.
2
Hard.
3
Good.
4
Easy.
created_at string required

The date and time the review happened. RFC 3339–formatted UTC datetime.

A deck imported without the reviews.json file starts fresh, like a newly created deck.


Media files

Media files referenced in the cards.json file need to be included in the media folder. Audio and image files are accepted, whether they are the value of an audio or image field, or an image embedded in a rich_content field.

FilesAccepted formatsMaximum size
Audiomp3, wav, ogg1MB
Imagejpg, jpeg, png, gif, webp, svg3MB

Size limitations

To be imported in Recall, a deck package must:

  • Be less than 500MB once compressed;
  • Contain no more than 5,000 cards;
  • Contain no more than 250,000 reviews.