REST API
Lector serves an HTTP API. The web client uses it, and so does any script you write. This page lists every endpoint that a personal access token can reach. There are 100 of them.
The machine-readable description is at /openapi.json. It follows OpenAPI 3.1, so a client generator reads it directly.
The app release sets the API version. There is no version prefix in the URL. New fields arrive in the responses you already read, so read the fields you need and ignore the rest.
Base URL
- Lector Cloud:
https://app.lector.dev - Self-hosted:
http://localhost:3457, or the host you run the API on. The API answers on port 3457 by default.
Authentication
Create a token in Lector. Send it on every call.
- Open Settings, then API tokens.
- Select the scopes that the token needs.
- Copy the token. Lector shows the value once.
curl 'https://app.lector.dev/api/stats/streak' \
-H 'Authorization: Bearer $LECTOR_TOKEN'A browser session works too, because the web client calls the same endpoints. A script must use a token.
Keep the token secret. It reaches your library with the scopes that you gave it. To withdraw a token, delete it in the same screen. A token cannot create another token.
Scopes
Each endpoint below names the scope it needs. A read uses the :read scope, and a write uses the :write scope. A :* scope grants both, and * grants everything.
anki:readanki:writechat:readchat:writecollections:readcollections:writedata:exportdata:importsettings:readsettings:writestats:readstats:writevocab:readvocab:write
Some parts of Lector accept no token at all. Token management, billing, moderation and the admin console need the browser. This page leaves them out.
Languages
Lector separates your data by language. Most endpoints accept a language query parameter. Give it a language pack code, for example af, es or grc. If you omit it, the API uses the active language of the account.
Errors
An error carries a JSON body with an error string. These four apply everywhere.
| Status | Meaning |
|---|---|
401 | The credential is missing, invalid or expired. |
403 | The token does not carry the scope this endpoint needs. |
429 | A plan limit or a rate limit stopped the call. The body names the limit. |
500 | The API failed. |
Each endpoint lists the other statuses that it answers with. A 400 means that the body is not valid. A 404 means that the record does not exist, in this account and this language.
Endpoints
Select a row to read the parameters, the body and the responses.
Library
Collections, groups and lessons.
GET/api/collectionsList collections collections:read
Collections in the language, in sort order.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The account’s collections. CollectionListItem[]
Example
curl 'https://app.lector.dev/api/collections' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/collectionsCreate a collection collections:write
Request body
titlestring requiredauthorstringcoverUrlstring or nullgroupIdstring or nulllanguagestringidstring Supply your own identifier. Optional.
Responses
- 200 The new collection. CreatedId
idstring required Identifier of the new record.
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/collections' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/collections/{id}Get a collection collections:read
Path parameters
idstring required Collection identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The collection. CollectionDetail
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/collections/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/collections/{id}Update a collection collections:write
Path parameters
idstring required Collection identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
Send only the fields to change.
titlestringauthorstringcoverUrlstring or nullgroupIdstring or null
Responses
- 200 The collection is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/collections/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/collections/{id}Delete a collection collections:write
Deletes the collection, its lessons, and any audio on disk.
Path parameters
idstring required Collection identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The collection is deleted. Success
successboolean requiredtrue
Example
curl -X DELETE 'https://app.lector.dev/api/collections/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/collections/{id}/lessonsList the lessons of a collection collections:read
Path parameters
idstring required Collection identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Lessons in sort order. LessonListItem[]
idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredwordCountinteger requiredprogress_scrollPositionnumberprogress_percentCompletenumberaudioDurationMsinteger or nulltranscriptionStatusstring or null"pending" · "processing" · "done" · "error" · nulltranscriptionErrorstring or nullcreatedAtstring (date-time) requiredlastReadAtstring (date-time)
Example
curl 'https://app.lector.dev/api/collections/{id}/lessons' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/collections/{id}/lessonsAdd a lesson to a collection collections:write
Path parameters
idstring required Collection identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
titlestring requiredtextContentstring required Lesson text, as Markdown.sortOrderintegeridstring Supply your own identifier. Optional.
Responses
- 200 The new lesson. CreatedId
idstring required Identifier of the new record.
- 400 The body is malformed, or a field is not valid.
- 404 No such collection, in this account and language.
Example
curl -X POST 'https://app.lector.dev/api/collections/{id}/lessons' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'PUT/api/collections/{id}/lessons/reorderReorder the lessons of a collection collections:write
Path parameters
idstring required Collection identifier.
Request body
idsstring[] required
Responses
- 200 The new order is stored. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/collections/{id}/lessons/reorder' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'PUT/api/collections/reorderReorder collections collections:write
Send the collections of one group in their new order.
Request body
idsstring[] required
Responses
- 200 The new order is stored. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/collections/reorder' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/groupsList collection groups collections:read
Groups hold collections of every language, so the count crosses languages.
Responses
- 200 Groups in sort order. CollectionGroup[]
idstring requirednamestring requiredsortOrderinteger requiredcollectionCountinteger Collections in the group, counted across every language.createdAtstring (date-time) required
Example
curl 'https://app.lector.dev/api/groups' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/groupsCreate a group collections:write
Request body
namestring required
Responses
- 200 The new group. CreatedId
idstring required Identifier of the new record.
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/groups' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'PUT/api/groups/{id}Rename or reorder a group collections:write
Path parameters
idstring required Group identifier.
Request body
namestringsortOrderinteger
Responses
- 200 The group is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/groups/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/groups/{id}Delete a group collections:write
The collections survive. They become ungrouped.
Path parameters
idstring required Group identifier.
Responses
- 200 The group is deleted. Success
successboolean requiredtrue
Example
curl -X DELETE 'https://app.lector.dev/api/groups/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/lessons/{id}Get a lesson collections:read
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The lesson. Lesson
idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbersourceTypestring or null Origin of the text, for exampleyoutube. Null for plain Markdown.sourceMetastring or null Origin metadata, as a JSON string.segmentWordsstring or null The distinct word forms a segmenter found, as a JSON string array. Null for every spaced language.audioDurationMsinteger or nullaudioBytesinteger or nulltranscriptionStatusstring or null Transcription state of an audio lesson. Null for a text lesson."pending" · "processing" · "done" · "error" · nulltranscriptionErrorstring or nulltranscriptionAttemptsintegercreatedAtstring (date-time) requiredlastReadAtstring (date-time)
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/lessons/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/lessons/{id}Update a lesson collections:write
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
Send only the fields to change.
titlestringtextContentstringcollectionIdstring or nullsortOrderinteger
Responses
- 200 The lesson is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/lessons/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/lessons/{id}Delete a lesson collections:write
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The lesson is deleted. Success
successboolean requiredtrue
Example
curl -X DELETE 'https://app.lector.dev/api/lessons/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/lessons/{id}/audioStream the audio of a lesson collections:read
Serves the audio file. The endpoint honours the Range header and answers 206 with Content-Range, so a player can seek.
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The complete audio file. string (binary)
- 206 The requested byte range. string (binary)
- 404 The lesson has no audio, or the stored file is gone.
Example
curl 'https://app.lector.dev/api/lessons/{id}/audio' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/lessons/{id}/progressStore reading progress collections:write
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
scrollPositionnumberpercentCompletenumber
Responses
- 200 The progress is stored. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
- 404 No such record, in this account and language.
Example
curl -X PUT 'https://app.lector.dev/api/lessons/{id}/progress' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/lessons/{id}/retry-transcriptionRetry a failed transcription collections:write
Puts a failed audio lesson back in the transcription queue.
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The lesson is queued again. Success
successboolean requiredtrue
- 404 No such lesson, or its transcription did not fail.
Example
curl -X POST 'https://app.lector.dev/api/lessons/{id}/retry-transcription' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/lessons/{id}/segmentsGet the timed transcript of a lesson collections:read
Returns the audio-timed lines for listen-along. The array is empty until transcription finishes, and for text lessons.
Path parameters
idstring required Lesson identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Segments in playback order. TranscriptSegment[]
idxinteger required Position in playback order.startMsinteger requiredendMsinteger requiredtextstring required
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/lessons/{id}/segments' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Import
Bring text, EPUB, audio and video into the library.
POST/api/extract-urlExtract an article from a URL collections:write
Fetches the page and returns its readable article as Markdown. Stores nothing.
Request body
urlstring required
Responses
- 200 The extracted article. object
titlestringauthorstring or nullcontentstring The article, as Markdown.siteNamestringexcerptstring or nullwordCountinteger
- 400 The URL is not valid, or the page is too large.
Example
curl -X POST 'https://app.lector.dev/api/extract-url' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/import/audioImport an audio file collections:write
Stores the audio and creates a pending lesson. A background worker writes the transcript, so poll the lesson for transcriptionStatus.
Request body multipart/form-data
filestring (binary) required The audio file.titlestringlanguagestringgroupIdstring
Responses
- 200 The audio is stored and the transcript is queued. object
collectionIdstringlessonIdstringtitlestringaudioDurationMsinteger or nulltranscriptionStatusstring"pending"
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/import/audio' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-F 'file=@example'POST/api/import/epubImport an EPUB collections:write
Creates one collection, and one lesson per chapter.
Request body multipart/form-data
filestring (binary) required The EPUB file.languagestringgroupIdstring Put the new collection in this group.
Responses
- 200 The import finished. object
collectionIdstringtitlestringauthorstringlessonCountinteger
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/import/epub' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-F 'file=@example'POST/api/import/youtubeImport a caption track as a lesson collections:write
Request body
urlstring requiredtrackIdstring A track from the resolve call.languagestringgroupIdstring
Responses
- 200 The lesson is created. object
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/import/youtube' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/import/youtube/resolveList the caption tracks of a video collections:write
Reads the video metadata and its caption tracks. Stores nothing.
Request body
urlstring required A YouTube watch URL.
Responses
- 200 Video metadata and the available tracks. object
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/import/youtube/resolve' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'Vocabulary
Saved words and phrases, and word knowledge states.
GET/api/known-wordsGet every word knowledge state vocab:read
Returns one map for the language. The reader colours words from it.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Word to state map. KnownWordMap
<key>string How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
Example
curl 'https://app.lector.dev/api/known-words' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/known-wordsUpdate word knowledge states in bulk vocab:write
Request body
languagestringupdatesobject[] requiredwordstring requiredstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
Responses
- 200 The states are stored. object
successbooleancountinteger
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/known-words' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/vocabList saved words and phrases vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.statestring Return only entries in this state.bookIdstring Return only entries from this collection.unpushedstring Set totrueto return only entries that Anki does not hold yet.textstring Return only the entry with this exact text. Fold the word first.
Responses
- 200 Matching entries. VocabEntry[]
idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) required
Example
curl 'https://app.lector.dev/api/vocab' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/vocabSave a word or phrase vocab:write
Request body
textstring requiredtypestring"word" · "phrase"sentencestringtranslationstringstatestring How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"bookIdstring or nullchapterinteger or nulllanguagestringidstring Supply your own identifier. Optional.
Responses
- 200 The new entry. CreatedId
idstring required Identifier of the new record.
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/vocab' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/vocab/{id}Get one saved entry vocab:read
Path parameters
idstring required Vocabulary entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The entry. VocabEntry
idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) required
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/vocab/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/vocab/{id}Update a saved entry vocab:write
Path parameters
idstring required Vocabulary entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
Send only the fields to change.
textstringsentencestringtranslationstringstatestring How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"reviewCountintegerpushedToAnkiinteger0 · 1ankiNoteIdinteger or null
Responses
- 200 The entry is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
- 404 No such record, in this account and language.
Example
curl -X PUT 'https://app.lector.dev/api/vocab/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/vocab/{id}Delete a saved entry vocab:write
Path parameters
idstring required Vocabulary entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The entry is deleted. Success
successboolean requiredtrue
- 404 No such record, in this account and language.
Example
curl -X DELETE 'https://app.lector.dev/api/vocab/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Practice
Cloze practice cards and their review schedule.
GET/api/clozeList practice cards vocab:read
Cards in the language, soonest review first. Hidden cards stay out.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.collectionstring Return only cards from this bank.wordstring Return only cards that blank this exact word.limitinteger Maximum cards to return. The default is 100.
Responses
- 200 Matching cards. ClozeCard[]
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
Example
curl 'https://app.lector.dev/api/cloze' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/clozeCreate or replace practice cards vocab:write
Send one object, or an array for a batch. Every card in a batch must use one language. A card with an existing identifier is replaced.
Request body
sentencestring requiredclozeWordstring requiredclozeIndexintegertranslationstring requiredsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or nulltatoebaSentenceIdinteger or nullvocabEntryIdstring or nullmasteryLevelinteger0 · 25 · 50 · 75 · 100nextReviewstring (date-time)languagestringidstring Supply your own identifier. Optional.
Responses
- 200 One object answers with the new identifier. An array answers with the stored count. CreatedId or object
idstring required Identifier of the new record.successbooleancountinteger
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/cloze' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/cloze/{id}Get one practice card vocab:read
Path parameters
idstring required Card identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The card. ClozeCard
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/cloze/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/cloze/{id}Update a practice card vocab:write
Path parameters
idstring required Card identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
Send only the fields to change.
sentencestringclozeWordstringclozeIndexintegertranslationstringmasteryLevelinteger0 · 25 · 50 · 75 · 100nextReviewstring (date-time)reviewCountintegerlastReviewedstring or nulltimesCorrectintegertimesIncorrectintegerblacklistedinteger0 · 1
Responses
- 200 The card is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
- 404 No such record, in this account and language.
Example
curl -X PUT 'https://app.lector.dev/api/cloze/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/cloze/{id}Delete a practice card vocab:write
Path parameters
idstring required Card identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The card is deleted. Success
successboolean requiredtrue
Example
curl -X DELETE 'https://app.lector.dev/api/cloze/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/cloze/{id}/reviewRecord a practice answer vocab:write
The client owns the schedule. Send the new mastery level and the next review time with the answer.
Path parameters
idstring required Card identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
correctboolean requiredmasteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) required
Responses
- 200 The answer is recorded. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
- 404 No such record, in this account and language.
Example
curl -X POST 'https://app.lector.dev/api/cloze/{id}/review' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/cloze/countsCount cards per bank vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Totals for each bank. object
<key>objecttotalintegerdueintegermasteredinteger
Example
curl 'https://app.lector.dev/api/cloze/counts' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/cloze/dueGet the cards due for practice vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.limitinteger Maximum cards to return. The default is 20.modestringnewreturns cards with no review yet.reviewreturns seen cards that are due. Omit it for both.collectionstring Return only cards from this bank.excludeWordsstring Comma-separated words to leave out of the round.
Responses
- 200 Cards to practise, in random order. ClozeCard[]
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
Example
curl 'https://app.lector.dev/api/cloze/due' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/cloze/onboardingGet the guided first-run cards vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.vocabIdsstring required Comma-separated vocabulary identifiers. Between 1 and 20.
Responses
- 200 The cards, in the order you asked for. ClozeCard[]
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
Example
curl 'https://app.lector.dev/api/cloze/onboarding?vocabIds=VALUE' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/cloze/onboardingCreate a guided first-run card vocab:write
The identifier comes from vocabId, so a repeat call updates the same card.
Request body
vocabIdstring requiredwordstring requiredsentencestring requiredtranslationstring requiredlanguagestring required
Responses
- 200 The card already existed and is updated. ClozeCard
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
- 201 The card is created. ClozeCard
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/cloze/onboarding' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/cloze/seedCheck whether the card bank needs a seed vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Card counts, and the advice to seed. object
dbCountinteger Cards the account holds.bankSizeinteger Cards in the built-in bank.needsSeedboolean
Example
curl 'https://app.lector.dev/api/cloze/seed' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/cloze/seedSeed cards from the built-in bank vocab:write
Adds the missing cards for the language. Repeat calls are safe.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 What the seed changed. object
seededintegerupdatedintegerminedintegertatoebaintegertotalinteger
Example
curl -X POST 'https://app.lector.dev/api/cloze/seed' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/cloze/statsGet lifetime practice totals vocab:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Correct and incorrect answers, summed over every card. object
timesCorrectintegertimesIncorrectinteger
Example
curl 'https://app.lector.dev/api/cloze/stats' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Dictionary
Word lookup and the accepted-translation cache.
POST/api/dictionary/cacheAccept a translation into the dictionary vocab:write
Stores a machine translation the user accepted. Later lookups of the word answer from the cache, at no cost.
Request body
wordstring requiredlanguagestringsensesobject[] requiredpartOfSpeechstring requiredglossstring requiredipastringetymologystring
Responses
- 200 The entry is cached. object
wordstring The stored word key.
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/dictionary/cache' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/dictionary/lookupLook up a word vocab:read
Searches the built-in dictionary, its inflection tables, and the translations you accepted. A miss answers 200 with a null entry, so fall back to POST /api/translate.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.wordstring required The word to look up.
Responses
- 200 The entry, or null on a miss. object
entryDictionaryEntry or null requiredwordstring requiredrankinteger Frequency rank in the language.ipastringetymologystringsensesobject[] requiredpartOfSpeechstring requiredglossstring requiredrelatedFormsobject[]formstring requiredrelationstring requiredlemmaInfoobject Set when the lookup matched an inflected form.stemstringlabelstringsourcestringdictis the built-in dictionary.cacheis a translation you accepted."dict" · "cache"
Example
curl 'https://app.lector.dev/api/dictionary/lookup?word=VALUE' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Language help
Machine translation, explanation and speech.
POST/api/explainExplain a practice sentence vocab:read
Explains the grammar of a sentence, and why the blanked word fits.
Request body
sentencestring requiredtranslationstring requiredclozeWordstringlanguagestring
Responses
- 200 The explanation, as Markdown. object
explanationstring
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/explain' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/tatoebaSearch example sentences vocab:read
Reads the Tatoeba corpus and returns sentences with an English translation.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.querystring Search text. Omit it for random sentences.limitinteger Maximum sentences. The ceiling is 100, and the default is 20.
Responses
- 200 Matching sentences. object
sentencesobject[]idintegertextstringlangstringtranslationobjectidintegertextstringlangstring
Example
curl 'https://app.lector.dev/api/tatoeba' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/translateTranslate a word or phrase vocab:read
Asks the language model for a translation in context. Look the word up in the dictionary first: a cached hit costs nothing.
Request body
wordstring required The word or phrase. A word must be one token.typestring required"word" · "phrase"sentencestring The sentence around it. Improves the result.languagestring
Responses
- 200 A phrase returns a plain translation. A word returns a full entry. object or object
translationstringtranslationstring Every sense gloss, joined.partOfSpeechstring Part of speech of the first sense.wordstringsensesobject[]partOfSpeechstringglossstringipastringetymologystringrelatedFormsobject[]formstringrelationstring
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/translate' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/translate/enrichEnrich a word entry vocab:read
Returns pronunciation, etymology and related forms as well as the senses. The Free plan needs your own provider key for this call.
Request body
wordstring required One token.sentencestringlanguagestring
Responses
- 200 The enriched entry. object
translationstring Every sense gloss, joined.partOfSpeechstring Part of speech of the first sense.wordstringsensesobject[]partOfSpeechstringglossstringipastringetymologystringrelatedFormsobject[]formstringrelationstring
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/translate/enrich' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/translate/glossGet a short gloss for a word vocab:read
The fast path the reader uses when the dictionary misses. Returns one short meaning.
Request body
wordstring required One token.sentencestringlanguagestring
Responses
- 200 The gloss, streamed as plain text. Read the body as a stream. string
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/translate/gloss' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/ttsSynthesize speech vocab:read
Returns the audio as base64. Some language packs have no voice, and answer 404 with noAudio. Do not fall back to a browser voice for those packs.
Request body
textstring required At most 5,000 bytes.ratenumber Speaking rate. The default is 0.9.languagestring
Responses
- 200 The audio. object
audioContentstring Base64 audio.contentTypestring"audio/mp3" · "audio/wav"
- 400 The body is malformed, or a field is not valid.
- 404 The language pack has no synthesized voice.
- 503 This deployment has no voice configured. Use a local voice instead.
Example
curl -X POST 'https://app.lector.dev/api/tts' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'Journal
Written entries and their corrections.
GET/api/journalList journal entries collections:read
Query parameters
languagestring Language pack code. Defaults to the account’s active language.datestring Return only entries with this entry date.limitinteger Maximum entries. The default is 20.offsetinteger Entries to skip. The default is 0.
Responses
- 200 Matching entries. JournalEntry[]
idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsCorrection[] or null The corrections. Null before a correction runs.originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)
Example
curl 'https://app.lector.dev/api/journal' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/journalCreate a journal entry collections:write
Request body
bodystring required The text of the entry.entryDatestring Calendar date,YYYY-MM-DD.languagestring
Responses
- 200 The new entry. object
idstringentryDatestring Calendar date,YYYY-MM-DD.
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/journal' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/journal-correctCorrect text without storing it vocab:read
Corrects a piece of text and returns the result. Nothing is stored.
Request body
bodystring required The text to correct.languagestring
Responses
- 200 The correction. Nothing is stored. object
correctedBodystringcorrectionsCorrection[]originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/journal-correct' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/journal/{id}Get a journal entry collections:read
Path parameters
idstring required Entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The entry. JournalEntry
idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsCorrection[] or null The corrections. Null before a correction runs.originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)
- 404 No such record, in this account and language.
Example
curl 'https://app.lector.dev/api/journal/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/journal/{id}Update a journal entry collections:write
Path parameters
idstring required Entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
bodystring required
Responses
- 200 The entry is updated. Success
successboolean requiredtrue
- 400 The entry is already submitted, so the text is locked.
- 404 No such record, in this account and language.
Example
curl -X PUT 'https://app.lector.dev/api/journal/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/journal/{id}Delete a journal entry collections:write
Path parameters
idstring required Entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The entry is deleted. Success
successboolean requiredtrue
- 404 No such record, in this account and language.
Example
curl -X DELETE 'https://app.lector.dev/api/journal/{id}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/journal/{id}/correctCorrect a journal entry collections:write
Runs the language model over the entry, stores the corrected text, and sets the status to submitted.
Path parameters
idstring required Entry identifier.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The correction. object
correctedBodystring or nullcorrectionsCorrection[]originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
- 404 No such record, in this account and language.
Example
curl -X POST 'https://app.lector.dev/api/journal/{id}/correct' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Statistics
Daily activity, streaks and fluency estimates.
GET/api/statsList daily statistics stats:read
One row per day, oldest first. Give a date range, or a number of days.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.startDatestring First day of the range. Pair it withendDate.endDatestring Last day of the range.daysinteger Days back from today. Ignored when a range is given.
Responses
- 200 Daily rows. DailyStats[]
datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or null
Example
curl 'https://app.lector.dev/api/stats' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/stats/activityGet daily activity for the heatmap stats:read
Sums each day across every language, to match the streak.
Responses
- 200 One row per day, oldest first. object[]
datestring Calendar date,YYYY-MM-DD.dictionaryLookupsintegerclozePracticedintegerminutesReadintegerankiReviewsinteger
Example
curl 'https://app.lector.dev/api/stats/activity' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/stats/fluencyGet the fluency estimate stats:read
Counts words by state, estimates a CEFR band, and reports growth over two weeks.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The estimate. object
totalKnownWordsintegertotalLearningintegertotalNewintegerbyStateobject<key>integerbyDomainobject[] Per-domain axes for the radar chart.pendinginteger Words with no domain yet.estimatedLevelstringnextLevelstringprogressToNextLevelnumberwordsToNextLevelintegerweeklyGrowthobjectthisWeekintegerlastWeekintegerdeltainteger
Example
curl 'https://app.lector.dev/api/stats/fluency' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/stats/readingGet estimated reading volume stats:read
Derived from the scroll progress of each lesson in the language.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 Reading totals. object
wordsReadinteger Estimated words read, over every lesson.totalWordsinteger Words in the library.lessonsTotalintegerlessonsStartedintegerlessonsCompletedinteger
Example
curl 'https://app.lector.dev/api/stats/reading' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/stats/streakGet the study streak stats:read
One value for the whole account. A day counts as active after any lookup, practice, reading time or Anki review, in any language.
Responses
- 200 The streak. object
streakinteger Days in the current streak.longestintegerpracticedTodayboolean
Example
curl 'https://app.lector.dev/api/stats/streak' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/stats/todayGet the statistics for today stats:read
Creates the row for today if it does not exist. Day rollover follows the time zone setting.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The row for today. DailyStats
datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or null
Example
curl 'https://app.lector.dev/api/stats/today' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/stats/todayAdd to a counter for today stats:write
Adds amount to one counter. The call is an increment, not a set.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Request body
fieldstring required"wordsRead" · "newWordsSaved" · "wordsMarkedKnown" · "minutesRead" · "clozePracticed" · "points" · "dictionaryLookups" · "ankiReviews"amountinteger The default is 1.
Responses
- 200 The counter is updated. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/stats/today' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/study-pingCheck whether study happened today stats:read
Aggregated across every language. Built for an external agent to poll.
Responses
- 200 The activity for today. object
donebooleandatestring Calendar date,YYYY-MM-DD.minutesintegerlookupsintegerclozePracticedintegersessionStartedAtstring or null
Example
curl 'https://app.lector.dev/api/study-ping' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/study-pingRecord the start of a study session stats:write
Stores the session start time once per day, on the row of the active language.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The activity for today. object
donebooleandatestring Calendar date,YYYY-MM-DD.minutesintegerlookupsintegersessionStartedAtstring or null
Example
curl -X POST 'https://app.lector.dev/api/study-ping' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Anki
Card queue and review sync for the Anki add-on.
GET/api/ankiCheck the Anki connection anki:read
Reads the deck list through the AnkiConnect add-on. Anki must run on the same host as the API.
Responses
- 200 Connection state and decks. An unreachable Anki answers `connected: false`. object
connectedbooleanversionintegerdecksstring[]errorstring
Example
curl 'https://app.lector.dev/api/anki' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/ankiCall an allowed AnkiConnect action anki:write
Passes one allowed action to AnkiConnect. The API syncs reviews after it adds a note.
Request body
actionstring required An allowed AnkiConnect action.paramsobject
Responses
- 200 The result from AnkiConnect. object
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/anki' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/anki/ackAcknowledge created or updated notes anki:write
Marks the vocabulary entries as pushed, and clears the pending rows. Echo the version from the pull. A card queued again then survives a late acknowledgement.
Request body
resultsobject[] requiredvocabIdstring requiredankiNoteIdintegerversioninteger
Responses
- 200 How many rows the acknowledgement cleared. object
ackedinteger
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/anki/ack' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/anki/pendingPull the pending card batch anki:read
Returns one batch, and how many rows remain. Loop the pull, the write and the acknowledgement until the queue is empty.
Responses
- 200 The batch, and the rows that remain after it. object
pendingobject[]lectorIdstring The vocabulary entry identifier.cardTypestring"basic" · "word" · "cloze"wordstring or nullsentencestring or nulltranslationstring or nullmeaningstring or nulllanguagestringsourceUrlstring or nullclipStartMsinteger or nullclipEndMsinteger or nullqueuedAtstring (date-time)versioninteger Echo it back on the acknowledgement.remaininginteger Advisory count, for progress output.
Example
curl 'https://app.lector.dev/api/anki/pending' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/anki/queueQueue vocabulary as Anki cards anki:write
Adds pending cards for the add-on to pull. A second call for the same entry replaces its pending row.
Request body
itemsobject[] requiredvocabIdstring requiredcardTypestring"basic" · "word" · "cloze"wordstring or nullsentencestring or nulltranslationstring or nullmeaningstring or nullsourceUrlstring or null Video URL, for a card mined from a transcript.clipStartMsinteger or nullclipEndMsinteger or null
Responses
- 200 How many cards the queue took, and how many it refused. object
queuedintegerfailedinteger
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/anki/queue' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/anki/reviewsReport reviews from the add-on anki:write
Raises the word state from the Anki review history. The endpoint never lowers a state, and never changes ignored.
Request body
Send reviews, reviewsByDay, or an inventory.
reviewsobject[]typestringintervalnumberreviewsByDayobject[]datestring Calendar date,YYYY-MM-DD.countintegerinventoryobject The notes the add-on holds.
Responses
- 200 What the report changed. object
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/anki/reviews' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/anki/sync-reviewsSync the daily review counts from Anki anki:write
Reads the review counts through AnkiConnect and stores them, so the heatmap and the streak count Anki days. An unreachable Anki leaves the stored data alone.
Responses
- 200 What the sync changed. object
Example
curl -X POST 'https://app.lector.dev/api/anki/sync-reviews' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Settings
Account preferences and provider configuration.
GET/api/byokGet the provider key state settings:read
Reports whether this deployment accepts your own provider key, and which key the account holds.
Responses
- 200 The state. object
availableboolean True when the deployment accepts a key.enabledboolean True when the account holds a key.providerstringmodelstringprovidersobject Each provider, and the models it allows.
Example
curl 'https://app.lector.dev/api/byok' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/byokStore your own provider key settings:write
Validates the key against the provider, then stores it. Send the key only. The API never reads it back.
Request body
providerstring"anthropic" · "openrouter"apiKeystring At most 512 characters.modelstring A model the provider catalog lists.
Responses
- 200 The key is stored. object
enabledbooleanproviderstringmodelstring
- 400 The body is malformed, or a field is not valid.
- 503 This deployment does not accept your own key.
Example
curl -X PUT 'https://app.lector.dev/api/byok' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/byokDelete your provider key settings:write
Responses
- 200 The key is deleted. object
enabledbooleanfalse
Example
curl -X DELETE 'https://app.lector.dev/api/byok' \
-H 'Authorization: Bearer $LECTOR_TOKEN'GET/api/llm-statusCheck the language model provider settings:read
Reports the provider, the model, and the result of a health check.
Responses
- 200 Provider health. object
providerstringmodelstringokboolean
Example
curl 'https://app.lector.dev/api/llm-status' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/llm-status/resetClear the cached provider settings:write
Call this after a provider setting changes, so the next call builds a new client.
Responses
- 200 The cache is clear. object
okboolean
Example
curl -X POST 'https://app.lector.dev/api/llm-status/reset' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/llm-status/testSend a test completion settings:write
Asks the provider for one tiny completion. The call spends monthly allowance.
Responses
- 200 The provider answered. object
okbooleanresponsestring
Example
curl -X POST 'https://app.lector.dev/api/llm-status/test' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/llm/openai/modelsList the models of an OpenAI-compatible endpoint chat:write
Asks the endpoint for its model list, from the server. Self-hosted deployments only. Cloud answers 404.
Request body
endpointstring required Base URL of the endpoint.apiKeystring Omit it to use the stored key.
Responses
- 200 The models. object
modelsobject[]
- 400 The body is malformed, or a field is not valid.
- 404 Not available on this deployment.
- 502 The endpoint refused the call.
Example
curl -X POST 'https://app.lector.dev/api/llm/openai/models' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/settingsGet every setting settings:read
Returns one object, keyed by setting name. A credential reads back as true, never as its value.
Responses
- 200 The settings of the account. object
Example
curl 'https://app.lector.dev/api/settings' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/settingsWrite settings in bulk settings:write
Writes every pair in the body. The API rejects the whole batch if one key is unknown, so a bad call changes nothing.
Request body
Setting name to value. Only the listed names are accepted.
Responses
- 200 The settings are stored. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/settings' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/settings/{key}Get one setting settings:read
Returns the value, or null when the account has no such setting.
Path parameters
keystring required Setting name.
Responses
- 200 The value. A credential reads back as `true`. any
Example
curl 'https://app.lector.dev/api/settings/{key}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PUT/api/settings/{key}Write one setting settings:write
Path parameters
keystring required Setting name.
Request body
valueany required Any JSON value.
Responses
- 200 The setting is stored. Success
successboolean requiredtrue
- 400 The body is malformed, or a field is not valid.
Example
curl -X PUT 'https://app.lector.dev/api/settings/{key}' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/settings/{key}Delete one setting settings:write
Path parameters
keystring required Setting name.
Responses
- 200 The setting is deleted. Success
successboolean requiredtrue
Example
curl -X DELETE 'https://app.lector.dev/api/settings/{key}' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Data
Export and restore the account’s learning data.
GET/api/dataExport the learning data data:export
Returns every portable record for the account. Credentials, billing state and cached shared content stay out.
Responses
- 200 The export. UserExport
formatstring required"lector-learning-data"versioninteger required1exportedAtstring (date-time) requiredcollectionsCollection[]idstring requiredtitlestring requiredauthorstring requiredcoverUrlstring or nullgroupIdstring or null Group that holds the collection.languagestringsortOrderinteger requiredcreatedAtstring (date-time) requiredlastReadAtstring (date-time) requiredcollectionGroupsCollectionGroup[]idstring requirednamestring requiredsortOrderinteger requiredcollectionCountinteger Collections in the group, counted across every language.createdAtstring (date-time) requiredlessonsLessonExport[]idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbercreatedAtstring (date-time) requiredlastReadAtstring (date-time)vocabVocabEntry[]idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) requiredknownWordsobject[]wordstringlanguagestringstatestring How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"domainstring or null Topic the classifier assigned.clozeSentencesClozeCard[]idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1journalEntriesJournalEntryExport[]idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsstring or null The corrections, as a JSON string.statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)dailyStatsDailyStats[]datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or nullacceptedDictionaryEntriesobject[]learnerProfilesobject[]onboardingProgressobject[]learnerEventsobject[]settingsobject[] Only the portable pair:targetLanguageandtimezone.keystringvaluestring
Example
curl 'https://app.lector.dev/api/data' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/dataRestore learning data data:import
Writes the records of an export into the account. The restored rows become yours, whatever the file says. One restore runs at a time.
Request body
formatstring required"lector-learning-data"versioninteger required1exportedAtstring (date-time) requiredcollectionsCollection[]idstring requiredtitlestring requiredauthorstring requiredcoverUrlstring or nullgroupIdstring or null Group that holds the collection.languagestringsortOrderinteger requiredcreatedAtstring (date-time) requiredlastReadAtstring (date-time) requiredcollectionGroupsCollectionGroup[]idstring requirednamestring requiredsortOrderinteger requiredcollectionCountinteger Collections in the group, counted across every language.createdAtstring (date-time) requiredlessonsLessonExport[]idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbercreatedAtstring (date-time) requiredlastReadAtstring (date-time)vocabVocabEntry[]idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) requiredknownWordsobject[]wordstringlanguagestringstatestring How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"domainstring or null Topic the classifier assigned.clozeSentencesClozeCard[]idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1journalEntriesJournalEntryExport[]idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsstring or null The corrections, as a JSON string.statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)dailyStatsDailyStats[]datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or nullacceptedDictionaryEntriesobject[]learnerProfilesobject[]onboardingProgressobject[]learnerEventsobject[]settingsobject[] Only the portable pair:targetLanguageandtimezone.keystringvaluestring
Responses
- 200 The restore finished. `imported` counts the rows per table. object
successbooleanimportedobject<key>integer
- 400 The body is malformed, or a field is not valid.
- 409 A restore is already running for the account.
- 503 The restore capacity is busy. Try again shortly.
Example
curl -X POST 'https://app.lector.dev/api/data' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'Chat
Conversation practice with the language model.
GET/api/chatGet the conversation history chat:read
Returns messages oldest first. Page back with before.
Query parameters
languagestring Language pack code. Defaults to the account’s active language.limitinteger Maximum messages. The default is 50.beforestring (date-time) Return messages created before this time. Use it to page back.
Responses
- 200 The messages. object[]
idstringrolestring"user" · "assistant"contentstringproviderstring or nullresponseIdstring or nulllanguagestringcreatedAtstring (date-time)
Example
curl 'https://app.lector.dev/api/chat' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/chatSend a chat message chat:write
Sends the message to the language model and returns the answer. The Free plan answers without storing the history.
Request body
messagestring required At most 32 KiB.languagestring
Responses
- 200 Both messages of the exchange. object
userMessageobjectassistantMessageobject
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/chat' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'DELETE/api/chatClear the conversation history chat:write
Query parameters
languagestring Language pack code. Defaults to the account’s active language.
Responses
- 200 The history is deleted. object
okboolean
Example
curl -X DELETE 'https://app.lector.dev/api/chat' \
-H 'Authorization: Bearer $LECTOR_TOKEN'Onboarding
Guided first-run state and starter content.
POST/api/learner-eventsRecord a learner event stats:write
Stores one product analytics event for the account. Send an idempotencyKey to make a retry safe.
Request body
eventTypestring required"onboarding.started" · "onboarding.profile_saved" · "onboarding.skipped" · "lesson.opened" · "reader.term_looked_up" · "vocab.saved" · "vocab.state_changed" · "practice.answer_submitted" · "practice.round_completed" · "onboarding.completed"languagestring requiredlessonIdstring or null Required forlesson.opened.vocabIdstring or null Required for the twovocab.*events.propertiesobjectidempotencyKeystring or null
Responses
- 200 The event is a repeat, so nothing changed. object
- 201 The event is recorded. object
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/learner-events' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'GET/api/onboardingGet the guided first-run state stats:read
Returns the profile, the current step, and the recommended lesson. An account with a language but no row is an existing user.
Responses
- 200 The state. OnboardingSnapshot
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
Example
curl 'https://app.lector.dev/api/onboarding' \
-H 'Authorization: Bearer $LECTOR_TOKEN'PATCH/api/onboardingAdvance the guided first run stats:write
Request body
currentStepstring"reader" · "practice" · "summary"nextLessonIdstringnextLessonTitlestring
Responses
- 200 The new state. OnboardingSnapshot
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
- 400 The body is malformed, or a field is not valid.
- 409 The guided first run has not started.
Example
curl -X PATCH 'https://app.lector.dev/api/onboarding' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/onboarding/completeFinish the guided first run stats:write
Responses
- 200 The new state. OnboardingSnapshot
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
- 409 The guided first run has not started.
Example
curl -X POST 'https://app.lector.dev/api/onboarding/complete' \
-H 'Authorization: Bearer $LECTOR_TOKEN'POST/api/onboarding/skipSkip the guided first run stats:write
Stores the profile and the target language, then marks the run skipped.
Request body
languagestring requiredapproximateLevelstring required"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[] required Supported interest names.dailyMinutesinteger required
Responses
- 200 The new state. OnboardingSnapshot
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/onboarding/skip' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'POST/api/onboarding/startStart the guided first run stats:write
Stores the learner profile and picks a starter lesson.
Request body
languagestring requiredapproximateLevelstring required"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[] required Supported interest names.dailyMinutesinteger required
Responses
- 200 The new state. OnboardingSnapshot
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
- 400 The body is malformed, or a field is not valid.
Example
curl -X POST 'https://app.lector.dev/api/onboarding/start' \
-H 'Authorization: Bearer $LECTOR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ ... }'Service
Health and deployment information.
GET/healthCheck that the service runs no token
Answers without a credential. Reports the deployment mode.
Responses
- 200 The service runs. object
okbooleanmodestring"selfhost" · "cloud"
Example
curl 'https://app.lector.dev/health'Objects
The records that the endpoints above return and accept.
Collection A book, course or folder of lessons in one language. These are the stored fields, and the data takeout carries exactly these.
idstring requiredtitlestring requiredauthorstring requiredcoverUrlstring or nullgroupIdstring or null Group that holds the collection.languagestringsortOrderinteger requiredcreatedAtstring (date-time) requiredlastReadAtstring (date-time) required
CollectionListItem
CollectionDetail
CollectionGroup A container for collections. Groups hold every language.
idstring requirednamestring requiredsortOrderinteger requiredcollectionCountinteger Collections in the group, counted across every language.createdAtstring (date-time) required
Lesson One readable text, and its audio when the source carried audio.
idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbersourceTypestring or null Origin of the text, for exampleyoutube. Null for plain Markdown.sourceMetastring or null Origin metadata, as a JSON string.segmentWordsstring or null The distinct word forms a segmenter found, as a JSON string array. Null for every spaced language.audioDurationMsinteger or nullaudioBytesinteger or nulltranscriptionStatusstring or null Transcription state of an audio lesson. Null for a text lesson."pending" · "processing" · "done" · "error" · nulltranscriptionErrorstring or nulltranscriptionAttemptsintegercreatedAtstring (date-time) requiredlastReadAtstring (date-time)
LessonListItem A lesson as the collection listing returns it. The text stays out, so fetch the lesson itself to read it.
idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredwordCountinteger requiredprogress_scrollPositionnumberprogress_percentCompletenumberaudioDurationMsinteger or nulltranscriptionStatusstring or null"pending" · "processing" · "done" · "error" · nulltranscriptionErrorstring or nullcreatedAtstring (date-time) requiredlastReadAtstring (date-time)
TranscriptSegment One timed line of an audio transcript.
idxinteger required Position in playback order.startMsinteger requiredendMsinteger requiredtextstring required
VocabEntry A word or phrase the account saved, with the sentence it came from.
idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) required
KnownWordMap Every rated word in the language, as a word to state map.
<key>string How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
ClozeCard A practice sentence with one word blanked out, plus its review schedule.
idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1
DailyStats One day of activity in one language.
datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or null
Correction One correction that the language model made to a journal entry.
originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
JournalEntry A piece of writing in the target language, and its correction.
idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsCorrection[] or null The corrections. Null before a correction runs.originalstring The wrong word or phrase.correctedstringexplanationstring Why the original is wrong.typestring"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)
DictionaryEntry A dictionary result for one word.
wordstring requiredrankinteger Frequency rank in the language.ipastringetymologystringsensesobject[] requiredpartOfSpeechstring requiredglossstring requiredrelatedFormsobject[]formstring requiredrelationstring requiredlemmaInfoobject Set when the lookup matched an inflected form.stemstringlabelstringsourcestringdictis the built-in dictionary.cacheis a translation you accepted."dict" · "cache"
OnboardingSnapshot The guided first-run state of the account.
progressobject or null Null before the account starts or skips the guided first run.versionintegerstatusstring"in_progress" · "completed" · "skipped"currentStepstring"reader" · "practice" · "summary"languagestringstarterCollectionIdstring or nullrecommendedLessonIdstring or nullrecommendedLessonTitlestring or nullnextLessonIdstring or nullnextLessonTitlestring or nullstartedAtstring (date-time)completedAtstring or nullupdatedAtstring (date-time)profileobject or nulllanguagestringapproximateLevelstring"new" · "beginner" · "intermediate" · "advanced" · "not_sure"interestsstring[]dailyMinutesintegercreatedAtstring (date-time)updatedAtstring (date-time)eventsLearnerEvent[] The learner events since the guided first run started.idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
LearnerEvent One recorded product analytics event.
idstringeventTypestringlanguagestringlessonIdstring or nullvocabIdstring or nullpropertiesobjectidempotencyKeystring or nulloccurredAtstring (date-time)
LessonExport A lesson as the data takeout carries it. The text travels, and the audio and transcription state stay behind.
idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbercreatedAtstring (date-time) requiredlastReadAtstring (date-time)
JournalEntryExport A journal entry as the data takeout carries it. `corrections` stays a JSON string here, while the journal endpoints parse it.
idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsstring or null The corrections, as a JSON string.statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)
UserExport Every portable learning record for the account.
formatstring required"lector-learning-data"versioninteger required1exportedAtstring (date-time) requiredcollectionsCollection[]idstring requiredtitlestring requiredauthorstring requiredcoverUrlstring or nullgroupIdstring or null Group that holds the collection.languagestringsortOrderinteger requiredcreatedAtstring (date-time) requiredlastReadAtstring (date-time) requiredcollectionGroupsCollectionGroup[]idstring requirednamestring requiredsortOrderinteger requiredcollectionCountinteger Collections in the group, counted across every language.createdAtstring (date-time) requiredlessonsLessonExport[]idstring requiredcollectionIdstring or nulltitlestring requiredsortOrderinteger requiredtextContentstring required The lesson text, as Markdown.wordCountinteger requiredlanguagestringprogress_scrollPositionnumberprogress_percentCompletenumbercreatedAtstring (date-time) requiredlastReadAtstring (date-time)vocabVocabEntry[]idstring requiredtextstring requiredtypestring required"word" · "phrase"sentencestring Sentence that held the word.translationstringstatestring required How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"stateUpdatedAtstring (date-time)reviewCountintegerbookIdstring or null Collection the word came from.chapterinteger or nulllanguagestring requiredpushedToAnkiinteger0 · 1ankiNoteIdinteger or nullcreatedAtstring (date-time) requiredknownWordsobject[]wordstringlanguagestringstatestring How well the account knows a word.level1tolevel4are the learning steps betweennewandknown.ignoredhides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"domainstring or null Topic the classifier assigned.clozeSentencesClozeCard[]idstring requiredsentencestring requiredclozeWordstring required The word the learner must supply.clozeIndexinteger required Position of the blanked word in the sentence, counted in words.translationstringlanguagestringsourcestring"tatoeba" · "mined"collectionstring"top500" · "top1000" · "top2000" · "mined" · "random"wordRankinteger or null Frequency rank of the blanked word.tatoebaSentenceIdinteger or nullvocabEntryIdstring or null Vocabulary entry the card was mined from.masteryLevelinteger required0 · 25 · 50 · 75 · 100nextReviewstring (date-time) requiredlastReviewedstring or nullreviewCountintegertimesCorrectintegertimesIncorrectintegerblacklistedinteger 1 hides the card.0 · 1journalEntriesJournalEntryExport[]idstring requiredbodystring requiredcorrectedBodystring or nullcorrectionsstring or null The corrections, as a JSON string.statusstring required"draft" · "submitted"wordCountinteger requiredlanguagestring requiredentryDatestring required Calendar date,YYYY-MM-DD.createdAtstring (date-time)updatedAtstring (date-time)dailyStatsDailyStats[]datestring required Calendar date,YYYY-MM-DD.languagestringwordsReadintegernewWordsSavedintegerwordsMarkedKnownintegerminutesReadintegerclozePracticedintegerpointsintegerdictionaryLookupsintegerankiReviewsintegersessionStartedAtstring or nullacceptedDictionaryEntriesobject[]learnerProfilesobject[]onboardingProgressobject[]learnerEventsobject[]settingsobject[] Only the portable pair:targetLanguageandtimezone.keystringvaluestring
Generated clients
To get a typed client, point a generator at /openapi.json. This command writes a TypeScript client into ./lector-client.
npx @openapitools/openapi-generator-cli generate \
-i https://lector.dev/openapi.json \
-g typescript-fetch \
-o ./lector-clientDoes this page disagree with the API? Tell us on the support page. The document comes straight out of the route table, so a wrong description is a bug that we can fix.