Complete API documentation for Komga Enhanced fork features.
All endpoints require authentication via:
X-API-Key: your-keyGET /api/v1/downloads
Query parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status (PENDING, DOWNLOADING, COMPLETED, FAILED, PAUSED, CANCELLED) |
libraryId |
string | Filter by library |
page |
int | Page number (0-indexed) |
size |
int | Page size (default: 20) |
Response:
{
"content": [
{
"id": "abc123",
"url": "https://mangadex.org/title/...",
"title": "Manga Title",
"status": "DOWNLOADING",
"progress": 45,
"currentChapter": "Chapter 5",
"totalChapters": 10,
"libraryId": "lib123",
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:05:00Z"
}
],
"totalElements": 1,
"totalPages": 1
}
POST /api/v1/downloads
Content-Type: application/json
{
"url": "https://mangadex.org/title/...",
"libraryId": "lib123",
"priority": 0
}
Response: Created download object
GET /api/v1/downloads/{id}
DELETE /api/v1/downloads/{id}
POST /api/v1/downloads/{id}/action
Content-Type: application/json
{
"action": "RETRY"
}
Actions: RETRY, PAUSE, RESUME, CANCEL
DELETE /api/v1/downloads/clear/completed
DELETE /api/v1/downloads/clear/failed
DELETE /api/v1/downloads/clear/cancelled
Response:
{
"cleared": 5
}
GET /api/v1/downloads/progress
Accept: text/event-stream
Events:
event: progress
data: {"id":"abc123","percent":45,"currentChapter":"Ch. 5","speed":"1.2 MB/s"}
event: complete
data: {"id":"abc123","title":"Manga Title"}
event: error
data: {"id":"abc123","error":"Rate limited"}
Retroactively inject missing ComicInfo.xml and ZIP comments into existing MangaDex CBZ files.
POST /api/v1/downloads/repair-comicinfo/{libraryId}
Response:
{
"mangaProcessed": 5,
"repaired": 12,
"skipped": 88,
"errors": []
}
GET /api/v1/downloads/scheduler
Response:
{
"enabled": true,
"intervalHours": 24,
"scheduleMode": "fixed_time",
"checkTime": "16:00",
"lastCheckTime": "2024-01-15T10:00:00"
}
| Field | Type | Description |
|---|---|---|
enabled |
boolean | Whether the scheduler is active |
intervalHours |
int | Hours between checks (used in interval mode) |
scheduleMode |
string | "interval" or "fixed_time" |
checkTime |
string? | Time in HH:mm format (used in fixed_time mode) |
lastCheckTime |
string? | Timestamp of last check |
POST /api/v1/downloads/scheduler
Content-Type: application/json
{
"enabled": true,
"intervalHours": 24,
"scheduleMode": "fixed_time",
"checkTime": "16:00"
}
Response: Updated scheduler settings
POST /api/v1/downloads/scheduler/check-now
Response: 204 No Content
Per-library follow.txt management. Each library can have its own follow.txt file with URLs.
GET /api/v1/downloads/follow-txt/{libraryId}
Response:
{
"libraryId": "lib123",
"libraryName": "Manga",
"content": "https://mangadex.org/title/...\nhttps://mangadex.org/title/..."
}
PUT /api/v1/downloads/follow-txt/{libraryId}
Content-Type: application/json
{
"content": "https://mangadex.org/title/...\nhttps://mangadex.org/title/..."
}
Response: 204 No Content
POST /api/v1/downloads/follow-txt/{libraryId}/check-now
Upload follow.txt MangaDex URLs to your MangaDex follows list.
POST /api/v1/downloads/follow-txt/{libraryId}/sync-to-mangadex
Check for new chapters across all followed manga.
POST /api/v1/downloads/check-new
Read / add / remove a manga on the user’s MangaDex account follow list (used by the Add to MangaDex follow list button and the Hide titles already on MangaDex follow list filter in the advanced MangaDex search). All three require the MangaDex Subscription plugin to be enabled and configured; they use that plugin’s stored credentials.
GET /api/v1/downloads/mangadex/follows
Response (lowercase UUIDs, paginated server-side through MangaDex’s /user/follows/manga and aggregated):
{
"uuids": ["18d92807-8627-4a23-9ef6-12a0a7fbd054", "..."]
}
POST /api/v1/downloads/mangadex/follows/{mangaId}
DELETE /api/v1/downloads/mangadex/follows/{mangaId}
Response (200 on success, 400 with the same body if the plugin is disabled / unauthenticated):
{ "success": true, "message": "Followed on MangaDex" }
Rewind last_check_time and run a feed check immediately. Picks up chapters that were silently dropped earlier (e.g. by a stuck last_check_time after a long restart gap, or — before 0.1.4.4 — by the isUrlAlreadyQueued/COMPLETED guard in checkFeed).
POST /api/v1/downloads/mangadex-subscription/force-resync?lookbackDays=N
lookbackDays defaults to 7. Response shape matches the follow endpoints ({success, message}).
Schema-driven list of one-click maintenance actions that the WebUI renders dynamically on /settings/fixes. New fixes are added by registering a Fix in FixRegistry.kt; no Vue change required. Each entry’s isEnabled predicate is evaluated server-side so disabled plugins / inactive features simply don’t appear in the response.
GET /api/v1/maintenance/fixes
Response:
[
{
"id": "mangadex-force-resync",
"title": "MangaDex Subscription — Force Resync",
"description": "Rewinds last_check_time and re-runs the followed-manga feed check now...",
"icon": "mdi-wrench-outline",
"endpoint": "/api/v1/downloads/mangadex-subscription/force-resync",
"method": "POST",
"params": [
{
"key": "lookbackDays",
"label": "Lookback window (days)",
"type": "number",
"default": 7,
"min": 1,
"max": 30,
"hint": "How far back to scan the followed-manga feed"
}
]
}
]
Param type is one of number, string, boolean. The UI sends the collected values as query parameters to the declared endpoint/method.
GET /api/v1/media-management/oversized-pages
Query parameters:
| Parameter | Type | Description |
|---|---|---|
minHeight |
int | Minimum height in pixels (default: 10000) |
libraryId |
string | Filter by library |
seriesId |
string | Filter by series |
page |
int | Page number |
size |
int | Page size |
Response:
{
"content": [
{
"bookId": "book123",
"bookTitle": "Chapter 1",
"seriesId": "series123",
"seriesTitle": "Webtoon Title",
"pageNumber": 1,
"width": 800,
"height": 15000,
"aspectRatio": 0.053,
"filePath": "/manga/Webtoon/Chapter 1.cbz"
}
],
"totalElements": 42
}
POST /api/v1/media-management/oversized-pages/split/{bookId}
Content-Type: application/json
{
"maxHeight": 2000,
"preserveOriginal": true
}
Response:
{
"bookId": "book123",
"originalPageCount": 5,
"newPageCount": 25,
"splitPages": [1, 3, 5]
}
POST /api/v1/media-management/oversized-pages/split-all
Content-Type: application/json
{
"maxHeight": 2000,
"minHeight": 10000,
"libraryId": "lib123"
}
Response:
{
"processed": 10,
"skipped": 2,
"errors": 0,
"details": [
{"bookId": "book1", "newPageCount": 25},
{"bookId": "book2", "newPageCount": 18}
]
}
POST /api/v1/tachiyomi/import
Content-Type: multipart/form-data
file: <backup file>
libraryId: lib123
Response:
{
"imported": 42,
"skipped": 5,
"errors": 0,
"urls": [
"https://mangadex.org/title/...",
"https://mangadex.org/title/..."
]
}
POST /api/v1/chapter-urls/check
Content-Type: application/json
{
"urls": [
"https://mangadex.org/chapter/...",
"https://mangadex.org/chapter/..."
]
}
Response:
{
"results": [
{"url": "https://...", "exists": true, "downloadedAt": "2024-01-10T10:00:00Z"},
{"url": "https://...", "exists": false}
]
}
DELETE /api/v1/chapter-urls/series/{seriesId}
GET /api/v1/health
Response:
{
"status": "UP",
"components": {
"database": "UP",
"diskSpace": "UP",
"galleryDl": "UP"
},
"galleryDlVersion": "1.26.0"
}
All endpoints may return:
{
"timestamp": "2024-01-15T10:00:00Z",
"status": 400,
"error": "Bad Request",
"message": "Invalid URL format",
"path": "/api/v1/downloads"
}
Common status codes:
| Code | Description |
|---|---|
| 400 | Bad request / validation error |
| 401 | Authentication required |
| 403 | Insufficient permissions |
| 404 | Resource not found |
| 429 | Rate limited |
| 500 | Internal server error |