All endpoints are under the base path /api. JSON is used for all request and response bodies. Timestamps are returned as ISO 8601 strings (e.g., "2026-03-14T02:00:00Z").
Resource IDs are opaque strings generated by the database. With the default SQLite backend they are 32-character lowercase hex strings (e.g. "f47ac10b58cc4372a567b409e2087bc1"); with PostgreSQL they are UUID strings (e.g. "550e8400-e29b-41d4-a716-446655440000"). Treat IDs as opaque — do not rely on their format.
| Domain | File | Description |
|---|---|---|
| Auth, OIDC/SSO, API Keys | api/auth.md | Login, signup, password change, SSO, long-lived API keys |
| Config | api/config.md | Server configuration: OIDC, SMTP, watch folder, LLM |
| Admin | api/admin.md | User management and audit logs |
| Libraries | api/libraries.md | Library CRUD and book listing by library |
| Authors | api/authors.md | Author CRUD and book listing by author |
| Series | api/series.md | Series CRUD and book listing by series |
| Tags | api/tags.md | Tag CRUD |
| Books & Book Files | api/books.md | Book CRUD, metadata enrichment, sub-resources, file management |
| OPDS | api/opds.md | OPDS credentials and OPDS 1.2 catalog |
| Kobo & KOSync | api/kobo.md | Kobo sync tokens and KOReader/KOSync protocol |
| Reading Lists | api/reading-lists.md | User-curated book collections |
| Reading Groups | api/reading-groups.md | Shared reading groups |
| Annotations | api/annotations.md | Book annotation CRUD |
| Stats & Recommendations | api/stats.md | Reading statistics and book recommendations |
Most endpoints require a JWT bearer token obtained from the login or signup endpoints, or a long-lived API key (prefix bib_).
The credential can be supplied in two ways:
-
Authorization header (required for API keys; recommended for API clients):
Authorization: Bearer <token-or-api-key> -
Session cookie (used automatically by the browser): On login and signup the server sets an
HttpOnlysession cookie namedbiblioteka_token. Subsequent browser requests to protected pages (including/asynqmon/) use this cookie automatically — no manual header is required. Cookies are not accepted for API keys.
Endpoints that require authentication are marked with 🔒. Endpoints that additionally require the caller to be an admin are marked with 🔒 Admin. Endpoints marked with 🔒 JWT only require a JWT token specifically — API keys are not accepted for those routes (see JWT-only endpoints).
The following endpoints use a stricter JWT-only check and do not accept API keys. This is an intentional security constraint — for example, an API key cannot be used to create, list, or delete other API keys.
| Endpoint | Reason |
|---|---|
PUT /api/auth/password |
Password changes must use a JWT session |
GET /api/config/status |
Sensitive config visibility requires a JWT |
GET /api/config/oidc, PUT /api/config/oidc |
Sensitive server config; admin only |
GET /api/config/smtp, PUT /api/config/smtp, POST /api/config/smtp/test |
Sensitive server config; admin only |
GET /api/config/watch-folder, PUT /api/config/watch-folder |
Sensitive server config; admin only |
GET /api/config/llm, PUT /api/config/llm |
Sensitive server config; admin only |
GET /api/admin/users, PUT /api/admin/users/{id} |
User management; admin only |
GET /api/opds/credentials, PUT /api/opds/credentials, DELETE /api/opds/credentials |
Credential management requires a JWT |
GET /api/api-keys, POST /api/api-keys, DELETE /api/api-keys/{id} |
API key management requires a JWT to prevent key self-escalation |
GET /api/kobo/tokens, POST /api/kobo/tokens, DELETE /api/kobo/tokens/{id} |
Kobo token management requires a JWT to prevent token self-escalation |
GET /api/kosync/credentials, PUT /api/kosync/credentials, DELETE /api/kosync/credentials |
KOSync credential management requires a JWT |
Response: 200 OK
{"status":"ok"}Returns the running server version string. No authentication required.
Response: 200 OK
{"version":"v1.2.3"}| Field | Type | Description |
|---|---|---|
version |
string | Semantic version tag of the server binary (e.g. "v1.2.3"). Equals "dev" when built outside the release pipeline. |
The version is also displayed in the application sidebar so users can confirm which release is deployed.
Several list endpoints accept limit and offset query parameters to page through results.
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 |
Maximum items per page (capped at 200) |
offset |
integer | 0 |
Number of items to skip before the first result |
Paginated responses include envelope fields alongside the data array:
| Field | Type | Description |
|---|---|---|
total |
integer | Total number of items across all pages |
limit |
integer | Effective limit used for this page |
offset |
integer | Effective offset used for this page |
Behavior: Most paginated endpoints (GET /api/books, GET /api/libraries/{id}/books, GET /api/authors/{id}/books, GET /api/series/{id}/books) use parseLimitOffset, which silently clamps out-of-range values — a non-integer or negative offset falls back to 0, and a limit below 1 falls back to 50. The GET /api/audit-logs endpoint uses stricter validation and returns 400 Bad Request for a non-integer or out-of-range limit/offset.
An interactive OpenAPI browser (powered by Swagger UI) that documents and lets you try every API endpoint in the browser.
| Property | Value |
|---|---|
| URL | /swagger/ |
| Auth | Public — no authentication required to browse the UI |
| Spec URL | /swagger/doc.json — raw OpenAPI 3.0 JSON |
Accessing
/swagger(without trailing slash) redirects to/swagger/automatically.
The UI is useful during development for exploring request/response shapes without needing a separate API client. Individual protected endpoints still require a valid JWT when invoked from within the UI.
An interactive web UI for monitoring background jobs (powered by asynqmon).
| Property | Value |
|---|---|
| URL | /asynqmon/ |
| Auth | 🔒 Valid admin JWT required — accepted as Authorization: Bearer <token> header or the biblioteka_token session cookie set on login |
| Availability | Route is mounted whenever the background worker subsystem is enabled; a reachable Redis instance is required for the UI to function correctly |
This dashboard is only available when the server is started with a Redis-backed worker (i.e. REDIS_URL is configured, default: redis://localhost:6379). It requires an authenticated admin session — accessing it without a valid JWT returns 401 Unauthorized.
Navigate to http://<host>:<port>/asynqmon/ in a browser after signing in as an admin to view queued, active, completed, and failed background jobs (library scans, file processing), and retry or delete individual tasks. Because login sets a biblioteka_token session cookie, the browser sends it automatically — no manual header or proxy configuration is required for browser access.
All error responses use the following shape:
{ "error": "descriptive error message" }Common HTTP status codes:
| Code | Meaning |
|---|---|
400 |
Bad request — invalid body, missing required fields |
401 |
Unauthorized — missing or invalid JWT |
403 |
Forbidden — insufficient permissions (admin required) |
404 |
Not found |
405 |
Method not allowed |
409 |
Conflict — duplicate name or email |
429 |
Too Many Requests — per-IP rate limit exceeded (auth endpoints and POST /api/config/smtp/test) |
500 |
Internal server error |