Documentation

Contents Features Overview Getting Started Managing Decks Adding Words Importing Words Reviewing Cards Tracking Progress Understanding FSRS Details The FSRS Algorithm Why FSRS How FSRS Works FSRS vs SM-2 (Anki) Benchmark Results Import & Export Deck Sharing Settings & API Keys Admin & User Management Account Security REST API Reference Authentication Endpoints Roles Error Responses AI Word Generation Workflow Prompt Template Structure Import Methods Keyboard Shortcuts

Features Overview

FlashVocab is a self-hosted spaced repetition app for vocabulary learning, powered by the FSRS algorithm — the most accurate open-source scheduling algorithm available today. Here's what you can do:

CategoryFeatures
Spaced RepetitionFSRS algorithm, 4-grade rating system (Again/Hard/Good/Easy), keyboard shortcuts, review filters by tag/state/mode, progress bar, session timer, interval previews
Deck ManagementCreate language decks with source/target language config, edit, duplicate (resets FSRS state), delete with cascade, share with other users (read-only)
Word ManagementAdd single or batch, import via paste JSON or file upload, search & filter by tag/state, edit, delete, duplicate detection, FSRS details per word
Import & ExportJSON import/export per deck, FSRS state preservation, tag-filtered export, import modal on Words & Decks pages, tags input on import, SuperMemo migration
Analytics30-day retention rate, daily review chart, 7-day due forecast, session timer & history, study time totals, cards/session metrics, total reviews
Multi-UserRole-based access (user, api_user, admin), admin panel for user CRUD, deck sharing by email (read-only), account lockout after 3 failed attempts
API & AI Integration30+ REST endpoints, API key auth for scripts/AI, machine-readable /api/spec, one-click key copy, batch API for AI word generation
SecurityJWT with httpOnly cookies, API keys (SHA256 hashed), bcrypt passwords, 8-char min length, account lockout, role-based permissions

Getting Started

After logging in, you'll be redirected to the Decks page. Select or create a deck, then start adding words and reviewing.

  1. Create a deck — click "New Deck", enter a name and choose source/target languages (e.g., Spanish to Polish).
  2. Add words — go to the Words page and click "+ Add Word", or use the batch API.
  3. Review — go to the Review page. FSRS schedules cards at the optimal moment for retention.
  4. Track progress — the Stats page shows retention rate, daily reviews, due forecast, and session history.

Managing Decks

The Decks page is your home screen. It shows all your decks in a grid layout with word counts, due badges, and action buttons.

ActionDescription
New DeckCreate a deck with a name, description, and source/target language pair (e.g., Spanish → Polish)
Select & StudySets the deck as active and redirects to the Review page. The active deck name appears in the nav bar
ImportOpens the import modal to paste JSON or upload a file directly into that deck
ShareShare the deck with another user by email. They get read-only access
EditChange the deck name, description, or language settings
DuplicateCreates a copy of the deck with all words. FSRS scheduling state is reset (all words start as New)
DeletePermanently removes the deck and all its words. This cannot be undone

The nav bar shows a deck selector dropdown — you can switch between decks from any page without going back to the Decks page. All pages (Review, Words, Stats) are scoped to the active deck.

Due badge: Each deck card shows how many cards are due for review. An orange badge appears when cards are due, helping you prioritize which decks to study.

Adding Words

Navigate to the Words page to manage your vocabulary. You can add words one at a time or in batch via the API.

Each word can include:

Duplicate detection: If you add a word that already exists in the deck (case-insensitive match), you'll see a warning with the option to "Add Anyway" or cancel.

Search and filter: Use the search box to find words by text, the tag dropdown to filter by tag, and the state dropdown to show only New, Learning, Review, or Relearning cards.

Importing Words

FlashVocab provides an Import button on both the Words page and each deck card on the Decks page. Click it to open the import modal.

The import modal has two tabs:

Word fields (strict validation)

The import modal performs strict field validation. Only the following field names are accepted — any unknown fields will be rejected with an error showing the allowed fields:

