Mankai Compatible API
To let Mankai’s HTTP plugin interact with your server, implement the compatible API described below. Match the endpoint paths, request bodies, and response formats for the operations your server supports.
Users connect to your server by adding a Mankai Compatible source in Settings → Sources. See source setup for the app configuration steps.
To support the in-app editor, also implement the Editor API.
Server information
Section titled “Server information”Retrieve information about the server.
Response — 200 OK
interface ServerInfoResponse { id: string authenticationEnabled: boolean editorEnabled?: boolean // default: false name?: string version?: string description?: string authors?: string[] repository?: string availableGenres?: string[] cooldown?: Cooldown capabilities?: PluginCapability[]}
interface Cooldown { default?: number getImage?: number getImageConcurrency?: number}
type PluginCapability = | 'onlineCheck' | 'suggestions' | 'list' | 'listByGenre' | 'listByStatus' | 'search' | 'searchByGenre' | 'searchByStatus' | 'searchByAuthor' | 'mangaDetails' | 'batchMangas' | 'mangaUpdates' | 'chapter' | 'image'default is the optional minimum delay between non-image plugin calls, expressed in milliseconds. getImage configures a separate minimum delay between image calls. getImageConcurrency optionally limits the number of concurrent image requests.
Authentication (optional)
Section titled “Authentication (optional)”If you want to enable authentication on your server, you must implement the following two endpoints.
POST /auth/login
Section titled “POST /auth/login”Exchange a username and password for an access token and refresh token.
Request body
interface LoginRequest { username: string password: string}Response — 200 OK
interface LoginResponse { message: string user: { // User Details (Optional) } accessToken: string refreshToken: string}POST /auth/refresh
Section titled “POST /auth/refresh”Exchange a valid refresh token for a new access token.
Request body
interface RefreshRequest { refreshToken: string}Response — 200 OK
interface RefreshResponse { message: string accessToken: string}These endpoints return data about manga and their chapters. Lightweight manga entries (used in lists, search, and batch lookups) use the Manga type defined below. The full details endpoint returns the more detailed MangaResponse type.
GET /manga
Section titled “GET /manga”Retrieve a paginated list of manga, optionally filtered by genre, status, or both.
Query parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
page |
number |
1 |
No | The page number to retrieve. |
genre |
string |
"all" |
No | Filter results by a single genre. |
status |
number |
0 (Any) |
No | Filter by status: 0 = Any, 1 = OnGoing, 2 = Completed. |
Response — 200 OK
type MangaListResponse = Manga[]
interface Chapter { id: string title?: string locked?: boolean}
interface Manga { id: string title?: string cover?: string // URL — absolute, or relative to the server's base URL status?: Status latestChapter?: Chapter}
enum Status { Any = 0, OnGoing = 1, Completed = 2,}POST /manga
Section titled “POST /manga”Retrieve lightweight details for a specific list of manga. This is useful for batch lookups (for example, refreshing a user’s library) where calling GET /manga/:id for each entry would be too slow.
Request body
type MangaRequest = string[] // Array of manga IDsResponse — 200 OK
Returns the same MangaListResponse shape as GET /manga.
POST /manga/updates
Section titled “POST /manga/updates”Check a batch of manga against the latest chapters currently known by Mankai.
This endpoint lets the server control update behavior. Exclude the mangaUpdates capability when the server should use Mankai’s default batch comparison instead.
Request body
interface MangaUpdateRequest { id: string latestChapter: Chapter}
type MangaUpdatesRequest = MangaUpdateRequest[]Response — 200 OK
Return a MangaUpdate[]. Every result must include id and updates. The updates flag alone controls whether Mankai marks the saved manga as updated. Metadata is refreshed for every returned result, including results where updates is false.
interface MangaUpdate extends Manga { updates: boolean}
type MangaUpdatesResponse = MangaUpdate[][ { "id": "one-piece", "updates": true, "latestChapter": { "id": "1124", "title": "Chapter 1124" } }, { "id": "completed-series", "updates": false, "status": 2 }]GET /manga/:id
Section titled “GET /manga/:id”Retrieve full details for a single manga, including its description, authors, genres, and all chapter groups and their chapters. Chapter groups appear in the same order as the entries in chapters. Chapter group titles must be unique within a manga.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id |
string |
The manga’s ID. |
Response — 200 OK
interface MangaResponse { id: string title?: string cover?: string // URL — absolute, or relative to the server's base URL status?: Status readingDirection?: ReadingDirection latestChapter?: Chapter description?: string externalLink?: string updatedAt?: number // Unix timestamp in milliseconds authors: string[] genres: Genre[] chapters: ChapterGroup[] // Ordered from first group to last group remarks?: string editable?: boolean // Whether this manga can be edited, defaults to true}
enum Genre { All = 'all', Action = 'action', Romance = 'romance', Yuri = 'yuri', BoysLove = 'boysLove', SchoolLife = 'schoolLife', Adventure = 'adventure', Harem = 'harem', SpeculativeFiction = 'speculativeFiction', War = 'war', Suspense = 'suspense', FanFiction = 'fanFiction', Comedy = 'comedy', Magic = 'magic', Horror = 'horror', Historical = 'historical', Sports = 'sports', Mature = 'mature', Mecha = 'mecha', Otokonoko = 'otokonoko',}
enum Status { Any = 0, OnGoing = 1, Completed = 2,}
enum ReadingDirection { LeftToRight = 1, RightToLeft = 2, Vertical = 3,}
interface Chapter { id: string title?: string locked?: boolean}
interface ChapterGroup { id?: string // Required for editable manga, Read-only plugins may omit it title: string // Unique within this manga chapters: Chapter[] // Increasing order: oldest/lowest chapter first}GET /manga/:id/chapter/:chapterId
Section titled “GET /manga/:id/chapter/:chapterId”Retrieve the page images for a specific chapter. The response is a list of image URLs that may be absolute or relative to the server’s base URL.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id |
string |
The manga’s ID. |
chapterId |
string |
The chapter’s ID. |
Response — 200 OK
// Array of image URLs (absolute, or relative to the server's base URL).type ChapterResponse = string[]Search
Section titled “Search”GET /search
Section titled “GET /search”Search for manga by title or author.
Query parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
query |
string |
null |
Yes | The search query string. |
page |
number |
1 |
No | The page number to retrieve. |
genre |
string |
"all" |
No | Filter results by a single genre. |
status |
number |
0 (Any) |
No | Filter by status: 0 = Any, 1 = OnGoing, 2 = Completed. |
isAuthor |
boolean |
false |
No | Search the authors field instead of the title field. |
Response — 200 OK
Returns the same MangaListResponse shape as GET /manga.
Suggestions
Section titled “Suggestions”GET /suggestion
Section titled “GET /suggestion”Retrieve autocomplete suggestions for a search query as the user types.
Query parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
query |
string |
null |
Yes | The query string to get suggestions for. |
Response — 200 OK
// Array of suggested manga titles.type SuggestionResponse = string[]