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 a key can never end up in a log line or a 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. | Anything that changes something. |
| write | Everything a read key can, plus add, edit, archive and restore. | Grade a review, or manage keys. |
What no key can do
Two routes 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 a minute per key. That is far above a batch import, which sends 200 cards in one call. Over the limit you get 429; the window is a minute, so waiting one clears it.
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. | Slow down. The window is a minute, so waiting one clears it. |
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.