FieldRequiredDescription
wordYesThe vocabulary word (e.g., "hola")
translationYesThe translation (e.g., "czesc")
example_sentenceNoAn example sentence using the word
example_translationNoTranslation of the example sentence
tagsNoComma-separated tags (e.g., "travel,A2")

Example JSON:

[
  {
    "word": "Disparar",
    "translation": "To skyrocket",
    "example_sentence": "Lidl dispara su beneficio en España.",
    "example_translation": "Lidl's profit is skyrocketing in Spain.",
    "tags": "business,B2"
  }
]

Common mistakes: Using definition instead of translation, context instead of example_sentence, or camelCase names like exampleSentence. The validation will catch these and show you the correct field names.

Both tabs accept two JSON formats:

Tags on import: Enter comma-separated tags in the "Tags to apply" field. These tags are applied to any imported words that don't already have tags set in the JSON. Words that already have tags in the JSON keep their original tags.

Duplicate handling: After importing, you'll see:

  1. How many words were successfully created
  2. A list of any duplicates that were skipped (case-insensitive match on the word text)
  3. An "Import anyway" button to force-add the duplicates as separate entries

Typical use cases:

Reviewing Cards

The Review page is the core of the app. Cards appear one at a time: you see the word, reveal the answer, then grade yourself.

  1. A card appears showing the word only.
  2. Press Space or click the card to reveal the answer (translation + example).
  3. Grade yourself using one of four buttons (or keys 1-4).
  4. FSRS calculates the optimal next review date based on your grade.
  5. The next card loads automatically. When all due cards are done, you'll see "All caught up!"

Grade meanings

GradeKeyMeaningEffect on scheduling
Again1Forgot the wordReset to short interval, increases lapse count
Hard2Recalled with difficultyShorter next interval than normal
Good3Recalled correctlyNormal interval increase
Easy4Recalled effortlesslyLarger interval increase

Review filters: Before starting, you can filter by tags, state (New/Learning/Review), or mode (Due only vs. all cards).

Tracking Progress

The Stats page shows comprehensive learning analytics for the active deck.

Key Metrics

MetricWhat it tells you
Total WordsTotal vocabulary in the active deck
Due NowCards overdue for review — this is the number you see on each deck's badge
Reviewed TodayHow many cards you've reviewed in today's sessions
Retention (30d)Percentage of reviews where you answered correctly (not "Again") over the last 30 days. This is your memory accuracy
New / Learning / ReviewCard counts by FSRS state: New (never reviewed), Learning (in initial reviews), Review (graduated to long intervals)

Study Time Analytics

The Stats page tracks how much time you spend studying:

Sessions are tracked automatically. The Review page starts a timer when you begin, and saves the session when you finish or leave the page.

Charts

Interpreting Your Retention Rate

Understanding FSRS Details

Click the "Details" button on any word in the Words page to see its FSRS memory metrics. Here's what each metric means:

MetricDescription
StateThe card's current phase: New (never reviewed), Learning (first reviews), Review (graduated, on long intervals), or Relearning (forgotten, being re-learned).
StabilityHow long your memory lasts, measured in days. At exactly stability days after a review, you have a 90% chance of remembering the word. Higher stability = stronger memory.
DifficultyHow hard this card is for you personally, on a 0-10 scale. Higher values mean the card is harder and gets shorter intervals. Unlike SM-2, difficulty uses mean reversion — it naturally decreases after consecutive correct answers.
RetrievabilityThe probability that you can recall this word right now, shown as a percentage. It starts at ~100% right after a review and decays over time following the forgetting curve. FSRS schedules reviews when this drops to ~90%.
ReviewsTotal number of times you've reviewed this card.
LapsesNumber of times you forgot the card (graded "Again" after it had graduated to Review state). More lapses = the card is a "leech" that needs extra attention.
Last reviewedWhen you last reviewed this card.
Next dueWhen FSRS has scheduled the next review.
Scheduled intervalThe gap in days between the last review and the next due date.

The FSRS Algorithm

Why FSRS

FlashVocab uses FSRS (Free Spaced Repetition Scheduler) — the most accurate open-source spaced repetition algorithm available today. Created by Jarrett Ye and backed by peer-reviewed research published at ACM KDD 2022 and IEEE TKDE 2023, FSRS represents a generational leap over the 37-year-old SM-2 algorithm still used as Anki's default.

