Using the API
Authentication
Requests carry a personal API key in a header. Keys are yours, they never expire on their own, and each one holds a single scope.
Send the key in a header
Put the key in x-api-key. There is no bearer token and no query parameter, so the key stays out of request URLs and browser history.
POST /api/cards
x-api-key: lymi_2f8c1a4e7b93d05a6c1f
content-type: application/jsonTwo scopes, chosen when you make the key
A key holds one scope for its whole life. To change it, make a new key and revoke the old one.
| Scope | Can | Cannot |
|---|---|---|
| read | List and read decks, cards, the review queue and settings. | Edit or archive learning content. Export requests are allowed with read access. |
| write | Everything a read key can, plus add, edit, archive and restore. | Grade a review, or manage keys. |
What no key can do
These actions need your own session in the app and answer 403 to any key, whatever its scope:
POST /api/review/grade. A review is a claim about your memory, so nothing else gets to make it.- Everything under
/api/keys. A key cannot list, mint or revoke another key, so one leaked key cannot become several.
Sessions, for the app itself
The Lymi app authenticates with a session cookie rather than a key. You will only meet this if you call the API from a browser tab already signed in to Lymi. Everything in these docs otherwise assumes a key.
Rate limit
600 requests per key. The count clears once the key has gone a minute without a request, so a script that never pauses reaches the limit even at a slow pace. A batch import sends 200 cards in one call, far below it. Over the limit you get 429 with a Retry-After header: the seconds to wait before the next request.
Errors have one shape
Every failure is JSON with an error field written in plain words. A 400 adds issues, which lists what failed validation.
{
"error": "Invalid card",
"issues": [
{
"code": "too_small",
"path": ["term"],
"message": "Too small: expected string to have >=1 characters"
}
]
}| Code | When | What to do |
|---|---|---|
| 400 | The body or the query string did not validate. | Read issues in the response. It names the field and what was wrong with it. |
| 401 | No key, or a key that is wrong or revoked. | Check the header is x-api-key and that the key still exists in Settings. |
| 403 | A read key tried to write, or a key tried a route only you can call. | Make a key with the write scope, or do this one in the app. |
| 404 | Not found, or not yours. | Check the id. Lymi does not say whether an id belongs to someone else. |
| 429 | The key is over its rate limit. | Wait the seconds in the Retry-After header, then send the request again. |
Revoking a key
Open Settings, find the key by its first characters, and revoke it. That is final and takes effect on the next request. Nothing the key added is removed; the cards stay where they are.
The privacy policy explains how Lymi handles account and API data. If a key or request is not working, follow the API support steps.