API Reference
HTTP routes exposed by the current Alex application
Alex's web UI uses route handlers under /api. They are application-internal APIs rather than a versioned public SDK, so clients should expect them to evolve with Alex releases.
Authentication
Protected routes accept either:
- A valid NextAuth session cookie for browser traffic
- The private
x-alex-desktop-authheader injected by the Electron shell for requests to its local server
Do not configure or forward the desktop header yourself. Remote traffic to a desktop Alex instance uses normal email/password authentication.
Roles:
- admin — User administration and destructive library operations, plus normal reader features
- user — Library access, personal collections, sharing, and per-user reading progress
Routes under /api/shared/[token] do not require login. Each handler validates the token and, for book resources, verifies membership in that shared collection.
Books
| Method | Endpoint | Description |
|---|---|---|
GET | /api/books | Paginated books. Query: q, type, status, sort, page, limit (maximum 100). |
GET | /api/books/now-reading | Current user's in-progress books, most recently read first. |
GET | /api/books/[id] | Book metadata and current user's progress. |
GET | /api/books/[id]/cover | Cover image. |
GET | /api/books/[id]/file | PDF or EPUB byte stream with Range support. |
GET | /api/books/[id]/book.epub | EPUB stream at a URL ending in .epub. Returns 400 for non-EPUB books. |
GET | /api/books/[id]/progress | Current user's progress row, or null when the book has not been started. |
PUT | /api/books/[id]/progress | Upsert current user's reading progress. |
GET /api/books query values:
type:all(default),pdf, orepubstatus:all(default),not_started,reading, orcompletedsort:added(default),title,author, orreadpage: defaults to1limit: defaults to24and is capped at100
Progress request bodies:
// PDF
{ "currentPage": 42, "totalPages": 300 }
// EPUB
{ "epubLocation": "epubcfi(...)", "percentComplete": 37.5 }
There are currently no PATCH or DELETE handlers for /api/books/[id].
Collections
| Method | Endpoint | Description |
|---|---|---|
GET | /api/collections | Current user's collections and book counts. Optional bookId adds containsBook to each result. |
POST | /api/collections | Create with { name, description? }; names are limited to 100 characters. |
GET | /api/collections/[id] | Collection metadata and paginated books. Query: page, limit (maximum 100). |
PUT | /api/collections/[id] | Update { name?, description? }. |
DELETE | /api/collections/[id] | Delete the collection and its memberships, not its books. |
POST | /api/collections/[id]/books | Add { bookId }; adding an existing membership is idempotent. |
DELETE | /api/collections/[id]/books/[bookId] | Remove a membership. |
GET | /api/collections/[id]/now-reading | Current user's in-progress books within the collection. |
GET | /api/collections/[id]/share | Return sharing state and the current token. |
POST | /api/collections/[id]/share | Enable sharing or return the existing token and URL. |
DELETE | /api/collections/[id]/share | Revoke sharing and clear the token. |
Collection ownership is enforced on every protected collection route.
Users and administration
| Method | Endpoint | Description |
|---|---|---|
GET | /api/users | Admin-only user list. |
POST | /api/users | Admin-only creation with { email, displayName, password, role }. Passwords require at least 6 characters. |
DELETE | /api/users/[id] | Admin-only deletion; an admin cannot delete their own account. |
POST | /api/admin/library/clear | Admin-only removal of indexed books and covers. The watcher can re-index source files. |
POST | /api/electron/clear-books | Electron-only reset helper, restricted to an authorized loopback request. |
Admin edits to a user's display name, role, or password use authenticated Next.js server actions, not PATCH /api/users/[id].
Real-time updates
| Method | Endpoint | Description |
|---|---|---|
GET | /api/library/events | Authenticated Server-Sent Events stream. Emits library-update when the ingestion version changes. |
The server checks the version every two seconds and writes a keepalive every 15 seconds.
Public shared collections
| Method | Endpoint | Description |
|---|---|---|
GET | /api/shared/[token] | Collection metadata and paginated books. Query: page, limit. |
GET | /api/shared/[token]/covers/[bookId] | Cover for a book in the collection. |
GET | /api/shared/[token]/books/[bookId]/file | PDF or EPUB bytes for a book in the collection. |
GET | /api/shared/[token]/books/[bookId]/book.epub | EPUB bytes for a book in the collection. |
There is no separate /api/shared/[token]/books list route; pagination is part of GET /api/shared/[token].
Source-aware streaming
The four private/public /file and /book.epub handlers use one pipeline:
source=local— Stream from disk with single-range HTTP support.source=s3— Spawnwatcher-rs s3-stream, forward the Range header, and stream from the configured bucket.
Normal browser reading does not require direct bucket access or bucket CORS.