The core promise: FSRS achieves 20-30% fewer reviews than SM-2 at the same retention rate, or higher retention with the same number of reviews. This is validated across 727 million reviews from 10,000 users in the largest spaced repetition benchmark ever conducted.

How FSRS Works

FSRS models human memory using three core variables:

VariableSymbolDescription
DifficultyDHow hard is this card to remember? Range: 1-10. Updated after each review.
StabilitySHow well is the memory stored? Measured in days — the time until retrievability drops to 90%.
RetrievabilityRWhat's the probability of recall right now? Decreases over time from 100% toward 0%.

These three variables (the DSR model) work together to determine when to schedule each card. After each review, FSRS recalculates stability based on your grade:

Before review: Stability = 10 days New Stability +-------+ ============= Rating 1: | Again | ------> 2 days (forgot — reset lower) Rating 2: | Hard | ------> 18 days (struggled) Rating 3: | Good | ------> 25 days (correct — normal growth) Rating 4: | Easy | ------> 45 days (effortless — big jump)

The forgetting curve: FSRS models forgetting as a power function — more accurate than the exponential decay used by older algorithms. Your retrievability decreases over time after each review:

Retrievability over time (Stability = 10 days) 100% |* | ** 90% |---**------------ <- Review scheduled here (R = 90%) | *** 80% | *** | **** 70% | ***** | ****** 60% | ******** | ************** 50% | **** +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--> 0 5 10 15 20 25 30 35 40 days

Key insight: The harder the card is for you specifically, the shorter the interval. The easier, the longer. This is personalized per card based on your review history.

FSRS vs SM-2 (Anki)

SM-2 was created in 1987. It's simple but has fundamental limitations by modern standards.

FeatureSM-2 (Anki default)FSRS (FlashVocab)
Created19872022
Memory modelSingle "ease factor"3-variable DSR model
Forgetting curveNot modeled at allExplicitly modeled (power function)
PersonalizationNone — same formula for everyone21 parameters optimized per user
Trainable parameters021
Desired retentionFixed (~90%, not configurable)Configurable (70%-97%)
After forgettingReset to 1 day, ease drops 20%Calculated post-lapse stability
"Ease hell"Yes — cards get permanently stuckNo — mean reversion prevents it
Interval calculationFixed multiplier: interval * easeDerived from predicted retrievability
Review efficiencyBaseline20-30% fewer reviews at same retention

The "Ease Hell" problem in SM-2: Once a card's ease factor drops to the minimum (130%), it never recovers with normal use. The card appears too frequently, wasting your time forever. FSRS solves this with mean reversion — after consecutive correct answers, difficulty naturally decreases back toward baseline.

FSRS vs Other Tools

ToolAlgorithmCostFSRS Advantage
AnkiSM-2 (FSRS opt-in since 2023)FreeFlashVocab uses FSRS by default, no configuration needed
SuperMemoSM-18/19 (proprietary)PaidFSRS is open-source, free, and cross-platform
DuolingoHLR (Half-Life Regression)FreemiumFSRS dramatically outperforms HLR (log loss 0.34 vs 0.47)
MnemosyneModified SM-2FreeSame SM-2 disadvantages as Anki
QuizletNo spaced repetitionFreemiumNo adaptive scheduling at all

Benchmark Results

From the open-spaced-repetition benchmark — the largest SRS evaluation ever conducted (727 million reviews, 10,000 users):

Algorithm Accuracy Ranking (Log Loss — lower is better) ======================================================== RWKV-P (neural net) |############ | 0.277 (requires thousands of parameters) LSTM (neural net) |############## | 0.333 FSRS-7 (21 params) |############## | 0.341 <-- Best practical algorithm FSRS-6 |############### | 0.346 FSRS-5 |################ | 0.356 GRU (neural net) |################## | 0.375 Duolingo HLR |########################| 0.469 Ebisu v2 |#########################| 0.499 0.25 0.35 0.45 0.50 FSRS-6 outperforms SM-2 on 99.6% of all tested user collections.

