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.

  1. Open Settings, then API tokens.
  2. Select the scopes that the token needs.
  3. 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:read
  • anki:write
  • chat:read
  • chat:write
  • collections:read
  • collections:write
  • data:export
  • data:import
  • settings:read
  • settings:write
  • stats:read
  • stats:write
  • vocab:read
  • vocab: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.

StatusMeaning
401The credential is missing, invalid or expired.
403The token does not carry the scope this endpoint needs.
429A plan limit or a rate limit stopped the call. The body names the limit.
500The 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

  • language string 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

  • title string required
  • author string
  • coverUrl string or null
  • groupId string or null
  • language string
  • id string Supply your own identifier. Optional.

Responses

  • 200 The new collection. CreatedId
    • id string 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

  • id string required Collection identifier.

Query parameters

  • language string 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

  • id string required Collection identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

Send only the fields to change.

  • title string
  • author string
  • coverUrl string or null
  • groupId string or null

Responses

  • 200 The collection is updated. Success
    • success boolean 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

  • id string required Collection identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The collection is deleted. Success
    • success boolean 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

  • id string required Collection identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Lessons in sort order. LessonListItem[]
    • id string required
    • collectionId string or null
    • title string required
    • sortOrder integer required
    • wordCount integer required
    • progress_scrollPosition number
    • progress_percentComplete number
    • audioDurationMs integer or null
    • transcriptionStatus string or null"pending" · "processing" · "done" · "error" · null
    • transcriptionError string or null
    • createdAt string (date-time) required
    • lastReadAt string (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

  • id string required Collection identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

  • title string required
  • textContent string required Lesson text, as Markdown.
  • sortOrder integer
  • id string Supply your own identifier. Optional.

Responses

  • 200 The new lesson. CreatedId
    • id string 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

  • id string required Collection identifier.

Request body

  • ids string[] required

Responses

  • 200 The new order is stored. Success
    • success boolean 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

  • ids string[] required

Responses

  • 200 The new order is stored. Success
    • success boolean 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[]
    • id string required
    • name string required
    • sortOrder integer required
    • collectionCount integer Collections in the group, counted across every language.
    • createdAt string (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

  • name string required

Responses

  • 200 The new group. CreatedId
    • id string 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

  • id string required Group identifier.

Request body

  • name string
  • sortOrder integer

Responses

  • 200 The group is updated. Success
    • success boolean 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

  • id string required Group identifier.

Responses

  • 200 The group is deleted. Success
    • success boolean 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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The lesson. Lesson
    • id string required
    • collectionId string or null
    • title string required
    • sortOrder integer required
    • textContent string required The lesson text, as Markdown.
    • wordCount integer required
    • language string
    • progress_scrollPosition number
    • progress_percentComplete number
    • sourceType string or null Origin of the text, for example youtube. Null for plain Markdown.
    • sourceMeta string or null Origin metadata, as a JSON string.
    • segmentWords string or null The distinct word forms a segmenter found, as a JSON string array. Null for every spaced language.
    • audioDurationMs integer or null
    • audioBytes integer or null
    • transcriptionStatus string or null Transcription state of an audio lesson. Null for a text lesson."pending" · "processing" · "done" · "error" · null
    • transcriptionError string or null
    • transcriptionAttempts integer
    • createdAt string (date-time) required
    • lastReadAt string (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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

Send only the fields to change.

  • title string
  • textContent string
  • collectionId string or null
  • sortOrder integer

Responses

  • 200 The lesson is updated. Success
    • success boolean 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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The lesson is deleted. Success
    • success boolean 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

  • id string required Lesson identifier.

Query parameters

  • language string 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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

  • scrollPosition number
  • percentComplete number

Responses

  • 200 The progress is stored. Success
    • success boolean 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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The lesson is queued again. Success
    • success boolean 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

  • id string required Lesson identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Segments in playback order. TranscriptSegment[]
    • idx integer required Position in playback order.
    • startMs integer required
    • endMs integer required
    • text string 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

  • url string required

Responses

  • 200 The extracted article. object
    • title string
    • author string or null
    • content string The article, as Markdown.
    • siteName string
    • excerpt string or null
    • wordCount integer
  • 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

  • file string (binary) required The audio file.
  • title string
  • language string
  • groupId string

Responses

  • 200 The audio is stored and the transcript is queued. object
    • collectionId string
    • lessonId string
    • title string
    • audioDurationMs integer or null
    • transcriptionStatus string"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

  • file string (binary) required The EPUB file.
  • language string
  • groupId string Put the new collection in this group.

Responses

  • 200 The import finished. object
    • collectionId string
    • title string
    • author string
    • lessonCount integer
  • 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

  • url string required
  • trackId string A track from the resolve call.
  • language string
  • groupId string

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

  • url string 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

  • language string 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. level1 to level4 are the learning steps between new and known. ignored hides 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

  • language string
  • updates object[] required
  • word string required
  • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"

Responses

  • 200 The states are stored. object
    • success boolean
    • count integer
  • 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

  • language string Language pack code. Defaults to the account’s active language.
  • state string Return only entries in this state.
  • bookId string Return only entries from this collection.
  • unpushed string Set to true to return only entries that Anki does not hold yet.
  • text string Return only the entry with this exact text. Fold the word first.

Responses

  • 200 Matching entries. VocabEntry[]
    • id string required
    • text string required
    • type string required"word" · "phrase"
    • sentence string Sentence that held the word.
    • translation string
    • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
    • stateUpdatedAt string (date-time)
    • reviewCount integer
    • bookId string or null Collection the word came from.
    • chapter integer or null
    • language string required
    • pushedToAnki integer0 · 1
    • ankiNoteId integer or null
    • createdAt string (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

  • text string required
  • type string"word" · "phrase"
  • sentence string
  • translation string
  • state string How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • bookId string or null
  • chapter integer or null
  • language string
  • id string Supply your own identifier. Optional.

Responses

  • 200 The new entry. CreatedId
    • id string 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

  • id string required Vocabulary entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The entry. VocabEntry
    • id string required
    • text string required
    • type string required"word" · "phrase"
    • sentence string Sentence that held the word.
    • translation string
    • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
    • stateUpdatedAt string (date-time)
    • reviewCount integer
    • bookId string or null Collection the word came from.
    • chapter integer or null
    • language string required
    • pushedToAnki integer0 · 1
    • ankiNoteId integer or null
    • createdAt string (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

  • id string required Vocabulary entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

Send only the fields to change.

  • text string
  • sentence string
  • translation string
  • state string How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • reviewCount integer
  • pushedToAnki integer0 · 1
  • ankiNoteId integer or null

Responses

  • 200 The entry is updated. Success
    • success boolean 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

  • id string required Vocabulary entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The entry is deleted. Success
    • success boolean 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

  • language string Language pack code. Defaults to the account’s active language.
  • collection string Return only cards from this bank.
  • word string Return only cards that blank this exact word.
  • limit integer Maximum cards to return. The default is 100.

Responses

  • 200 Matching cards. ClozeCard[]
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 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

  • sentence string required
  • clozeWord string required
  • clozeIndex integer
  • translation string required
  • source string"tatoeba" · "mined"
  • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
  • wordRank integer or null
  • tatoebaSentenceId integer or null
  • vocabEntryId string or null
  • masteryLevel integer0 · 25 · 50 · 75 · 100
  • nextReview string (date-time)
  • language string
  • id string Supply your own identifier. Optional.

Responses

  • 200 One object answers with the new identifier. An array answers with the stored count. CreatedId or object
    • id string required Identifier of the new record.
    • success boolean
    • count integer
  • 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

  • id string required Card identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The card. ClozeCard
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 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

  • id string required Card identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

Send only the fields to change.

  • sentence string
  • clozeWord string
  • clozeIndex integer
  • translation string
  • masteryLevel integer0 · 25 · 50 · 75 · 100
  • nextReview string (date-time)
  • reviewCount integer
  • lastReviewed string or null
  • timesCorrect integer
  • timesIncorrect integer
  • blacklisted integer0 · 1

Responses

  • 200 The card is updated. Success
    • success boolean 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

  • id string required Card identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The card is deleted. Success
    • success boolean 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

  • id string required Card identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

  • correct boolean required
  • masteryLevel integer required0 · 25 · 50 · 75 · 100
  • nextReview string (date-time) required

Responses

  • 200 The answer is recorded. Success
    • success boolean 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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Totals for each bank. object
    • <key> object
    • total integer
    • due integer
    • mastered integer

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

  • language string Language pack code. Defaults to the account’s active language.
  • limit integer Maximum cards to return. The default is 20.
  • mode string new returns cards with no review yet. review returns seen cards that are due. Omit it for both.
  • collection string Return only cards from this bank.
  • excludeWords string Comma-separated words to leave out of the round.

Responses

  • 200 Cards to practise, in random order. ClozeCard[]
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 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

  • language string Language pack code. Defaults to the account’s active language.
  • vocabIds string required Comma-separated vocabulary identifiers. Between 1 and 20.

Responses

  • 200 The cards, in the order you asked for. ClozeCard[]
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 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

  • vocabId string required
  • word string required
  • sentence string required
  • translation string required
  • language string required

Responses

  • 200 The card already existed and is updated. ClozeCard
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 1 hides the card.0 · 1
  • 201 The card is created. ClozeCard
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Card counts, and the advice to seed. object
    • dbCount integer Cards the account holds.
    • bankSize integer Cards in the built-in bank.
    • needsSeed boolean

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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 What the seed changed. object
    • seeded integer
    • updated integer
    • mined integer
    • tatoeba integer
    • total integer

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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Correct and incorrect answers, summed over every card. object
    • timesCorrect integer
    • timesIncorrect integer

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

  • word string required
  • language string
  • senses object[] required
  • partOfSpeech string required
  • gloss string required
  • ipa string
  • etymology string

Responses

  • 200 The entry is cached. object
    • word string 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

  • language string Language pack code. Defaults to the account’s active language.
  • word string required The word to look up.

Responses

  • 200 The entry, or null on a miss. object
    • entry DictionaryEntry or null required
    • word string required
    • rank integer Frequency rank in the language.
    • ipa string
    • etymology string
    • senses object[] required
    • partOfSpeech string required
    • gloss string required
    • relatedForms object[]
    • form string required
    • relation string required
    • lemmaInfo object Set when the lookup matched an inflected form.
    • stem string
    • label string
    • source string dict is the built-in dictionary. cache is 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

  • sentence string required
  • translation string required
  • clozeWord string
  • language string

Responses

  • 200 The explanation, as Markdown. object
    • explanation string
  • 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

  • language string Language pack code. Defaults to the account’s active language.
  • query string Search text. Omit it for random sentences.
  • limit integer Maximum sentences. The ceiling is 100, and the default is 20.

Responses

  • 200 Matching sentences. object
    • sentences object[]
    • id integer
    • text string
    • lang string
    • translation object
    • id integer
    • text string
    • lang string

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

  • word string required The word or phrase. A word must be one token.
  • type string required"word" · "phrase"
  • sentence string The sentence around it. Improves the result.
  • language string

Responses

  • 200 A phrase returns a plain translation. A word returns a full entry. object or object
    • translation string
    • translation string Every sense gloss, joined.
    • partOfSpeech string Part of speech of the first sense.
    • word string
    • senses object[]
    • partOfSpeech string
    • gloss string
    • ipa string
    • etymology string
    • relatedForms object[]
    • form string
    • relation string
  • 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

  • word string required One token.
  • sentence string
  • language string

Responses

  • 200 The enriched entry. object
    • translation string Every sense gloss, joined.
    • partOfSpeech string Part of speech of the first sense.
    • word string
    • senses object[]
    • partOfSpeech string
    • gloss string
    • ipa string
    • etymology string
    • relatedForms object[]
    • form string
    • relation string
  • 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

  • word string required One token.
  • sentence string
  • language string

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

  • text string required At most 5,000 bytes.
  • rate number Speaking rate. The default is 0.9.
  • language string

Responses

  • 200 The audio. object
    • audioContent string Base64 audio.
    • contentType string"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

  • language string Language pack code. Defaults to the account’s active language.
  • date string Return only entries with this entry date.
  • limit integer Maximum entries. The default is 20.
  • offset integer Entries to skip. The default is 0.

Responses

  • 200 Matching entries. JournalEntry[]
    • id string required
    • body string required
    • correctedBody string or null
    • corrections Correction[] or null The corrections. Null before a correction runs.
    • original string The wrong word or phrase.
    • corrected string
    • explanation string Why the original is wrong.
    • type string"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
    • status string required"draft" · "submitted"
    • wordCount integer required
    • language string required
    • entryDate string required Calendar date, YYYY-MM-DD.
    • createdAt string (date-time)
    • updatedAt string (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

  • body string required The text of the entry.
  • entryDate string Calendar date, YYYY-MM-DD.
  • language string

Responses

  • 200 The new entry. object
    • id string
    • entryDate string 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

  • body string required The text to correct.
  • language string

Responses

  • 200 The correction. Nothing is stored. object
    • correctedBody string
    • corrections Correction[]
    • original string The wrong word or phrase.
    • corrected string
    • explanation string Why the original is wrong.
    • type string"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

  • id string required Entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The entry. JournalEntry
    • id string required
    • body string required
    • correctedBody string or null
    • corrections Correction[] or null The corrections. Null before a correction runs.
    • original string The wrong word or phrase.
    • corrected string
    • explanation string Why the original is wrong.
    • type string"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
    • status string required"draft" · "submitted"
    • wordCount integer required
    • language string required
    • entryDate string required Calendar date, YYYY-MM-DD.
    • createdAt string (date-time)
    • updatedAt string (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

  • id string required Entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Request body

  • body string required

Responses

  • 200 The entry is updated. Success
    • success boolean 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

  • id string required Entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The entry is deleted. Success
    • success boolean 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

  • id string required Entry identifier.

Query parameters

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The correction. object
    • correctedBody string or null
    • corrections Correction[]
    • original string The wrong word or phrase.
    • corrected string
    • explanation string Why the original is wrong.
    • type string"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

  • language string Language pack code. Defaults to the account’s active language.
  • startDate string First day of the range. Pair it with endDate.
  • endDate string Last day of the range.
  • days integer Days back from today. Ignored when a range is given.

Responses

  • 200 Daily rows. DailyStats[]
    • date string required Calendar date, YYYY-MM-DD.
    • language string
    • wordsRead integer
    • newWordsSaved integer
    • wordsMarkedKnown integer
    • minutesRead integer
    • clozePracticed integer
    • points integer
    • dictionaryLookups integer
    • ankiReviews integer
    • sessionStartedAt string 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[]
    • date string Calendar date, YYYY-MM-DD.
    • dictionaryLookups integer
    • clozePracticed integer
    • minutesRead integer
    • ankiReviews integer

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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The estimate. object
    • totalKnownWords integer
    • totalLearning integer
    • totalNew integer
    • byState object
    • <key> integer
    • byDomain object[] Per-domain axes for the radar chart.
    • pending integer Words with no domain yet.
    • estimatedLevel string
    • nextLevel string
    • progressToNextLevel number
    • wordsToNextLevel integer
    • weeklyGrowth object
    • thisWeek integer
    • lastWeek integer
    • delta integer

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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 Reading totals. object
    • wordsRead integer Estimated words read, over every lesson.
    • totalWords integer Words in the library.
    • lessonsTotal integer
    • lessonsStarted integer
    • lessonsCompleted integer

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
    • streak integer Days in the current streak.
    • longest integer
    • practicedToday boolean

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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The row for today. DailyStats
    • date string required Calendar date, YYYY-MM-DD.
    • language string
    • wordsRead integer
    • newWordsSaved integer
    • wordsMarkedKnown integer
    • minutesRead integer
    • clozePracticed integer
    • points integer
    • dictionaryLookups integer
    • ankiReviews integer
    • sessionStartedAt string 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

  • language string Language pack code. Defaults to the account’s active language.

Request body

  • field string required"wordsRead" · "newWordsSaved" · "wordsMarkedKnown" · "minutesRead" · "clozePracticed" · "points" · "dictionaryLookups" · "ankiReviews"
  • amount integer The default is 1.

Responses

  • 200 The counter is updated. Success
    • success boolean 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
    • done boolean
    • date string Calendar date, YYYY-MM-DD.
    • minutes integer
    • lookups integer
    • clozePracticed integer
    • sessionStartedAt string 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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The activity for today. object
    • done boolean
    • date string Calendar date, YYYY-MM-DD.
    • minutes integer
    • lookups integer
    • sessionStartedAt string 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
    • connected boolean
    • version integer
    • decks string[]
    • error string

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

  • action string required An allowed AnkiConnect action.
  • params object

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

  • results object[] required
  • vocabId string required
  • ankiNoteId integer
  • version integer

Responses

  • 200 How many rows the acknowledgement cleared. object
    • acked integer
  • 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
    • pending object[]
    • lectorId string The vocabulary entry identifier.
    • cardType string"basic" · "word" · "cloze"
    • word string or null
    • sentence string or null
    • translation string or null
    • meaning string or null
    • language string
    • sourceUrl string or null
    • clipStartMs integer or null
    • clipEndMs integer or null
    • queuedAt string (date-time)
    • version integer Echo it back on the acknowledgement.
    • remaining integer 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

  • items object[] required
  • vocabId string required
  • cardType string"basic" · "word" · "cloze"
  • word string or null
  • sentence string or null
  • translation string or null
  • meaning string or null
  • sourceUrl string or null Video URL, for a card mined from a transcript.
  • clipStartMs integer or null
  • clipEndMs integer or null

Responses

  • 200 How many cards the queue took, and how many it refused. object
    • queued integer
    • failed integer
  • 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.

  • reviews object[]
  • type string
  • interval number
  • reviewsByDay object[]
  • date string Calendar date, YYYY-MM-DD.
  • count integer
  • inventory object 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
    • available boolean True when the deployment accepts a key.
    • enabled boolean True when the account holds a key.
    • provider string
    • model string
    • providers object 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

  • provider string"anthropic" · "openrouter"
  • apiKey string At most 512 characters.
  • model string A model the provider catalog lists.

Responses

  • 200 The key is stored. object
    • enabled boolean
    • provider string
    • model string
  • 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
    • enabled booleanfalse

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
    • provider string
    • model string
    • ok boolean

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
    • ok boolean

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
    • ok boolean
    • response string

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

  • endpoint string required Base URL of the endpoint.
  • apiKey string Omit it to use the stored key.

Responses

  • 200 The models. object
    • models object[]
  • 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
    • success boolean 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

  • key string 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

  • key string required Setting name.

Request body

  • value any required Any JSON value.

Responses

  • 200 The setting is stored. Success
    • success boolean 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

  • key string required Setting name.

Responses

  • 200 The setting is deleted. Success
    • success boolean 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
    • format string required"lector-learning-data"
    • version integer required1
    • exportedAt string (date-time) required
    • collections Collection[]
    • id string required
    • title string required
    • author string required
    • coverUrl string or null
    • groupId string or null Group that holds the collection.
    • language string
    • sortOrder integer required
    • createdAt string (date-time) required
    • lastReadAt string (date-time) required
    • collectionGroups CollectionGroup[]
    • id string required
    • name string required
    • sortOrder integer required
    • collectionCount integer Collections in the group, counted across every language.
    • createdAt string (date-time) required
    • lessons LessonExport[]
    • id string required
    • collectionId string or null
    • title string required
    • sortOrder integer required
    • textContent string required The lesson text, as Markdown.
    • wordCount integer required
    • language string
    • progress_scrollPosition number
    • progress_percentComplete number
    • createdAt string (date-time) required
    • lastReadAt string (date-time)
    • vocab VocabEntry[]
    • id string required
    • text string required
    • type string required"word" · "phrase"
    • sentence string Sentence that held the word.
    • translation string
    • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
    • stateUpdatedAt string (date-time)
    • reviewCount integer
    • bookId string or null Collection the word came from.
    • chapter integer or null
    • language string required
    • pushedToAnki integer0 · 1
    • ankiNoteId integer or null
    • createdAt string (date-time) required
    • knownWords object[]
    • word string
    • language string
    • state string How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
    • domain string or null Topic the classifier assigned.
    • clozeSentences ClozeCard[]
    • id string required
    • sentence string required
    • clozeWord string required The word the learner must supply.
    • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
    • translation string
    • language string
    • source string"tatoeba" · "mined"
    • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
    • wordRank integer or null Frequency rank of the blanked word.
    • tatoebaSentenceId integer or null
    • vocabEntryId string or null Vocabulary entry the card was mined from.
    • masteryLevel integer required0 · 25 · 50 · 75 · 100
    • nextReview string (date-time) required
    • lastReviewed string or null
    • reviewCount integer
    • timesCorrect integer
    • timesIncorrect integer
    • blacklisted integer 1 hides the card.0 · 1
    • journalEntries JournalEntryExport[]
    • id string required
    • body string required
    • correctedBody string or null
    • corrections string or null The corrections, as a JSON string.
    • status string required"draft" · "submitted"
    • wordCount integer required
    • language string required
    • entryDate string required Calendar date, YYYY-MM-DD.
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • dailyStats DailyStats[]
    • date string required Calendar date, YYYY-MM-DD.
    • language string
    • wordsRead integer
    • newWordsSaved integer
    • wordsMarkedKnown integer
    • minutesRead integer
    • clozePracticed integer
    • points integer
    • dictionaryLookups integer
    • ankiReviews integer
    • sessionStartedAt string or null
    • acceptedDictionaryEntries object[]
    • learnerProfiles object[]
    • onboardingProgress object[]
    • learnerEvents object[]
    • settings object[] Only the portable pair: targetLanguage and timezone.
    • key string
    • value string

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

  • format string required"lector-learning-data"
  • version integer required1
  • exportedAt string (date-time) required
  • collections Collection[]
  • id string required
  • title string required
  • author string required
  • coverUrl string or null
  • groupId string or null Group that holds the collection.
  • language string
  • sortOrder integer required
  • createdAt string (date-time) required
  • lastReadAt string (date-time) required
  • collectionGroups CollectionGroup[]
  • id string required
  • name string required
  • sortOrder integer required
  • collectionCount integer Collections in the group, counted across every language.
  • createdAt string (date-time) required
  • lessons LessonExport[]
  • id string required
  • collectionId string or null
  • title string required
  • sortOrder integer required
  • textContent string required The lesson text, as Markdown.
  • wordCount integer required
  • language string
  • progress_scrollPosition number
  • progress_percentComplete number
  • createdAt string (date-time) required
  • lastReadAt string (date-time)
  • vocab VocabEntry[]
  • id string required
  • text string required
  • type string required"word" · "phrase"
  • sentence string Sentence that held the word.
  • translation string
  • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • stateUpdatedAt string (date-time)
  • reviewCount integer
  • bookId string or null Collection the word came from.
  • chapter integer or null
  • language string required
  • pushedToAnki integer0 · 1
  • ankiNoteId integer or null
  • createdAt string (date-time) required
  • knownWords object[]
  • word string
  • language string
  • state string How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • domain string or null Topic the classifier assigned.
  • clozeSentences ClozeCard[]
  • id string required
  • sentence string required
  • clozeWord string required The word the learner must supply.
  • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
  • translation string
  • language string
  • source string"tatoeba" · "mined"
  • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
  • wordRank integer or null Frequency rank of the blanked word.
  • tatoebaSentenceId integer or null
  • vocabEntryId string or null Vocabulary entry the card was mined from.
  • masteryLevel integer required0 · 25 · 50 · 75 · 100
  • nextReview string (date-time) required
  • lastReviewed string or null
  • reviewCount integer
  • timesCorrect integer
  • timesIncorrect integer
  • blacklisted integer 1 hides the card.0 · 1
  • journalEntries JournalEntryExport[]
  • id string required
  • body string required
  • correctedBody string or null
  • corrections string or null The corrections, as a JSON string.
  • status string required"draft" · "submitted"
  • wordCount integer required
  • language string required
  • entryDate string required Calendar date, YYYY-MM-DD.
  • createdAt string (date-time)
  • updatedAt string (date-time)
  • dailyStats DailyStats[]
  • date string required Calendar date, YYYY-MM-DD.
  • language string
  • wordsRead integer
  • newWordsSaved integer
  • wordsMarkedKnown integer
  • minutesRead integer
  • clozePracticed integer
  • points integer
  • dictionaryLookups integer
  • ankiReviews integer
  • sessionStartedAt string or null
  • acceptedDictionaryEntries object[]
  • learnerProfiles object[]
  • onboardingProgress object[]
  • learnerEvents object[]
  • settings object[] Only the portable pair: targetLanguage and timezone.
  • key string
  • value string

Responses

  • 200 The restore finished. `imported` counts the rows per table. object
    • success boolean
    • imported object
    • <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

  • language string Language pack code. Defaults to the account’s active language.
  • limit integer Maximum messages. The default is 50.
  • before string (date-time) Return messages created before this time. Use it to page back.

Responses

  • 200 The messages. object[]
    • id string
    • role string"user" · "assistant"
    • content string
    • provider string or null
    • responseId string or null
    • language string
    • createdAt string (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

  • message string required At most 32 KiB.
  • language string

Responses

  • 200 Both messages of the exchange. object
    • userMessage object
    • assistantMessage object
  • 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

  • language string Language pack code. Defaults to the account’s active language.

Responses

  • 200 The history is deleted. object
    • ok boolean

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

  • eventType string 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"
  • language string required
  • lessonId string or null Required for lesson.opened.
  • vocabId string or null Required for the two vocab.* events.
  • properties object
  • idempotencyKey string 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
    • progress object or null Null before the account starts or skips the guided first run.
    • version integer
    • status string"in_progress" · "completed" · "skipped"
    • currentStep string"reader" · "practice" · "summary"
    • language string
    • starterCollectionId string or null
    • recommendedLessonId string or null
    • recommendedLessonTitle string or null
    • nextLessonId string or null
    • nextLessonTitle string or null
    • startedAt string (date-time)
    • completedAt string or null
    • updatedAt string (date-time)
    • profile object or null
    • language string
    • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
    • interests string[]
    • dailyMinutes integer
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • events LearnerEvent[] The learner events since the guided first run started.
    • id string
    • eventType string
    • language string
    • lessonId string or null
    • vocabId string or null
    • properties object
    • idempotencyKey string or null
    • occurredAt string (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

  • currentStep string"reader" · "practice" · "summary"
  • nextLessonId string
  • nextLessonTitle string

Responses

  • 200 The new state. OnboardingSnapshot
    • progress object or null Null before the account starts or skips the guided first run.
    • version integer
    • status string"in_progress" · "completed" · "skipped"
    • currentStep string"reader" · "practice" · "summary"
    • language string
    • starterCollectionId string or null
    • recommendedLessonId string or null
    • recommendedLessonTitle string or null
    • nextLessonId string or null
    • nextLessonTitle string or null
    • startedAt string (date-time)
    • completedAt string or null
    • updatedAt string (date-time)
    • profile object or null
    • language string
    • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
    • interests string[]
    • dailyMinutes integer
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • events LearnerEvent[] The learner events since the guided first run started.
    • id string
    • eventType string
    • language string
    • lessonId string or null
    • vocabId string or null
    • properties object
    • idempotencyKey string or null
    • occurredAt string (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
    • progress object or null Null before the account starts or skips the guided first run.
    • version integer
    • status string"in_progress" · "completed" · "skipped"
    • currentStep string"reader" · "practice" · "summary"
    • language string
    • starterCollectionId string or null
    • recommendedLessonId string or null
    • recommendedLessonTitle string or null
    • nextLessonId string or null
    • nextLessonTitle string or null
    • startedAt string (date-time)
    • completedAt string or null
    • updatedAt string (date-time)
    • profile object or null
    • language string
    • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
    • interests string[]
    • dailyMinutes integer
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • events LearnerEvent[] The learner events since the guided first run started.
    • id string
    • eventType string
    • language string
    • lessonId string or null
    • vocabId string or null
    • properties object
    • idempotencyKey string or null
    • occurredAt string (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

  • language string required
  • approximateLevel string required"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
  • interests string[] required Supported interest names.
  • dailyMinutes integer required

Responses

  • 200 The new state. OnboardingSnapshot
    • progress object or null Null before the account starts or skips the guided first run.
    • version integer
    • status string"in_progress" · "completed" · "skipped"
    • currentStep string"reader" · "practice" · "summary"
    • language string
    • starterCollectionId string or null
    • recommendedLessonId string or null
    • recommendedLessonTitle string or null
    • nextLessonId string or null
    • nextLessonTitle string or null
    • startedAt string (date-time)
    • completedAt string or null
    • updatedAt string (date-time)
    • profile object or null
    • language string
    • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
    • interests string[]
    • dailyMinutes integer
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • events LearnerEvent[] The learner events since the guided first run started.
    • id string
    • eventType string
    • language string
    • lessonId string or null
    • vocabId string or null
    • properties object
    • idempotencyKey string or null
    • occurredAt string (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

  • language string required
  • approximateLevel string required"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
  • interests string[] required Supported interest names.
  • dailyMinutes integer required

Responses

  • 200 The new state. OnboardingSnapshot
    • progress object or null Null before the account starts or skips the guided first run.
    • version integer
    • status string"in_progress" · "completed" · "skipped"
    • currentStep string"reader" · "practice" · "summary"
    • language string
    • starterCollectionId string or null
    • recommendedLessonId string or null
    • recommendedLessonTitle string or null
    • nextLessonId string or null
    • nextLessonTitle string or null
    • startedAt string (date-time)
    • completedAt string or null
    • updatedAt string (date-time)
    • profile object or null
    • language string
    • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
    • interests string[]
    • dailyMinutes integer
    • createdAt string (date-time)
    • updatedAt string (date-time)
    • events LearnerEvent[] The learner events since the guided first run started.
    • id string
    • eventType string
    • language string
    • lessonId string or null
    • vocabId string or null
    • properties object
    • idempotencyKey string or null
    • occurredAt string (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
    • ok boolean
    • mode string"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.
  • id string required
  • title string required
  • author string required
  • coverUrl string or null
  • groupId string or null Group that holds the collection.
  • language string
  • sortOrder integer required
  • createdAt string (date-time) required
  • lastReadAt string (date-time) required
CollectionListItem
CollectionDetail
CollectionGroup A container for collections. Groups hold every language.
  • id string required
  • name string required
  • sortOrder integer required
  • collectionCount integer Collections in the group, counted across every language.
  • createdAt string (date-time) required
Lesson One readable text, and its audio when the source carried audio.
  • id string required
  • collectionId string or null
  • title string required
  • sortOrder integer required
  • textContent string required The lesson text, as Markdown.
  • wordCount integer required
  • language string
  • progress_scrollPosition number
  • progress_percentComplete number
  • sourceType string or null Origin of the text, for example youtube. Null for plain Markdown.
  • sourceMeta string or null Origin metadata, as a JSON string.
  • segmentWords string or null The distinct word forms a segmenter found, as a JSON string array. Null for every spaced language.
  • audioDurationMs integer or null
  • audioBytes integer or null
  • transcriptionStatus string or null Transcription state of an audio lesson. Null for a text lesson."pending" · "processing" · "done" · "error" · null
  • transcriptionError string or null
  • transcriptionAttempts integer
  • createdAt string (date-time) required
  • lastReadAt string (date-time)
LessonListItem A lesson as the collection listing returns it. The text stays out, so fetch the lesson itself to read it.
  • id string required
  • collectionId string or null
  • title string required
  • sortOrder integer required
  • wordCount integer required
  • progress_scrollPosition number
  • progress_percentComplete number
  • audioDurationMs integer or null
  • transcriptionStatus string or null"pending" · "processing" · "done" · "error" · null
  • transcriptionError string or null
  • createdAt string (date-time) required
  • lastReadAt string (date-time)
TranscriptSegment One timed line of an audio transcript.
  • idx integer required Position in playback order.
  • startMs integer required
  • endMs integer required
  • text string required
VocabEntry A word or phrase the account saved, with the sentence it came from.
  • id string required
  • text string required
  • type string required"word" · "phrase"
  • sentence string Sentence that held the word.
  • translation string
  • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • stateUpdatedAt string (date-time)
  • reviewCount integer
  • bookId string or null Collection the word came from.
  • chapter integer or null
  • language string required
  • pushedToAnki integer0 · 1
  • ankiNoteId integer or null
  • createdAt string (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. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
ClozeCard A practice sentence with one word blanked out, plus its review schedule.
  • id string required
  • sentence string required
  • clozeWord string required The word the learner must supply.
  • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
  • translation string
  • language string
  • source string"tatoeba" · "mined"
  • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
  • wordRank integer or null Frequency rank of the blanked word.
  • tatoebaSentenceId integer or null
  • vocabEntryId string or null Vocabulary entry the card was mined from.
  • masteryLevel integer required0 · 25 · 50 · 75 · 100
  • nextReview string (date-time) required
  • lastReviewed string or null
  • reviewCount integer
  • timesCorrect integer
  • timesIncorrect integer
  • blacklisted integer 1 hides the card.0 · 1
DailyStats One day of activity in one language.
  • date string required Calendar date, YYYY-MM-DD.
  • language string
  • wordsRead integer
  • newWordsSaved integer
  • wordsMarkedKnown integer
  • minutesRead integer
  • clozePracticed integer
  • points integer
  • dictionaryLookups integer
  • ankiReviews integer
  • sessionStartedAt string or null
Correction One correction that the language model made to a journal entry.
  • original string The wrong word or phrase.
  • corrected string
  • explanation string Why the original is wrong.
  • type string"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
JournalEntry A piece of writing in the target language, and its correction.
  • id string required
  • body string required
  • correctedBody string or null
  • corrections Correction[] or null The corrections. Null before a correction runs.
  • original string The wrong word or phrase.
  • corrected string
  • explanation string Why the original is wrong.
  • type string"grammar" · "spelling" · "word_choice" · "word_order" · "missing_word" · "extra_word"
  • status string required"draft" · "submitted"
  • wordCount integer required
  • language string required
  • entryDate string required Calendar date, YYYY-MM-DD.
  • createdAt string (date-time)
  • updatedAt string (date-time)
DictionaryEntry A dictionary result for one word.
  • word string required
  • rank integer Frequency rank in the language.
  • ipa string
  • etymology string
  • senses object[] required
  • partOfSpeech string required
  • gloss string required
  • relatedForms object[]
  • form string required
  • relation string required
  • lemmaInfo object Set when the lookup matched an inflected form.
  • stem string
  • label string
  • source string dict is the built-in dictionary. cache is a translation you accepted."dict" · "cache"
OnboardingSnapshot The guided first-run state of the account.
  • progress object or null Null before the account starts or skips the guided first run.
  • version integer
  • status string"in_progress" · "completed" · "skipped"
  • currentStep string"reader" · "practice" · "summary"
  • language string
  • starterCollectionId string or null
  • recommendedLessonId string or null
  • recommendedLessonTitle string or null
  • nextLessonId string or null
  • nextLessonTitle string or null
  • startedAt string (date-time)
  • completedAt string or null
  • updatedAt string (date-time)
  • profile object or null
  • language string
  • approximateLevel string"new" · "beginner" · "intermediate" · "advanced" · "not_sure"
  • interests string[]
  • dailyMinutes integer
  • createdAt string (date-time)
  • updatedAt string (date-time)
  • events LearnerEvent[] The learner events since the guided first run started.
  • id string
  • eventType string
  • language string
  • lessonId string or null
  • vocabId string or null
  • properties object
  • idempotencyKey string or null
  • occurredAt string (date-time)
LearnerEvent One recorded product analytics event.
  • id string
  • eventType string
  • language string
  • lessonId string or null
  • vocabId string or null
  • properties object
  • idempotencyKey string or null
  • occurredAt string (date-time)
LessonExport A lesson as the data takeout carries it. The text travels, and the audio and transcription state stay behind.
  • id string required
  • collectionId string or null
  • title string required
  • sortOrder integer required
  • textContent string required The lesson text, as Markdown.
  • wordCount integer required
  • language string
  • progress_scrollPosition number
  • progress_percentComplete number
  • createdAt string (date-time) required
  • lastReadAt string (date-time)
JournalEntryExport A journal entry as the data takeout carries it. `corrections` stays a JSON string here, while the journal endpoints parse it.
  • id string required
  • body string required
  • correctedBody string or null
  • corrections string or null The corrections, as a JSON string.
  • status string required"draft" · "submitted"
  • wordCount integer required
  • language string required
  • entryDate string required Calendar date, YYYY-MM-DD.
  • createdAt string (date-time)
  • updatedAt string (date-time)
UserExport Every portable learning record for the account.
  • format string required"lector-learning-data"
  • version integer required1
  • exportedAt string (date-time) required
  • collections Collection[]
  • id string required
  • title string required
  • author string required
  • coverUrl string or null
  • groupId string or null Group that holds the collection.
  • language string
  • sortOrder integer required
  • createdAt string (date-time) required
  • lastReadAt string (date-time) required
  • collectionGroups CollectionGroup[]
  • id string required
  • name string required
  • sortOrder integer required
  • collectionCount integer Collections in the group, counted across every language.
  • createdAt string (date-time) required
  • lessons LessonExport[]
  • id string required
  • collectionId string or null
  • title string required
  • sortOrder integer required
  • textContent string required The lesson text, as Markdown.
  • wordCount integer required
  • language string
  • progress_scrollPosition number
  • progress_percentComplete number
  • createdAt string (date-time) required
  • lastReadAt string (date-time)
  • vocab VocabEntry[]
  • id string required
  • text string required
  • type string required"word" · "phrase"
  • sentence string Sentence that held the word.
  • translation string
  • state string required How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • stateUpdatedAt string (date-time)
  • reviewCount integer
  • bookId string or null Collection the word came from.
  • chapter integer or null
  • language string required
  • pushedToAnki integer0 · 1
  • ankiNoteId integer or null
  • createdAt string (date-time) required
  • knownWords object[]
  • word string
  • language string
  • state string How well the account knows a word. level1 to level4 are the learning steps between new and known. ignored hides the word."new" · "level1" · "level2" · "level3" · "level4" · "known" · "ignored"
  • domain string or null Topic the classifier assigned.
  • clozeSentences ClozeCard[]
  • id string required
  • sentence string required
  • clozeWord string required The word the learner must supply.
  • clozeIndex integer required Position of the blanked word in the sentence, counted in words.
  • translation string
  • language string
  • source string"tatoeba" · "mined"
  • collection string"top500" · "top1000" · "top2000" · "mined" · "random"
  • wordRank integer or null Frequency rank of the blanked word.
  • tatoebaSentenceId integer or null
  • vocabEntryId string or null Vocabulary entry the card was mined from.
  • masteryLevel integer required0 · 25 · 50 · 75 · 100
  • nextReview string (date-time) required
  • lastReviewed string or null
  • reviewCount integer
  • timesCorrect integer
  • timesIncorrect integer
  • blacklisted integer 1 hides the card.0 · 1
  • journalEntries JournalEntryExport[]
  • id string required
  • body string required
  • correctedBody string or null
  • corrections string or null The corrections, as a JSON string.
  • status string required"draft" · "submitted"
  • wordCount integer required
  • language string required
  • entryDate string required Calendar date, YYYY-MM-DD.
  • createdAt string (date-time)
  • updatedAt string (date-time)
  • dailyStats DailyStats[]
  • date string required Calendar date, YYYY-MM-DD.
  • language string
  • wordsRead integer
  • newWordsSaved integer
  • wordsMarkedKnown integer
  • minutesRead integer
  • clozePracticed integer
  • points integer
  • dictionaryLookups integer
  • ankiReviews integer
  • sessionStartedAt string or null
  • acceptedDictionaryEntries object[]
  • learnerProfiles object[]
  • onboardingProgress object[]
  • learnerEvents object[]
  • settings object[] Only the portable pair: targetLanguage and timezone.
  • key string
  • value string

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-client

Does 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.