My App
LoopKitBackend

Import & Export

CSV and JSON import/export for deck portability

ImportExportService

importCSV

async importCSV(
    csv: string,
    mapping: FieldMapping,
    deckId: string,
    noteTypeId: string,
    tags?: string[],
): Promise<ImportResult>

Imports notes from CSV data. Each row becomes a note, and cards are generated for each template.

Parameters:

ParameterTypeDescription
csvstringRaw CSV content with headers
mappingFieldMappingMaps CSV column names to note field names
deckIdstringTarget deck for imported cards
noteTypeIdstringNote type to use
tagsstring[]Optional tags for all imported notes
type FieldMapping = { [csvColumn: string]: string };

Example:

const csv = `question,answer
"What is 2+2?","4"
"Capital of France?","Paris"`;

const result = await importExport.importCSV(
    csv,
    { question: 'Front', answer: 'Back' },
    'deck-id',
    'basic-type-id',
    ['imported'],
);
// { notesCreated: 2, cardsCreated: 2, errors: [] }

exportCSV

async exportCSV(deckId: string): Promise<string>

Exports all unique notes in a deck as CSV. Fields become columns, tags are joined with commas.

importJSON

async importJSON(data: LoopKitExportData): Promise<ImportResult>

Imports a full LoopKit export including presets, note types, decks, notes, cards, and optionally review logs.

exportJSON

async exportJSON(
    deckId: string,
    includeReviewLogs?: boolean,
): Promise<LoopKitExportData>

Exports a complete deck and all its descendants as JSON. Includes all related entities.

interface LoopKitExportData {
    version: string;
    exportedAt: string;
    decks: DeckBase[];
    noteTypes: NoteType[];
    notes: NoteBase[];
    cards: CardBase[];
    presets: DeckPreset[];
    reviewLogs?: ReviewLog[];
}

ImportResult

interface ImportResult {
    notesCreated: number;
    cardsCreated: number;
    errors: string[];  // Per-row errors (import continues on error)
}

Import is fault-tolerant — individual row failures are recorded in errors without aborting the import.

On this page