What this means in practice:

Import & Export

Go to Settings to import and export words for the active deck.

Export

Downloads all words from the active deck as a JSON file, including FSRS scheduling state. You can optionally filter by tag using the dropdown before clicking Export.

Import

Select a JSON file to import words. The import flow includes duplicate detection:

  1. Words that already exist in the deck (case-insensitive match) are skipped by default and listed.
  2. If duplicates are found, you'll see an "Import duplicates anyway" button to add them as separate entries.
  3. Words without FSRS data are imported as new cards. Words with FSRS data (from a previous export) retain their scheduling state.

Deck Sharing

You can share your decks with other FlashVocab users. Shared users get read-only access to view the deck and its words.

How to share a deck

  1. Go to the Decks page
  2. Click the Share button on any deck you own
  3. Enter the email address of the user you want to share with
  4. The deck will appear in their deck list marked as a shared deck

What shared users can do

ActionAllowed?
View deck and word listYes
Search and filter wordsYes
Add, edit, or delete wordsNo
Review cardsNo
Import wordsNo
Delete or modify the deckNo

The deck owner can unshare at any time by clicking the share button again and removing the user. Sharing is per-user — each user must be added individually.

Use cases: Teachers sharing vocabulary lists with students, study groups using the same word sets, or creating a "master deck" for new users to reference.

Settings & API Keys

The Settings page provides account management and programmatic access.

API Keys

API keys allow external tools (scripts, AI assistants like Claude or ChatGPT) to read and write words and decks programmatically.

  1. Click "Generate Key" and enter an optional label
  2. The raw key is shown — click Copy to copy it to your clipboard, or Show to reveal it
  3. Use in HTTP requests: Authorization: Bearer sk_your_key_here
  4. Keys can be revoked at any time

Note: Only users with the api_user or admin role can create API keys. If you don't see the API Keys section, ask your admin to grant you the api_user role.

API keys can read/write words and decks but cannot perform destructive operations (deck delete, password change) or access review/stats endpoints — those require browser login.

Change Password

Enter your current password and a new password (minimum 8 characters) to update your login credentials.

Import / Export (Settings page)

The Settings page also provides import/export for the active deck, with optional tag filtering on export. This is in addition to the Import modal available on the Words and Decks pages.

Admin & User Management

Admins can manage user accounts from the Admin page, accessible via Settings > User Management.

ActionDescription
Create userSet display name, email, initial password, and roles
Edit userChange name, email, roles, or status (active/inactive/locked)
Reset passwordSet a new password for any user (minimum 8 characters)
Delete userPermanently remove the user and all their data (decks, words, reviews). Cannot delete yourself
Unlock accountChange a locked user's status back to "active" after failed login lockout

Roles

Each user can have one or more roles. Roles control what features are available:

RoleWhat it grants
userOwn decks, add/review words, view stats, change password
api_userEverything user can do, plus create and use API keys for programmatic access
adminFull access: user management, all features, API keys

Users can have multiple roles at once (e.g., user + api_user).

Account Security

FlashVocab includes several security measures to protect your account and data:

REST API Reference

FlashVocab exposes 30+ REST endpoints for programmatic access. You can use these from scripts, AI assistants, or external tools.

Authentication

All endpoints (except login and /api/spec) require authentication. Two methods are supported:

Endpoints marked JWT only require browser login — API keys are not accepted for destructive operations (deck delete, password change) or review/stats endpoints.

API Spec (Machine-Readable)

Fetch /api/spec (no auth required) to get a compact JSON description of every endpoint, including auth requirements, request bodies, query parameters, and response shapes. This is designed for LLMs and AI tools to discover the API programmatically.

Endpoints

Auth

MethodEndpointAuthDescription
POST/api/auth/loginNoneLogin with { email, password }
POST/api/auth/logoutNoneClear session cookie
GET/api/auth/meJWT onlyGet current user info. Returns { userId, username, email, roles }
PUT/api/auth/passwordJWT onlyChange password { currentPassword, newPassword } (min 8 chars)

Admin

All admin endpoints require JWT with the admin role.

MethodEndpointAuthDescription
GET/api/admin/usersJWT (admin)List all users
POST/api/admin/usersJWT (admin)Create user { username, email, password, roles? }. Password min 8 chars. Roles is a string array, default ["user"]
PUT/api/admin/users/:idJWT (admin)Update user { roles?, status?, email?, username? }
PUT/api/admin/users/:id/passwordJWT (admin)Reset user password { password } (min 8 chars)
DELETE/api/admin/users/:idJWT (admin)Delete user and all their data. Cannot delete self

Roles: Users can have multiple roles stored as an array: admin, user, api_user. The admin role grants access to user management. The api_user role (or admin) allows creating API keys.

Decks

MethodEndpointAuthDescription
GET/api/decksJWT or KeyList all decks with word_count and due_count
GET/api/decks/:idJWT or KeyGet deck with detailed stats
POST/api/decksJWT or KeyCreate deck { name, description?, source_lang?, target_lang? }
PUT/api/decks/:idJWT or KeyUpdate deck fields
DELETE/api/decks/:idJWT onlyDelete deck and all its words (cascade)
POST/api/decks/:id/duplicateJWT or KeyDuplicate deck with all words (FSRS state reset)

Deck Sharing

MethodEndpointAuthDescription
GET/api/decks/:id/sharesJWT or KeyList users a deck is shared with (owner only)
POST/api/decks/:id/sharesJWT or KeyShare deck with user { email } (owner only). Returns 404 if user not found, 409 if already shared
DELETE/api/decks/:id/shares/:userIdJWT or KeyUnshare deck with user (owner only)

Words

All list/create operations require deck_id parameter.

MethodEndpointAuthDescription
GET/api/words?deck_id=NJWT or KeyList words (paginated). Optional: search, tags, state, page, limit
GET/api/words/:idJWT or KeyGet single word by ID
POST/api/wordsJWT or KeyCreate word { deck_id, word, translation, ... }. Returns 409 on duplicate
POST/api/words/batchJWT or KeyBatch create { deck_id, words: [...] }. Skips duplicates by default
PUT/api/words/:idJWT or KeyUpdate word fields
DELETE/api/words/:idJWT or KeyDelete word

Review

MethodEndpointAuthDescription
GET/api/review?deck_id=NJWT onlyGet due cards. Optional: tags, state, mode, limit
GET/api/review/tags?deck_id=NJWT onlyGet all tags used in this deck
POST/api/review/:idJWT onlyGrade a card { rating: 1|2|3|4 }

Statistics

MethodEndpointAuthDescription
GET/api/stats?deck_id=NJWT onlyFull statistics for the deck
POST/api/stats/sessionJWT onlySave study session { started_at, ended_at, duration_ms, cards_reviewed?, deck_id? }

Import / Export

MethodEndpointAuthDescription
POST/api/importJWT onlyImport words { words: [...], deck_id }. Skips duplicates by default
GET/api/export?deck_id=NJWT onlyExport words as JSON. Optional tags filter

API Keys

MethodEndpointAuthDescription
GET/api/keysJWT onlyList all API keys
POST/api/keysJWT onlyGenerate new key { label? }. Returns raw key (shown once)
DELETE/api/keys/:idJWT onlyRevoke an API key

Roles

Each user can have one or more roles, returned as a roles array in the JWT and API responses:

RoleCapabilities
userOwn decks, review, settings. No API keys, no user management
api_userSame as user + can create and use API keys
adminFull access: manage users, own decks, review, API keys

Multiple roles can be assigned (e.g. ["user", "api_user"]). Roles are stored as comma-separated values in the database and exposed as arrays in the API.

Error Responses

All errors return JSON with an error field, e.g. { "error": "deck_id is required" }

StatusMeaning
400Bad request (missing/invalid parameters)
401Unauthorized (missing or invalid credentials)
403Forbidden (insufficient permissions, e.g., non-admin accessing admin routes, or writing to a read-only shared deck)
404Resource not found
409Conflict (duplicate word exists)
500Server error

AI Word Generation

FlashVocab is designed to work with AI assistants (Claude, ChatGPT, etc.) for generating vocabulary words. AI-generated words can be imported into FlashVocab in two ways:

  1. Automated — give the AI your API key and it calls the API directly. No manual steps needed.
  2. Manual — the AI generates JSON, and you paste or upload it into the app using the Import button.

Workflow

  1. Pick your import method — decide if you want the AI to call the API directly (needs an API key) or just generate JSON for you to paste/upload.
  2. Copy the prompt template below and paste it into your AI assistant.
  3. Edit the configuration — set your source/target language, deck ID, topics, and difficulty level.
  4. Run it — the AI generates vocabulary words.
  5. Import — either the AI imports automatically, or you use one of the manual methods below.

Tip: You can also tell the AI to fetch /api/spec first so it discovers the API format automatically:

"Fetch https://flashvocab.app/api/spec to understand the API, then generate 20 Spanish-Polish vocabulary words about travel."

Prompt Template Structure

Copy and edit the template below. The AI will output JSON ready for import. Replace YOUR_DECK_ID with your actual deck ID — you can find it on the Decks page or by calling GET /api/decks.

First, fetch the API spec to understand the exact format:
GET https://flashvocab.app/api/spec

Generate vocabulary words in this JSON structure:

{
  "deck_id": YOUR_DECK_ID,
  "words": [
    {
      "word": "el almuerzo",
      "translation": "obiad (lunch)",
      "example_sentence": "Vamos a tomar el almuerzo juntos.",
      "example_translation": "Zjedzmy razem obiad.",
      "tags": "food,A2"
    }
  ]
}

Configuration (edit these):
- Source language: Spanish (es)
- Target language: Polish (pl)
- Deck ID: YOUR_DECK_ID (find via Decks page or GET /api/decks)
- Words per tag: 15
- Difficulty level: A2-B1

Tags/topics to generate:
- travel
- food
- daily-routine
- work
- health

Quality guidelines:
1. Words: use natural form (infinitive for verbs, singular for nouns with article)
2. Translations: most common translation in target language
3. Example sentences: natural, everyday (8-15 words)
4. Example translations: natural, not word-for-word
5. Tags: topic tag + CEFR level (A1,A2,B1,B2), comma-separated
6. No duplicates across tags
7. Mix nouns, verbs, adjectives, and common phrases

Import Methods

After the AI generates the words, choose one of these methods to get them into FlashVocab:

Method A — Fully automated (AI + API key):

Give the AI your API key and endpoint URL. It calls POST /api/words/batch directly — no manual steps needed.

"Fetch https://flashvocab.app/api/spec, then generate and import 20 Spanish-Polish
words about travel into deck YOUR_DECK_ID using API key sk_YOUR_API_KEY"

The AI will handle everything: generate the words, format the JSON, and POST it to the API. You can find your API key in Settings > API Keys (click Copy to copy it).

Method B — Copy-paste into FlashVocab:

  1. Ask the AI to generate the JSON payload (without an API key).
  2. Go to the Words page or Decks page and click the Import button.
  3. Switch to the Paste JSON tab.
  4. Paste the AI's JSON output into the textarea and click Import.

Duplicates are automatically detected and listed. You can click "Import anyway" to add them as separate entries.

Method C — Upload a JSON file:

  1. Save the AI's output to a .json file.
  2. Go to Words or Decks page → click Import.
  3. Use the Upload File tab to select your file, then click Import.

Same duplicate handling as the paste method. Both { "words": [...] } and bare array [...] formats are accepted.

Method D — curl (advanced):

# Import from file using API key
curl -X POST https://flashvocab.app/api/words/batch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk_YOUR_API_KEY" \
  -d @words.json

The batch endpoint returns { created, ids, duplicates }. Duplicates are skipped by default — pass "allow_duplicates": true in the JSON to override.

Keyboard Shortcuts

KeyContextAction
Space / EnterReviewReveal the answer
1Review (answer shown)Grade as Again
2Review (answer shown)Grade as Hard
3Review (answer shown)Grade as Good
4Review (answer shown)Grade as Easy

GitHub Repository — source code and issue tracker.